mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Add viewport and scissor support (flutter/engine#9)
This commit is contained in:
parent
3be670ac64
commit
6fa7495680
@ -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
|
||||
|
||||
@ -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(); }
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user