Add viewport and scissor support (flutter/engine#9)

This commit is contained in:
Brandon DeRosier 2022-02-16 15:46:24 -08:00 committed by Dan Field
parent 3be670ac64
commit 6fa7495680
5 changed files with 90 additions and 0 deletions

View File

@ -335,5 +335,37 @@ TEST(GeometryTest, RectContainsPoint) {
}
}
TEST(GeometryTest, RectContainsRect) {
{
Rect a(100, 100, 100, 100);
ASSERT_TRUE(a.Contains(a));
}
{
Rect a(100, 100, 100, 100);
Rect b(0, 0, 0, 0);
ASSERT_FALSE(a.Contains(b));
}
{
Rect a(100, 100, 100, 100);
Rect b(150, 150, 20, 20);
ASSERT_TRUE(a.Contains(b));
}
{
Rect a(100, 100, 100, 100);
Rect b(150, 150, 100, 100);
ASSERT_FALSE(a.Contains(b));
}
{
Rect a(100, 100, 100, 100);
Rect b(50, 50, 100, 100);
ASSERT_FALSE(a.Contains(b));
}
{
Rect a(100, 100, 100, 100);
Rect b(0, 0, 300, 300);
ASSERT_FALSE(a.Contains(b));
}
}
} // namespace testing
} // namespace impeller

View File

@ -84,6 +84,10 @@ struct TRect {
p.y < origin.y + size.height;
}
constexpr bool Contains(const TRect& o) const {
return Union(o).size == size;
}
constexpr bool IsZero() const { return size.IsZero(); }
constexpr bool IsEmpty() const { return size.IsEmpty(); }

View File

@ -428,6 +428,28 @@ bool RenderPassMTL::EncodeCommands(Allocator& allocator,
: MTLWindingCounterClockwise];
[encoder setCullMode:MTLCullModeNone];
[encoder setStencilReferenceValue:command.stencil_reference];
if (command.viewport.has_value()) {
auto v = command.viewport.value();
MTLViewport viewport = {
.originX = v.rect.origin.x,
.originY = v.rect.origin.y,
.width = v.rect.size.width,
.height = v.rect.size.height,
.znear = v.znear,
.zfar = v.zfar,
};
[encoder setViewport:viewport];
}
if (command.scissor.has_value()) {
auto s = command.scissor.value();
MTLScissorRect scissor = {
.x = static_cast<NSUInteger>(s.origin.x),
.y = static_cast<NSUInteger>(s.origin.y),
.width = static_cast<NSUInteger>(s.size.width),
.height = static_cast<NSUInteger>(s.size.height),
};
[encoder setScissorRect:scissor];
}
if (!bind_stage_resources(command.vertex_bindings, ShaderStage::kVertex)) {
return false;
}
@ -472,6 +494,15 @@ bool RenderPassMTL::AddCommand(Command command) {
return false;
}
if (command.scissor.has_value()) {
auto target_rect = IRect({}, render_target_.GetRenderTargetSize());
if (!target_rect.Contains(command.scissor.value())) {
VALIDATION_LOG << "Cannot apply a scissor that lies outside the bounds "
"of the render target.";
return false;
}
}
commands_.emplace_back(std::move(command));
return true;
}

View File

@ -6,10 +6,12 @@
#include <map>
#include <memory>
#include <optional>
#include <string>
#include "flutter/fml/logging.h"
#include "flutter/fml/macros.h"
#include "impeller/geometry/rect.h"
#include "impeller/renderer/buffer_view.h"
#include "impeller/renderer/formats.h"
#include "impeller/renderer/pipeline.h"
@ -69,6 +71,19 @@ struct Command {
PrimitiveType primitive_type = PrimitiveType::kTriangle;
WindingOrder winding = WindingOrder::kClockwise;
uint32_t stencil_reference = 0u;
//----------------------------------------------------------------------------
/// The viewport coordinates that the rasterizer linearly maps normalized
/// device coordinates to.
/// If unset, the viewport is the size of the render target with a zero
/// origin, znear=0, and zfar=1.
///
std::optional<Viewport> viewport;
//----------------------------------------------------------------------------
/// The scissor rect to use for clipping writes to the render target. The
/// scissor rect must lie entirely within the render target.
/// If unset, no scissor is applied.
///
std::optional<IRect> scissor;
bool BindVertices(const VertexBuffer& buffer);

View File

@ -11,6 +11,8 @@
#include "flutter/fml/hash_combine.h"
#include "flutter/fml/macros.h"
#include "impeller/geometry/rect.h"
#include "impeller/geometry/scalar.h"
#include "impeller/geometry/color.h"
namespace impeller {
@ -149,6 +151,12 @@ enum class PrimitiveType {
// checks. Hence, they are not supported here.
};
struct Viewport {
Rect rect;
Scalar znear = 0.0f;
Scalar zfar = 1.0f;
};
enum class MinMagFilter {
/// Select nearest to the sample point. Most widely supported.
kNearest,