mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Impeller] Stencil -> Clip (flutter/engine#46519)
The days of using the stencil buffer for clip tracking may be numbered, so move away from mentioning the stencil buffer for concepts that are actually about clips.
This commit is contained in:
parent
06f2bee3bf
commit
4b271e17c5
@ -61,7 +61,7 @@ void Canvas::Save(bool create_subpass,
|
||||
auto entry = CanvasStackEntry{};
|
||||
entry.xformation = xformation_stack_.back().xformation;
|
||||
entry.cull_rect = xformation_stack_.back().cull_rect;
|
||||
entry.stencil_depth = xformation_stack_.back().stencil_depth;
|
||||
entry.clip_depth = xformation_stack_.back().clip_depth;
|
||||
if (create_subpass) {
|
||||
entry.rendering_mode = Entity::RenderingMode::kSubpass;
|
||||
auto subpass = std::make_unique<EntityPass>();
|
||||
@ -82,7 +82,7 @@ void Canvas::Save(bool create_subpass,
|
||||
subpass->SetBlendMode(blend_mode);
|
||||
current_pass_ = GetCurrentPass().AddSubpass(std::move(subpass));
|
||||
current_pass_->SetTransformation(xformation_stack_.back().xformation);
|
||||
current_pass_->SetStencilDepth(xformation_stack_.back().stencil_depth);
|
||||
current_pass_->SetClipDepth(xformation_stack_.back().clip_depth);
|
||||
}
|
||||
xformation_stack_.emplace_back(entry);
|
||||
}
|
||||
@ -172,7 +172,7 @@ void Canvas::RestoreToCount(size_t count) {
|
||||
void Canvas::DrawPath(const Path& path, const Paint& paint) {
|
||||
Entity entity;
|
||||
entity.SetTransformation(GetCurrentTransformation());
|
||||
entity.SetStencilDepth(GetStencilDepth());
|
||||
entity.SetClipDepth(GetClipDepth());
|
||||
entity.SetBlendMode(paint.blend_mode);
|
||||
entity.SetContents(paint.WithFilters(paint.CreateContentsForEntity(path)));
|
||||
|
||||
@ -182,7 +182,7 @@ void Canvas::DrawPath(const Path& path, const Paint& paint) {
|
||||
void Canvas::DrawPaint(const Paint& paint) {
|
||||
Entity entity;
|
||||
entity.SetTransformation(GetCurrentTransformation());
|
||||
entity.SetStencilDepth(GetStencilDepth());
|
||||
entity.SetClipDepth(GetClipDepth());
|
||||
entity.SetBlendMode(paint.blend_mode);
|
||||
entity.SetContents(paint.CreateContentsForEntity({}, true));
|
||||
|
||||
@ -216,7 +216,7 @@ bool Canvas::AttemptDrawBlurredRRect(const Rect& rect,
|
||||
|
||||
Entity entity;
|
||||
entity.SetTransformation(GetCurrentTransformation());
|
||||
entity.SetStencilDepth(GetStencilDepth());
|
||||
entity.SetClipDepth(GetClipDepth());
|
||||
entity.SetBlendMode(new_paint.blend_mode);
|
||||
entity.SetContents(new_paint.WithFilters(std::move(contents)));
|
||||
|
||||
@ -237,7 +237,7 @@ void Canvas::DrawRect(Rect rect, const Paint& paint) {
|
||||
|
||||
Entity entity;
|
||||
entity.SetTransformation(GetCurrentTransformation());
|
||||
entity.SetStencilDepth(GetStencilDepth());
|
||||
entity.SetClipDepth(GetClipDepth());
|
||||
entity.SetBlendMode(paint.blend_mode);
|
||||
entity.SetContents(paint.WithFilters(
|
||||
paint.CreateContentsForGeometry(Geometry::MakeRect(rect))));
|
||||
@ -256,7 +256,7 @@ void Canvas::DrawRRect(Rect rect, Scalar corner_radius, const Paint& paint) {
|
||||
if (paint.style == Paint::Style::kFill) {
|
||||
Entity entity;
|
||||
entity.SetTransformation(GetCurrentTransformation());
|
||||
entity.SetStencilDepth(GetStencilDepth());
|
||||
entity.SetClipDepth(GetClipDepth());
|
||||
entity.SetBlendMode(paint.blend_mode);
|
||||
entity.SetContents(paint.WithFilters(
|
||||
paint.CreateContentsForGeometry(Geometry::MakeFillPath(path))));
|
||||
@ -370,11 +370,11 @@ void Canvas::ClipGeometry(std::unique_ptr<Geometry> geometry,
|
||||
Entity entity;
|
||||
entity.SetTransformation(GetCurrentTransformation());
|
||||
entity.SetContents(std::move(contents));
|
||||
entity.SetStencilDepth(GetStencilDepth());
|
||||
entity.SetClipDepth(GetClipDepth());
|
||||
|
||||
GetCurrentPass().AddEntity(entity);
|
||||
|
||||
++xformation_stack_.back().stencil_depth;
|
||||
++xformation_stack_.back().clip_depth;
|
||||
xformation_stack_.back().contains_clips = true;
|
||||
}
|
||||
|
||||
@ -409,7 +409,7 @@ void Canvas::RestoreClip() {
|
||||
// This path is empty because ClipRestoreContents just generates a quad that
|
||||
// takes up the full render target.
|
||||
entity.SetContents(std::make_shared<ClipRestoreContents>());
|
||||
entity.SetStencilDepth(GetStencilDepth());
|
||||
entity.SetClipDepth(GetClipDepth());
|
||||
|
||||
GetCurrentPass().AddEntity(entity);
|
||||
}
|
||||
@ -424,7 +424,7 @@ void Canvas::DrawPoints(std::vector<Point> points,
|
||||
|
||||
Entity entity;
|
||||
entity.SetTransformation(GetCurrentTransformation());
|
||||
entity.SetStencilDepth(GetStencilDepth());
|
||||
entity.SetClipDepth(GetClipDepth());
|
||||
entity.SetBlendMode(paint.blend_mode);
|
||||
entity.SetContents(paint.WithFilters(paint.CreateContentsForGeometry(
|
||||
Geometry::MakePointField(std::move(points), radius,
|
||||
@ -443,15 +443,15 @@ void Canvas::DrawPicture(const Picture& picture) {
|
||||
|
||||
pass->IterateAllElements([&](auto& element) -> bool {
|
||||
if (auto entity = std::get_if<Entity>(&element)) {
|
||||
entity->IncrementStencilDepth(GetStencilDepth());
|
||||
entity->IncrementStencilDepth(GetClipDepth());
|
||||
entity->SetTransformation(GetCurrentTransformation() *
|
||||
entity->GetTransformation());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
|
||||
subpass->get()->SetStencilDepth(subpass->get()->GetStencilDepth() +
|
||||
GetStencilDepth());
|
||||
subpass->get()->SetClipDepth(subpass->get()->GetClipDepth() +
|
||||
GetClipDepth());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -502,7 +502,7 @@ void Canvas::DrawImageRect(const std::shared_ptr<Image>& image,
|
||||
|
||||
Entity entity;
|
||||
entity.SetBlendMode(paint.blend_mode);
|
||||
entity.SetStencilDepth(GetStencilDepth());
|
||||
entity.SetClipDepth(GetClipDepth());
|
||||
entity.SetContents(paint.WithFilters(contents));
|
||||
entity.SetTransformation(GetCurrentTransformation());
|
||||
|
||||
@ -524,8 +524,8 @@ EntityPass& Canvas::GetCurrentPass() {
|
||||
return *current_pass_;
|
||||
}
|
||||
|
||||
size_t Canvas::GetStencilDepth() const {
|
||||
return xformation_stack_.back().stencil_depth;
|
||||
size_t Canvas::GetClipDepth() const {
|
||||
return xformation_stack_.back().clip_depth;
|
||||
}
|
||||
|
||||
void Canvas::SaveLayer(const Paint& paint,
|
||||
@ -549,7 +549,7 @@ void Canvas::DrawTextFrame(const std::shared_ptr<TextFrame>& text_frame,
|
||||
Point position,
|
||||
const Paint& paint) {
|
||||
Entity entity;
|
||||
entity.SetStencilDepth(GetStencilDepth());
|
||||
entity.SetClipDepth(GetClipDepth());
|
||||
entity.SetBlendMode(paint.blend_mode);
|
||||
|
||||
auto text_contents = std::make_shared<TextContents>();
|
||||
@ -600,7 +600,7 @@ void Canvas::DrawVertices(const std::shared_ptr<VerticesGeometry>& vertices,
|
||||
|
||||
Entity entity;
|
||||
entity.SetTransformation(GetCurrentTransformation());
|
||||
entity.SetStencilDepth(GetStencilDepth());
|
||||
entity.SetClipDepth(GetClipDepth());
|
||||
entity.SetBlendMode(paint.blend_mode);
|
||||
|
||||
// If there are no vertex color or texture coordinates. Or if there
|
||||
@ -673,7 +673,7 @@ void Canvas::DrawAtlas(const std::shared_ptr<Image>& atlas,
|
||||
|
||||
Entity entity;
|
||||
entity.SetTransformation(GetCurrentTransformation());
|
||||
entity.SetStencilDepth(GetStencilDepth());
|
||||
entity.SetClipDepth(GetClipDepth());
|
||||
entity.SetBlendMode(paint.blend_mode);
|
||||
entity.SetContents(paint.WithFilters(contents));
|
||||
|
||||
|
||||
@ -34,7 +34,7 @@ struct CanvasStackEntry {
|
||||
Matrix xformation;
|
||||
// |cull_rect| is conservative screen-space bounds of the clipped output area
|
||||
std::optional<Rect> cull_rect;
|
||||
size_t stencil_depth = 0u;
|
||||
size_t clip_depth = 0u;
|
||||
Entity::RenderingMode rendering_mode = Entity::RenderingMode::kDirect;
|
||||
bool contains_clips = false;
|
||||
};
|
||||
@ -171,7 +171,7 @@ class Canvas {
|
||||
|
||||
EntityPass& GetCurrentPass();
|
||||
|
||||
size_t GetStencilDepth() const;
|
||||
size_t GetClipDepth() const;
|
||||
|
||||
void ClipGeometry(std::unique_ptr<Geometry> geometry,
|
||||
Entity::ClipOperation clip_op);
|
||||
|
||||
@ -250,7 +250,7 @@ bool AtlasContents::Render(const ContentContext& renderer,
|
||||
DEBUG_COMMAND_INFO(
|
||||
cmd, SPrintF("DrawAtlas Blend (%s)", BlendModeToString(blend_mode_)));
|
||||
cmd.BindVertices(vtx_buffer);
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
auto options = OptionsFromPass(pass);
|
||||
cmd.pipeline = renderer.GetPorterDuffBlendPipeline(options);
|
||||
|
||||
@ -425,7 +425,7 @@ bool AtlasTextureContents::Render(const ContentContext& renderer,
|
||||
|
||||
auto options = OptionsFromPassAndEntity(pass, entity);
|
||||
cmd.pipeline = renderer.GetTexturePipeline(options);
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer));
|
||||
VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info));
|
||||
FS::BindTextureSampler(cmd, texture,
|
||||
@ -515,7 +515,7 @@ bool AtlasColorContents::Render(const ContentContext& renderer,
|
||||
auto opts = OptionsFromPassAndEntity(pass, entity);
|
||||
opts.blend_mode = BlendMode::kSourceOver;
|
||||
cmd.pipeline = renderer.GetGeometryColorPipeline(opts);
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer));
|
||||
VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info));
|
||||
FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info));
|
||||
|
||||
@ -34,31 +34,29 @@ std::optional<Rect> ClipContents::GetCoverage(const Entity& entity) const {
|
||||
return std::nullopt;
|
||||
};
|
||||
|
||||
Contents::StencilCoverage ClipContents::GetStencilCoverage(
|
||||
Contents::ClipCoverage ClipContents::GetClipCoverage(
|
||||
const Entity& entity,
|
||||
const std::optional<Rect>& current_stencil_coverage) const {
|
||||
if (!current_stencil_coverage.has_value()) {
|
||||
return {.type = StencilCoverage::Type::kAppend, .coverage = std::nullopt};
|
||||
const std::optional<Rect>& current_clip_coverage) const {
|
||||
if (!current_clip_coverage.has_value()) {
|
||||
return {.type = ClipCoverage::Type::kAppend, .coverage = std::nullopt};
|
||||
}
|
||||
switch (clip_op_) {
|
||||
case Entity::ClipOperation::kDifference:
|
||||
// This can be optimized further by considering cases when the bounds of
|
||||
// the current stencil will shrink.
|
||||
return {.type = StencilCoverage::Type::kAppend,
|
||||
.coverage = current_stencil_coverage};
|
||||
return {.type = ClipCoverage::Type::kAppend,
|
||||
.coverage = current_clip_coverage};
|
||||
case Entity::ClipOperation::kIntersect:
|
||||
if (!geometry_) {
|
||||
return {.type = StencilCoverage::Type::kAppend,
|
||||
.coverage = std::nullopt};
|
||||
return {.type = ClipCoverage::Type::kAppend, .coverage = std::nullopt};
|
||||
}
|
||||
auto coverage = geometry_->GetCoverage(entity.GetTransformation());
|
||||
if (!coverage.has_value() || !current_stencil_coverage.has_value()) {
|
||||
return {.type = StencilCoverage::Type::kAppend,
|
||||
.coverage = std::nullopt};
|
||||
if (!coverage.has_value() || !current_clip_coverage.has_value()) {
|
||||
return {.type = ClipCoverage::Type::kAppend, .coverage = std::nullopt};
|
||||
}
|
||||
return {
|
||||
.type = StencilCoverage::Type::kAppend,
|
||||
.coverage = current_stencil_coverage->Intersection(coverage.value()),
|
||||
.type = ClipCoverage::Type::kAppend,
|
||||
.coverage = current_clip_coverage->Intersection(coverage.value()),
|
||||
};
|
||||
}
|
||||
FML_UNREACHABLE();
|
||||
@ -66,7 +64,7 @@ Contents::StencilCoverage ClipContents::GetStencilCoverage(
|
||||
|
||||
bool ClipContents::ShouldRender(
|
||||
const Entity& entity,
|
||||
const std::optional<Rect>& stencil_coverage) const {
|
||||
const std::optional<Rect>& clip_coverage) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -87,7 +85,7 @@ bool ClipContents::Render(const ContentContext& renderer,
|
||||
|
||||
auto options = OptionsFromPass(pass);
|
||||
options.blend_mode = BlendMode::kDestination;
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
options.stencil_compare = CompareFunction::kEqual;
|
||||
options.stencil_operation = StencilOperation::kIncrementClamp;
|
||||
|
||||
@ -113,7 +111,7 @@ bool ClipContents::Render(const ContentContext& renderer,
|
||||
{
|
||||
DEBUG_COMMAND_INFO(cmd, "Difference Clip (Punch)");
|
||||
|
||||
cmd.stencil_reference = entity.GetStencilDepth() + 1;
|
||||
cmd.stencil_reference = entity.GetClipDepth() + 1;
|
||||
options.stencil_compare = CompareFunction::kEqual;
|
||||
options.stencil_operation = StencilOperation::kDecrementClamp;
|
||||
}
|
||||
@ -155,15 +153,15 @@ std::optional<Rect> ClipRestoreContents::GetCoverage(
|
||||
return std::nullopt;
|
||||
};
|
||||
|
||||
Contents::StencilCoverage ClipRestoreContents::GetStencilCoverage(
|
||||
Contents::ClipCoverage ClipRestoreContents::GetClipCoverage(
|
||||
const Entity& entity,
|
||||
const std::optional<Rect>& current_stencil_coverage) const {
|
||||
return {.type = StencilCoverage::Type::kRestore, .coverage = std::nullopt};
|
||||
const std::optional<Rect>& current_clip_coverage) const {
|
||||
return {.type = ClipCoverage::Type::kRestore, .coverage = std::nullopt};
|
||||
}
|
||||
|
||||
bool ClipRestoreContents::ShouldRender(
|
||||
const Entity& entity,
|
||||
const std::optional<Rect>& stencil_coverage) const {
|
||||
const std::optional<Rect>& clip_coverage) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -186,7 +184,7 @@ bool ClipRestoreContents::Render(const ContentContext& renderer,
|
||||
options.stencil_operation = StencilOperation::kSetToReferenceValue;
|
||||
options.primitive_type = PrimitiveType::kTriangleStrip;
|
||||
cmd.pipeline = renderer.GetClipPipeline(options);
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
|
||||
// Create a rect that covers either the given restore area, or the whole
|
||||
// render target texture.
|
||||
|
||||
@ -29,13 +29,13 @@ class ClipContents final : public Contents {
|
||||
std::optional<Rect> GetCoverage(const Entity& entity) const override;
|
||||
|
||||
// |Contents|
|
||||
StencilCoverage GetStencilCoverage(
|
||||
ClipCoverage GetClipCoverage(
|
||||
const Entity& entity,
|
||||
const std::optional<Rect>& current_stencil_coverage) const override;
|
||||
const std::optional<Rect>& current_clip_coverage) const override;
|
||||
|
||||
// |Contents|
|
||||
bool ShouldRender(const Entity& entity,
|
||||
const std::optional<Rect>& stencil_coverage) const override;
|
||||
const std::optional<Rect>& clip_coverage) const override;
|
||||
|
||||
// |Contents|
|
||||
bool Render(const ContentContext& renderer,
|
||||
@ -70,13 +70,13 @@ class ClipRestoreContents final : public Contents {
|
||||
std::optional<Rect> GetCoverage(const Entity& entity) const override;
|
||||
|
||||
// |Contents|
|
||||
StencilCoverage GetStencilCoverage(
|
||||
ClipCoverage GetClipCoverage(
|
||||
const Entity& entity,
|
||||
const std::optional<Rect>& current_stencil_coverage) const override;
|
||||
const std::optional<Rect>& current_clip_coverage) const override;
|
||||
|
||||
// |Contents|
|
||||
bool ShouldRender(const Entity& entity,
|
||||
const std::optional<Rect>& stencil_coverage) const override;
|
||||
const std::optional<Rect>& clip_coverage) const override;
|
||||
|
||||
// |Contents|
|
||||
bool Render(const ContentContext& renderer,
|
||||
|
||||
@ -100,7 +100,7 @@ bool ConicalGradientContents::RenderSSBO(const ContentContext& renderer,
|
||||
|
||||
Command cmd;
|
||||
DEBUG_COMMAND_INFO(cmd, "ConicalGradientSSBOFill");
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
|
||||
auto geometry_result =
|
||||
GetGeometry()->GetPositionBuffer(renderer, entity, pass);
|
||||
@ -168,7 +168,7 @@ bool ConicalGradientContents::RenderTexture(const ContentContext& renderer,
|
||||
|
||||
Command cmd;
|
||||
DEBUG_COMMAND_INFO(cmd, "ConicalGradientFill");
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
|
||||
auto options = OptionsFromPassAndEntity(pass, entity);
|
||||
if (geometry_result.prevent_overdraw) {
|
||||
|
||||
@ -49,11 +49,11 @@ bool Contents::IsOpaque() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
Contents::StencilCoverage Contents::GetStencilCoverage(
|
||||
Contents::ClipCoverage Contents::GetClipCoverage(
|
||||
const Entity& entity,
|
||||
const std::optional<Rect>& current_stencil_coverage) const {
|
||||
return {.type = StencilCoverage::Type::kNoChange,
|
||||
.coverage = current_stencil_coverage};
|
||||
const std::optional<Rect>& current_clip_coverage) const {
|
||||
return {.type = ClipCoverage::Type::kNoChange,
|
||||
.coverage = current_clip_coverage};
|
||||
}
|
||||
|
||||
std::optional<Snapshot> Contents::RenderToSnapshot(
|
||||
@ -133,8 +133,8 @@ bool Contents::ApplyColorFilter(
|
||||
}
|
||||
|
||||
bool Contents::ShouldRender(const Entity& entity,
|
||||
const std::optional<Rect>& stencil_coverage) const {
|
||||
if (!stencil_coverage.has_value()) {
|
||||
const std::optional<Rect>& clip_coverage) const {
|
||||
if (!clip_coverage.has_value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -145,7 +145,7 @@ bool Contents::ShouldRender(const Entity& entity,
|
||||
if (coverage == Rect::MakeMaximum()) {
|
||||
return true;
|
||||
}
|
||||
return stencil_coverage->IntersectsWithRect(coverage.value());
|
||||
return clip_coverage->IntersectsWithRect(coverage.value());
|
||||
}
|
||||
|
||||
void Contents::SetCoverageHint(std::optional<Rect> coverage_hint) {
|
||||
|
||||
@ -36,7 +36,7 @@ class Contents {
|
||||
/// unpremultiplied color.
|
||||
using ColorFilterProc = std::function<Color(Color)>;
|
||||
|
||||
struct StencilCoverage {
|
||||
struct ClipCoverage {
|
||||
enum class Type { kNoChange, kAppend, kRestore };
|
||||
|
||||
Type type = Type::kNoChange;
|
||||
@ -89,18 +89,18 @@ class Contents {
|
||||
virtual bool IsOpaque() const;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// @brief Given the current screen space bounding rectangle of the stencil,
|
||||
/// return the expected stencil coverage after this draw call. This
|
||||
/// should only be implemented for contents that may write to the
|
||||
/// stencil buffer.
|
||||
/// @brief Given the current screen space bounding rectangle of the clip
|
||||
/// buffer, return the expected clip coverage after this draw call.
|
||||
/// This should only be implemented for contents that may write to the
|
||||
/// clip buffer.
|
||||
///
|
||||
virtual StencilCoverage GetStencilCoverage(
|
||||
virtual ClipCoverage GetClipCoverage(
|
||||
const Entity& entity,
|
||||
const std::optional<Rect>& current_stencil_coverage) const;
|
||||
const std::optional<Rect>& current_clip_coverage) const;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// @brief Render this contents to a snapshot, respecting the entity's
|
||||
/// transform, path, stencil depth, and blend mode.
|
||||
/// transform, path, clip depth, and blend mode.
|
||||
/// The result texture size is always the size of
|
||||
/// `GetCoverage(entity)`.
|
||||
///
|
||||
@ -113,7 +113,7 @@ class Contents {
|
||||
const std::string& label = "Snapshot") const;
|
||||
|
||||
virtual bool ShouldRender(const Entity& entity,
|
||||
const std::optional<Rect>& stencil_coverage) const;
|
||||
const std::optional<Rect>& clip_coverage) const;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// @brief Return the color source's intrinsic size, if available.
|
||||
|
||||
@ -114,7 +114,7 @@ static std::optional<Entity> AdvancedBlend(
|
||||
return std::nullopt;
|
||||
}
|
||||
return Entity::FromSnapshot(dst_snapshot, entity.GetBlendMode(),
|
||||
entity.GetStencilDepth());
|
||||
entity.GetClipDepth());
|
||||
}
|
||||
auto maybe_src_uvs = src_snapshot->GetCoverageUVs(coverage);
|
||||
if (!maybe_src_uvs.has_value()) {
|
||||
@ -122,7 +122,7 @@ static std::optional<Entity> AdvancedBlend(
|
||||
return std::nullopt;
|
||||
}
|
||||
return Entity::FromSnapshot(dst_snapshot, entity.GetBlendMode(),
|
||||
entity.GetStencilDepth());
|
||||
entity.GetClipDepth());
|
||||
}
|
||||
src_uvs = maybe_src_uvs.value();
|
||||
}
|
||||
@ -242,7 +242,7 @@ static std::optional<Entity> AdvancedBlend(
|
||||
? 1.0f
|
||||
: dst_snapshot->opacity) *
|
||||
alpha.value_or(1.0)},
|
||||
entity.GetBlendMode(), entity.GetStencilDepth());
|
||||
entity.GetBlendMode(), entity.GetClipDepth());
|
||||
}
|
||||
|
||||
std::optional<Entity> BlendFilterContents::CreateForegroundAdvancedBlend(
|
||||
@ -294,7 +294,7 @@ std::optional<Entity> BlendFilterContents::CreateForegroundAdvancedBlend(
|
||||
DEBUG_COMMAND_INFO(cmd, SPrintF("Foreground Advanced Blend Filter (%s)",
|
||||
BlendModeToString(blend_mode)));
|
||||
cmd.BindVertices(vtx_buffer);
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
auto options = OptionsFromPass(pass);
|
||||
|
||||
switch (blend_mode) {
|
||||
@ -391,7 +391,7 @@ std::optional<Entity> BlendFilterContents::CreateForegroundAdvancedBlend(
|
||||
|
||||
Entity sub_entity;
|
||||
sub_entity.SetContents(std::move(contents));
|
||||
sub_entity.SetStencilDepth(entity.GetStencilDepth());
|
||||
sub_entity.SetClipDepth(entity.GetClipDepth());
|
||||
|
||||
return sub_entity;
|
||||
}
|
||||
@ -416,7 +416,7 @@ std::optional<Entity> BlendFilterContents::CreateForegroundPorterDuffBlend(
|
||||
|
||||
Entity foreground_entity;
|
||||
foreground_entity.SetBlendMode(entity.GetBlendMode());
|
||||
foreground_entity.SetStencilDepth(entity.GetStencilDepth());
|
||||
foreground_entity.SetClipDepth(entity.GetClipDepth());
|
||||
foreground_entity.SetContents(std::move(contents));
|
||||
return foreground_entity;
|
||||
}
|
||||
@ -429,7 +429,7 @@ std::optional<Entity> BlendFilterContents::CreateForegroundPorterDuffBlend(
|
||||
|
||||
if (blend_mode == BlendMode::kDestination) {
|
||||
return Entity::FromSnapshot(dst_snapshot, entity.GetBlendMode(),
|
||||
entity.GetStencilDepth());
|
||||
entity.GetClipDepth());
|
||||
}
|
||||
|
||||
RenderProc render_proc = [foreground_color, coverage, dst_snapshot,
|
||||
@ -467,7 +467,7 @@ std::optional<Entity> BlendFilterContents::CreateForegroundPorterDuffBlend(
|
||||
DEBUG_COMMAND_INFO(cmd, SPrintF("Foreground PorterDuff Blend Filter (%s)",
|
||||
BlendModeToString(blend_mode)));
|
||||
cmd.BindVertices(vtx_buffer);
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
auto options = OptionsFromPass(pass);
|
||||
cmd.pipeline = renderer.GetPorterDuffBlendPipeline(options);
|
||||
|
||||
@ -519,7 +519,7 @@ std::optional<Entity> BlendFilterContents::CreateForegroundPorterDuffBlend(
|
||||
|
||||
Entity sub_entity;
|
||||
sub_entity.SetContents(std::move(contents));
|
||||
sub_entity.SetStencilDepth(entity.GetStencilDepth());
|
||||
sub_entity.SetClipDepth(entity.GetClipDepth());
|
||||
|
||||
return sub_entity;
|
||||
}
|
||||
@ -672,7 +672,7 @@ static std::optional<Entity> PipelineBlend(
|
||||
? 1.0f
|
||||
: dst_snapshot->opacity) *
|
||||
alpha.value_or(1.0)},
|
||||
entity.GetBlendMode(), entity.GetStencilDepth());
|
||||
entity.GetBlendMode(), entity.GetClipDepth());
|
||||
}
|
||||
|
||||
#define BLEND_CASE(mode) \
|
||||
|
||||
@ -114,7 +114,7 @@ std::optional<Entity> BorderMaskBlurFilterContents::RenderFilter(
|
||||
|
||||
cmd.pipeline = renderer.GetBorderMaskBlurPipeline(options);
|
||||
cmd.BindVertices(vtx_buffer);
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
|
||||
VS::FrameInfo frame_info;
|
||||
frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
|
||||
@ -146,7 +146,7 @@ std::optional<Entity> BorderMaskBlurFilterContents::RenderFilter(
|
||||
|
||||
Entity sub_entity;
|
||||
sub_entity.SetContents(std::move(contents));
|
||||
sub_entity.SetStencilDepth(entity.GetStencilDepth());
|
||||
sub_entity.SetClipDepth(entity.GetClipDepth());
|
||||
sub_entity.SetBlendMode(entity.GetBlendMode());
|
||||
return sub_entity;
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ std::optional<Entity> ColorMatrixFilterContents::RenderFilter(
|
||||
const Entity& entity, RenderPass& pass) -> bool {
|
||||
Command cmd;
|
||||
DEBUG_COMMAND_INFO(cmd, "Color Matrix Filter");
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
|
||||
auto options = OptionsFromPassAndEntity(pass, entity);
|
||||
cmd.pipeline = renderer.GetColorMatrixColorFilterPipeline(options);
|
||||
@ -117,7 +117,7 @@ std::optional<Entity> ColorMatrixFilterContents::RenderFilter(
|
||||
|
||||
Entity sub_entity;
|
||||
sub_entity.SetContents(std::move(contents));
|
||||
sub_entity.SetStencilDepth(entity.GetStencilDepth());
|
||||
sub_entity.SetClipDepth(entity.GetClipDepth());
|
||||
sub_entity.SetBlendMode(entity.GetBlendMode());
|
||||
return sub_entity;
|
||||
}
|
||||
|
||||
@ -104,17 +104,15 @@ std::optional<Entity> DirectionalGaussianBlurFilterContents::RenderFilter(
|
||||
}
|
||||
|
||||
if (blur_sigma_.sigma < kEhCloseEnough) {
|
||||
return Entity::FromSnapshot(
|
||||
input_snapshot.value(), entity.GetBlendMode(),
|
||||
entity.GetStencilDepth()); // No blur to render.
|
||||
return Entity::FromSnapshot(input_snapshot.value(), entity.GetBlendMode(),
|
||||
entity.GetClipDepth()); // No blur to render.
|
||||
}
|
||||
|
||||
// If the radius length is < .5, the shader will take at most 1 sample,
|
||||
// resulting in no blur.
|
||||
if (transformed_blur_radius_length < .5) {
|
||||
return Entity::FromSnapshot(
|
||||
input_snapshot.value(), entity.GetBlendMode(),
|
||||
entity.GetStencilDepth()); // No blur to render.
|
||||
return Entity::FromSnapshot(input_snapshot.value(), entity.GetBlendMode(),
|
||||
entity.GetClipDepth()); // No blur to render.
|
||||
}
|
||||
|
||||
// A matrix that rotates the snapshot space such that the blur direction is
|
||||
@ -273,7 +271,7 @@ std::optional<Entity> DirectionalGaussianBlurFilterContents::RenderFilter(
|
||||
(scaled_size / floored_size)),
|
||||
.sampler_descriptor = sampler_desc,
|
||||
.opacity = input_snapshot->opacity},
|
||||
entity.GetBlendMode(), entity.GetStencilDepth());
|
||||
entity.GetBlendMode(), entity.GetClipDepth());
|
||||
}
|
||||
|
||||
std::optional<Rect> DirectionalGaussianBlurFilterContents::GetFilterCoverage(
|
||||
|
||||
@ -47,7 +47,7 @@ std::optional<Entity> LinearToSrgbFilterContents::RenderFilter(
|
||||
const Entity& entity, RenderPass& pass) -> bool {
|
||||
Command cmd;
|
||||
DEBUG_COMMAND_INFO(cmd, "Linear to sRGB Filter");
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
|
||||
auto options = OptionsFromPassAndEntity(pass, entity);
|
||||
cmd.pipeline = renderer.GetLinearToSrgbFilterPipeline(options);
|
||||
@ -98,7 +98,7 @@ std::optional<Entity> LinearToSrgbFilterContents::RenderFilter(
|
||||
|
||||
Entity sub_entity;
|
||||
sub_entity.SetContents(std::move(contents));
|
||||
sub_entity.SetStencilDepth(entity.GetStencilDepth());
|
||||
sub_entity.SetClipDepth(entity.GetClipDepth());
|
||||
sub_entity.SetBlendMode(entity.GetBlendMode());
|
||||
return sub_entity;
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ std::optional<Entity> LocalMatrixFilterContents::RenderFilter(
|
||||
const std::optional<Rect>& coverage_hint) const {
|
||||
return Entity::FromSnapshot(
|
||||
inputs[0]->GetSnapshot("LocalMatrix", renderer, entity),
|
||||
entity.GetBlendMode(), entity.GetStencilDepth());
|
||||
entity.GetBlendMode(), entity.GetClipDepth());
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
@ -65,7 +65,7 @@ std::optional<Entity> MatrixFilterContents::RenderFilter(
|
||||
|
||||
snapshot->sampler_descriptor = sampler_descriptor_;
|
||||
return Entity::FromSnapshot(snapshot, entity.GetBlendMode(),
|
||||
entity.GetStencilDepth());
|
||||
entity.GetClipDepth());
|
||||
}
|
||||
|
||||
std::optional<Rect> MatrixFilterContents::GetFilterCoverage(
|
||||
|
||||
@ -59,7 +59,7 @@ std::optional<Entity> DirectionalMorphologyFilterContents::RenderFilter(
|
||||
|
||||
if (radius_.radius < kEhCloseEnough) {
|
||||
return Entity::FromSnapshot(input_snapshot.value(), entity.GetBlendMode(),
|
||||
entity.GetStencilDepth());
|
||||
entity.GetClipDepth());
|
||||
}
|
||||
|
||||
auto maybe_input_uvs = input_snapshot->GetCoverageUVs(coverage);
|
||||
@ -153,7 +153,7 @@ std::optional<Entity> DirectionalMorphologyFilterContents::RenderFilter(
|
||||
.transform = Matrix::MakeTranslation(coverage.origin),
|
||||
.sampler_descriptor = sampler_desc,
|
||||
.opacity = input_snapshot->opacity},
|
||||
entity.GetBlendMode(), entity.GetStencilDepth());
|
||||
entity.GetBlendMode(), entity.GetClipDepth());
|
||||
}
|
||||
|
||||
std::optional<Rect> DirectionalMorphologyFilterContents::GetFilterCoverage(
|
||||
|
||||
@ -47,7 +47,7 @@ std::optional<Entity> SrgbToLinearFilterContents::RenderFilter(
|
||||
const Entity& entity, RenderPass& pass) -> bool {
|
||||
Command cmd;
|
||||
DEBUG_COMMAND_INFO(cmd, "sRGB to Linear Filter");
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
|
||||
auto options = OptionsFromPassAndEntity(pass, entity);
|
||||
cmd.pipeline = renderer.GetSrgbToLinearFilterPipeline(options);
|
||||
@ -98,7 +98,7 @@ std::optional<Entity> SrgbToLinearFilterContents::RenderFilter(
|
||||
|
||||
Entity sub_entity;
|
||||
sub_entity.SetContents(std::move(contents));
|
||||
sub_entity.SetStencilDepth(entity.GetStencilDepth());
|
||||
sub_entity.SetClipDepth(entity.GetClipDepth());
|
||||
sub_entity.SetBlendMode(entity.GetBlendMode());
|
||||
return sub_entity;
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ std::optional<Entity> YUVToRGBFilterContents::RenderFilter(
|
||||
const Entity& entity, RenderPass& pass) -> bool {
|
||||
Command cmd;
|
||||
DEBUG_COMMAND_INFO(cmd, "YUV to RGB Filter");
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
|
||||
auto options = OptionsFromPassAndEntity(pass, entity);
|
||||
cmd.pipeline = renderer.GetYUVToRGBFilterPipeline(options);
|
||||
@ -133,7 +133,7 @@ std::optional<Entity> YUVToRGBFilterContents::RenderFilter(
|
||||
|
||||
Entity sub_entity;
|
||||
sub_entity.SetContents(std::move(contents));
|
||||
sub_entity.SetStencilDepth(entity.GetStencilDepth());
|
||||
sub_entity.SetClipDepth(entity.GetClipDepth());
|
||||
sub_entity.SetBlendMode(entity.GetBlendMode());
|
||||
return sub_entity;
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ bool FramebufferBlendContents::Render(const ContentContext& renderer,
|
||||
Command cmd;
|
||||
DEBUG_COMMAND_INFO(cmd, "Framebuffer Advanced Blend Filter");
|
||||
cmd.BindVertices(vtx_buffer);
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
|
||||
switch (blend_mode_) {
|
||||
case BlendMode::kScreen:
|
||||
|
||||
@ -101,7 +101,7 @@ bool LinearGradientContents::RenderTexture(const ContentContext& renderer,
|
||||
|
||||
Command cmd;
|
||||
DEBUG_COMMAND_INFO(cmd, "LinearGradientFill");
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
|
||||
auto options = OptionsFromPassAndEntity(pass, entity);
|
||||
if (geometry_result.prevent_overdraw) {
|
||||
@ -162,7 +162,7 @@ bool LinearGradientContents::RenderSSBO(const ContentContext& renderer,
|
||||
|
||||
Command cmd;
|
||||
DEBUG_COMMAND_INFO(cmd, "LinearGradientSSBOFill");
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
|
||||
auto geometry_result =
|
||||
GetGeometry()->GetPositionBuffer(renderer, entity, pass);
|
||||
|
||||
@ -99,7 +99,7 @@ bool RadialGradientContents::RenderSSBO(const ContentContext& renderer,
|
||||
|
||||
Command cmd;
|
||||
DEBUG_COMMAND_INFO(cmd, "RadialGradientSSBOFill");
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
|
||||
auto geometry_result =
|
||||
GetGeometry()->GetPositionBuffer(renderer, entity, pass);
|
||||
@ -160,7 +160,7 @@ bool RadialGradientContents::RenderTexture(const ContentContext& renderer,
|
||||
|
||||
Command cmd;
|
||||
DEBUG_COMMAND_INFO(cmd, "RadialGradientFill");
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
|
||||
auto options = OptionsFromPassAndEntity(pass, entity);
|
||||
if (geometry_result.prevent_overdraw) {
|
||||
|
||||
@ -153,7 +153,7 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer,
|
||||
Command cmd;
|
||||
DEBUG_COMMAND_INFO(cmd, "RuntimeEffectContents");
|
||||
cmd.pipeline = pipeline;
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
cmd.BindVertices(geometry_result.vertex_buffer);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@ -54,7 +54,7 @@ bool SolidColorContents::Render(const ContentContext& renderer,
|
||||
|
||||
Command cmd;
|
||||
DEBUG_COMMAND_INFO(cmd, "Solid Fill");
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
|
||||
auto geometry_result =
|
||||
GetGeometry()->GetPositionBuffer(renderer, entity, pass);
|
||||
|
||||
@ -96,7 +96,7 @@ bool SolidRRectBlurContents::Render(const ContentContext& renderer,
|
||||
color = Color::White();
|
||||
}
|
||||
cmd.pipeline = renderer.GetRRectBlurPipeline(opts);
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
|
||||
cmd.BindVertices(vtx_builder.CreateVertexBuffer(pass.GetTransientsBuffer()));
|
||||
|
||||
|
||||
@ -105,7 +105,7 @@ bool SweepGradientContents::RenderSSBO(const ContentContext& renderer,
|
||||
|
||||
Command cmd;
|
||||
DEBUG_COMMAND_INFO(cmd, "SweepGradientSSBOFill");
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
auto geometry_result =
|
||||
GetGeometry()->GetPositionBuffer(renderer, entity, pass);
|
||||
|
||||
@ -167,7 +167,7 @@ bool SweepGradientContents::RenderTexture(const ContentContext& renderer,
|
||||
|
||||
Command cmd;
|
||||
DEBUG_COMMAND_INFO(cmd, "SweepGradientFill");
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
|
||||
auto options = OptionsFromPassAndEntity(pass, entity);
|
||||
if (geometry_result.prevent_overdraw) {
|
||||
|
||||
@ -98,7 +98,7 @@ bool TextContents::Render(const ContentContext& renderer,
|
||||
} else {
|
||||
cmd.pipeline = renderer.GetGlyphAtlasColorPipeline(opts);
|
||||
}
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
|
||||
using VS = GlyphAtlasPipeline::VertexShader;
|
||||
using FS = GlyphAtlasPipeline::FragmentShader;
|
||||
|
||||
@ -170,7 +170,7 @@ bool TextureContents::Render(const ContentContext& renderer,
|
||||
cmd.pipeline = renderer.GetTexturePipeline(pipeline_options);
|
||||
#endif // IMPELLER_ENABLE_OPENGLES
|
||||
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer));
|
||||
VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info));
|
||||
if (is_external_texture) {
|
||||
|
||||
@ -145,7 +145,7 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
|
||||
DEBUG_COMMAND_INFO(cmd, "TextureFill");
|
||||
}
|
||||
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
|
||||
auto options = OptionsFromPassAndEntity(pass, entity);
|
||||
if (geometry_result.prevent_overdraw) {
|
||||
|
||||
@ -137,7 +137,7 @@ bool VerticesUVContents::Render(const ContentContext& renderer,
|
||||
auto opts = OptionsFromPassAndEntity(pass, entity);
|
||||
opts.primitive_type = geometry_result.type;
|
||||
cmd.pipeline = renderer.GetTexturePipeline(opts);
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
cmd.BindVertices(geometry_result.vertex_buffer);
|
||||
|
||||
VS::FrameInfo frame_info;
|
||||
@ -187,7 +187,7 @@ bool VerticesColorContents::Render(const ContentContext& renderer,
|
||||
auto opts = OptionsFromPassAndEntity(pass, entity);
|
||||
opts.primitive_type = geometry_result.type;
|
||||
cmd.pipeline = renderer.GetGeometryColorPipeline(opts);
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.stencil_reference = entity.GetClipDepth();
|
||||
cmd.BindVertices(geometry_result.vertex_buffer);
|
||||
|
||||
VS::FrameInfo frame_info;
|
||||
|
||||
@ -21,7 +21,7 @@ namespace impeller {
|
||||
std::optional<Entity> Entity::FromSnapshot(
|
||||
const std::optional<Snapshot>& snapshot,
|
||||
BlendMode blend_mode,
|
||||
uint32_t stencil_depth) {
|
||||
uint32_t clip_depth) {
|
||||
if (!snapshot.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
@ -36,7 +36,7 @@ std::optional<Entity> Entity::FromSnapshot(
|
||||
|
||||
Entity entity;
|
||||
entity.SetBlendMode(blend_mode);
|
||||
entity.SetStencilDepth(stencil_depth);
|
||||
entity.SetClipDepth(clip_depth);
|
||||
entity.SetTransformation(snapshot->transform);
|
||||
entity.SetContents(contents);
|
||||
return entity;
|
||||
@ -62,16 +62,16 @@ std::optional<Rect> Entity::GetCoverage() const {
|
||||
return contents_->GetCoverage(*this);
|
||||
}
|
||||
|
||||
Contents::StencilCoverage Entity::GetStencilCoverage(
|
||||
const std::optional<Rect>& current_stencil_coverage) const {
|
||||
Contents::ClipCoverage Entity::GetClipCoverage(
|
||||
const std::optional<Rect>& current_clip_coverage) const {
|
||||
if (!contents_) {
|
||||
return {};
|
||||
}
|
||||
return contents_->GetStencilCoverage(*this, current_stencil_coverage);
|
||||
return contents_->GetClipCoverage(*this, current_clip_coverage);
|
||||
}
|
||||
|
||||
bool Entity::ShouldRender(const std::optional<Rect>& stencil_coverage) const {
|
||||
return contents_->ShouldRender(*this, stencil_coverage);
|
||||
bool Entity::ShouldRender(const std::optional<Rect>& clip_coverage) const {
|
||||
return contents_->ShouldRender(*this, clip_coverage);
|
||||
}
|
||||
|
||||
void Entity::SetContents(std::shared_ptr<Contents> contents) {
|
||||
@ -82,16 +82,16 @@ const std::shared_ptr<Contents>& Entity::GetContents() const {
|
||||
return contents_;
|
||||
}
|
||||
|
||||
void Entity::SetStencilDepth(uint32_t depth) {
|
||||
stencil_depth_ = depth;
|
||||
void Entity::SetClipDepth(uint32_t depth) {
|
||||
clip_depth_ = depth;
|
||||
}
|
||||
|
||||
uint32_t Entity::GetStencilDepth() const {
|
||||
return stencil_depth_;
|
||||
uint32_t Entity::GetClipDepth() const {
|
||||
return clip_depth_;
|
||||
}
|
||||
|
||||
void Entity::IncrementStencilDepth(uint32_t increment) {
|
||||
stencil_depth_ += increment;
|
||||
clip_depth_ += increment;
|
||||
}
|
||||
|
||||
void Entity::SetBlendMode(BlendMode blend_mode) {
|
||||
|
||||
@ -65,7 +65,7 @@ class Entity {
|
||||
static std::optional<Entity> FromSnapshot(
|
||||
const std::optional<Snapshot>& snapshot,
|
||||
BlendMode blend_mode = BlendMode::kSourceOver,
|
||||
uint32_t stencil_depth = 0);
|
||||
uint32_t clip_depth = 0);
|
||||
|
||||
Entity();
|
||||
|
||||
@ -77,20 +77,20 @@ class Entity {
|
||||
|
||||
std::optional<Rect> GetCoverage() const;
|
||||
|
||||
Contents::StencilCoverage GetStencilCoverage(
|
||||
const std::optional<Rect>& current_stencil_coverage) const;
|
||||
Contents::ClipCoverage GetClipCoverage(
|
||||
const std::optional<Rect>& current_clip_coverage) const;
|
||||
|
||||
bool ShouldRender(const std::optional<Rect>& stencil_coverage) const;
|
||||
bool ShouldRender(const std::optional<Rect>& clip_coverage) const;
|
||||
|
||||
void SetContents(std::shared_ptr<Contents> contents);
|
||||
|
||||
const std::shared_ptr<Contents>& GetContents() const;
|
||||
|
||||
void SetStencilDepth(uint32_t stencil_depth);
|
||||
void SetClipDepth(uint32_t clip_depth);
|
||||
|
||||
void IncrementStencilDepth(uint32_t increment);
|
||||
|
||||
uint32_t GetStencilDepth() const;
|
||||
uint32_t GetClipDepth() const;
|
||||
|
||||
void SetBlendMode(BlendMode blend_mode);
|
||||
|
||||
@ -116,7 +116,7 @@ class Entity {
|
||||
Matrix transformation_;
|
||||
std::shared_ptr<Contents> contents_;
|
||||
BlendMode blend_mode_ = BlendMode::kSourceOver;
|
||||
uint32_t stencil_depth_ = 0u;
|
||||
uint32_t clip_depth_ = 0u;
|
||||
mutable Capture capture_;
|
||||
};
|
||||
|
||||
|
||||
@ -352,9 +352,9 @@ bool EntityPass::Render(ContentContext& renderer,
|
||||
return true;
|
||||
});
|
||||
|
||||
StencilCoverageStack stencil_coverage_stack = {StencilCoverageLayer{
|
||||
ClipCoverageStack clip_coverage_stack = {ClipCoverageLayer{
|
||||
.coverage = Rect::MakeSize(root_render_target.GetRenderTargetSize()),
|
||||
.stencil_depth = 0}};
|
||||
.clip_depth = 0}};
|
||||
|
||||
bool supports_onscreen_backdrop_reads =
|
||||
renderer.GetDeviceCapabilities().SupportsReadFromOnscreenTexture() &&
|
||||
@ -378,7 +378,7 @@ bool EntityPass::Render(ContentContext& renderer,
|
||||
Point(), // global_pass_position
|
||||
Point(), // local_pass_position
|
||||
0, // pass_depth
|
||||
stencil_coverage_stack // stencil_coverage_stack
|
||||
clip_coverage_stack // clip_coverage_stack
|
||||
)) {
|
||||
// Validation error messages are triggered for all `OnRender()` failure
|
||||
// cases.
|
||||
@ -490,7 +490,7 @@ bool EntityPass::Render(ContentContext& renderer,
|
||||
Point(), // global_pass_position
|
||||
Point(), // local_pass_position
|
||||
0, // pass_depth
|
||||
stencil_coverage_stack); // stencil_coverage_stack
|
||||
clip_coverage_stack); // clip_coverage_stack
|
||||
}
|
||||
|
||||
EntityPass::EntityResult EntityPass::GetEntityForElement(
|
||||
@ -501,8 +501,8 @@ EntityPass::EntityResult EntityPass::GetEntityForElement(
|
||||
ISize root_pass_size,
|
||||
Point global_pass_position,
|
||||
uint32_t pass_depth,
|
||||
StencilCoverageStack& stencil_coverage_stack,
|
||||
size_t stencil_depth_floor) const {
|
||||
ClipCoverageStack& clip_coverage_stack,
|
||||
size_t clip_depth_floor) const {
|
||||
Entity element_entity;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@ -546,8 +546,8 @@ EntityPass::EntityResult EntityPass::GetEntityForElement(
|
||||
global_pass_position, // global_pass_position
|
||||
Point(), // local_pass_position
|
||||
pass_depth, // pass_depth
|
||||
stencil_coverage_stack, // stencil_coverage_stack
|
||||
stencil_depth_, // stencil_depth_floor
|
||||
clip_coverage_stack, // clip_coverage_stack
|
||||
clip_depth_, // clip_depth_floor
|
||||
nullptr, // backdrop_filter_contents
|
||||
pass_context.GetRenderPass(pass_depth) // collapsed_parent_pass
|
||||
)) {
|
||||
@ -581,14 +581,14 @@ EntityPass::EntityResult EntityPass::GetEntityForElement(
|
||||
pass_context.EndPass();
|
||||
}
|
||||
|
||||
if (stencil_coverage_stack.empty()) {
|
||||
if (clip_coverage_stack.empty()) {
|
||||
// The current clip is empty. This means the pass texture won't be
|
||||
// visible, so skip it.
|
||||
capture.CreateChild("Subpass Entity (Skipped: Empty clip A)");
|
||||
return EntityPass::EntityResult::Skip();
|
||||
}
|
||||
auto stencil_coverage_back = stencil_coverage_stack.back().coverage;
|
||||
if (!stencil_coverage_back.has_value()) {
|
||||
auto clip_coverage_back = clip_coverage_stack.back().coverage;
|
||||
if (!clip_coverage_back.has_value()) {
|
||||
capture.CreateChild("Subpass Entity (Skipped: Empty clip B)");
|
||||
return EntityPass::EntityResult::Skip();
|
||||
}
|
||||
@ -599,7 +599,7 @@ EntityPass::EntityResult EntityPass::GetEntityForElement(
|
||||
Rect(global_pass_position, Size(pass_context.GetPassTarget()
|
||||
.GetRenderTarget()
|
||||
.GetRenderTargetSize()))
|
||||
.Intersection(stencil_coverage_back.value());
|
||||
.Intersection(clip_coverage_back.value());
|
||||
if (!coverage_limit.has_value()) {
|
||||
capture.CreateChild("Subpass Entity (Skipped: Empty coverage limit A)");
|
||||
return EntityPass::EntityResult::Skip();
|
||||
@ -652,8 +652,8 @@ EntityPass::EntityResult EntityPass::GetEntityForElement(
|
||||
subpass_coverage->origin -
|
||||
global_pass_position, // local_pass_position
|
||||
++pass_depth, // pass_depth
|
||||
stencil_coverage_stack, // stencil_coverage_stack
|
||||
subpass->stencil_depth_, // stencil_depth_floor
|
||||
clip_coverage_stack, // clip_coverage_stack
|
||||
subpass->clip_depth_, // clip_depth_floor
|
||||
subpass_backdrop_filter_contents // backdrop_filter_contents
|
||||
)) {
|
||||
// Validation error messages are triggered for all `OnRender()` failure
|
||||
@ -686,7 +686,7 @@ EntityPass::EntityResult EntityPass::GetEntityForElement(
|
||||
capture.CreateChild("Entity (Subpass texture)");
|
||||
element_entity.SetCapture(subpass_texture_capture);
|
||||
element_entity.SetContents(std::move(offscreen_texture_contents));
|
||||
element_entity.SetStencilDepth(subpass->stencil_depth_);
|
||||
element_entity.SetClipDepth(subpass->clip_depth_);
|
||||
element_entity.SetBlendMode(subpass->blend_mode_);
|
||||
element_entity.SetTransformation(subpass_texture_capture.AddMatrix(
|
||||
"Transform", Matrix::MakeTranslation(Vector3(subpass_coverage->origin -
|
||||
@ -706,8 +706,8 @@ bool EntityPass::OnRender(
|
||||
Point global_pass_position,
|
||||
Point local_pass_position,
|
||||
uint32_t pass_depth,
|
||||
StencilCoverageStack& stencil_coverage_stack,
|
||||
size_t stencil_depth_floor,
|
||||
ClipCoverageStack& clip_coverage_stack,
|
||||
size_t clip_depth_floor,
|
||||
std::shared_ptr<Contents> backdrop_filter_contents,
|
||||
const std::optional<InlinePassContext::RenderPassResult>&
|
||||
collapsed_parent_pass) const {
|
||||
@ -728,8 +728,8 @@ bool EntityPass::OnRender(
|
||||
pass_context.GetRenderPass(pass_depth);
|
||||
}
|
||||
|
||||
auto render_element = [&stencil_depth_floor, &pass_context, &pass_depth,
|
||||
&renderer, &stencil_coverage_stack,
|
||||
auto render_element = [&clip_depth_floor, &pass_context, &pass_depth,
|
||||
&renderer, &clip_coverage_stack,
|
||||
&global_pass_position](Entity& element_entity) {
|
||||
auto result = pass_context.GetRenderPass(pass_depth);
|
||||
|
||||
@ -762,78 +762,77 @@ bool EntityPass::OnRender(
|
||||
}
|
||||
}
|
||||
|
||||
auto current_stencil_coverage = stencil_coverage_stack.back().coverage;
|
||||
if (current_stencil_coverage.has_value()) {
|
||||
auto current_clip_coverage = clip_coverage_stack.back().coverage;
|
||||
if (current_clip_coverage.has_value()) {
|
||||
// Entity transforms are relative to the current pass position, so we need
|
||||
// to check stencil coverage in the same space.
|
||||
current_stencil_coverage->origin -= global_pass_position;
|
||||
// to check clip coverage in the same space.
|
||||
current_clip_coverage->origin -= global_pass_position;
|
||||
}
|
||||
|
||||
if (!element_entity.ShouldRender(current_stencil_coverage)) {
|
||||
if (!element_entity.ShouldRender(current_clip_coverage)) {
|
||||
return true; // Nothing to render.
|
||||
}
|
||||
|
||||
auto stencil_coverage =
|
||||
element_entity.GetStencilCoverage(current_stencil_coverage);
|
||||
if (stencil_coverage.coverage.has_value()) {
|
||||
stencil_coverage.coverage->origin += global_pass_position;
|
||||
auto clip_coverage = element_entity.GetClipCoverage(current_clip_coverage);
|
||||
if (clip_coverage.coverage.has_value()) {
|
||||
clip_coverage.coverage->origin += global_pass_position;
|
||||
}
|
||||
|
||||
// The coverage hint tells the rendered Contents which portion of the
|
||||
// rendered output will actually be used, and so we set this to the current
|
||||
// stencil coverage (which is the max clip bounds). The contents may
|
||||
// clip coverage (which is the max clip bounds). The contents may
|
||||
// optionally use this hint to avoid unnecessary rendering work.
|
||||
if (element_entity.GetContents()->GetCoverageHint().has_value()) {
|
||||
// If the element already has a coverage hint (because its an advanced
|
||||
// blend), then we need to intersect the stencil coverage hint with the
|
||||
// blend), then we need to intersect the clip coverage hint with the
|
||||
// existing coverage hint.
|
||||
element_entity.GetContents()->SetCoverageHint(
|
||||
current_stencil_coverage->Intersection(
|
||||
current_clip_coverage->Intersection(
|
||||
element_entity.GetContents()->GetCoverageHint().value()));
|
||||
} else {
|
||||
element_entity.GetContents()->SetCoverageHint(current_stencil_coverage);
|
||||
element_entity.GetContents()->SetCoverageHint(current_clip_coverage);
|
||||
}
|
||||
|
||||
switch (stencil_coverage.type) {
|
||||
case Contents::StencilCoverage::Type::kNoChange:
|
||||
switch (clip_coverage.type) {
|
||||
case Contents::ClipCoverage::Type::kNoChange:
|
||||
break;
|
||||
case Contents::StencilCoverage::Type::kAppend: {
|
||||
auto op = stencil_coverage_stack.back().coverage;
|
||||
stencil_coverage_stack.push_back(StencilCoverageLayer{
|
||||
.coverage = stencil_coverage.coverage,
|
||||
.stencil_depth = element_entity.GetStencilDepth() + 1});
|
||||
FML_DCHECK(stencil_coverage_stack.back().stencil_depth ==
|
||||
stencil_coverage_stack.size() - 1);
|
||||
case Contents::ClipCoverage::Type::kAppend: {
|
||||
auto op = clip_coverage_stack.back().coverage;
|
||||
clip_coverage_stack.push_back(
|
||||
ClipCoverageLayer{.coverage = clip_coverage.coverage,
|
||||
.clip_depth = element_entity.GetClipDepth() + 1});
|
||||
FML_DCHECK(clip_coverage_stack.back().clip_depth ==
|
||||
clip_coverage_stack.size() - 1);
|
||||
|
||||
if (!op.has_value()) {
|
||||
// Running this append op won't impact the stencil because the whole
|
||||
// screen is already being clipped, so skip it.
|
||||
// Running this append op won't impact the clip buffer because the
|
||||
// whole screen is already being clipped, so skip it.
|
||||
return true;
|
||||
}
|
||||
} break;
|
||||
case Contents::StencilCoverage::Type::kRestore: {
|
||||
if (stencil_coverage_stack.back().stencil_depth <=
|
||||
element_entity.GetStencilDepth()) {
|
||||
// Drop stencil restores that will do nothing.
|
||||
case Contents::ClipCoverage::Type::kRestore: {
|
||||
if (clip_coverage_stack.back().clip_depth <=
|
||||
element_entity.GetClipDepth()) {
|
||||
// Drop clip restores that will do nothing.
|
||||
return true;
|
||||
}
|
||||
|
||||
auto restoration_depth = element_entity.GetStencilDepth();
|
||||
FML_DCHECK(restoration_depth < stencil_coverage_stack.size());
|
||||
auto restoration_depth = element_entity.GetClipDepth();
|
||||
FML_DCHECK(restoration_depth < clip_coverage_stack.size());
|
||||
|
||||
// We only need to restore the area that covers the coverage of the
|
||||
// stencil rect at target depth + 1.
|
||||
// clip rect at target depth + 1.
|
||||
std::optional<Rect> restore_coverage =
|
||||
(restoration_depth + 1 < stencil_coverage_stack.size())
|
||||
? stencil_coverage_stack[restoration_depth + 1].coverage
|
||||
(restoration_depth + 1 < clip_coverage_stack.size())
|
||||
? clip_coverage_stack[restoration_depth + 1].coverage
|
||||
: std::nullopt;
|
||||
if (restore_coverage.has_value()) {
|
||||
// Make the coverage rectangle relative to the current pass.
|
||||
restore_coverage->origin -= global_pass_position;
|
||||
}
|
||||
stencil_coverage_stack.resize(restoration_depth + 1);
|
||||
clip_coverage_stack.resize(restoration_depth + 1);
|
||||
|
||||
if (!stencil_coverage_stack.back().coverage.has_value()) {
|
||||
if (!clip_coverage_stack.back().coverage.has_value()) {
|
||||
// Running this restore op won't make anything renderable, so skip it.
|
||||
return true;
|
||||
}
|
||||
@ -856,8 +855,8 @@ bool EntityPass::OnRender(
|
||||
}
|
||||
#endif
|
||||
|
||||
element_entity.SetStencilDepth(element_entity.GetStencilDepth() -
|
||||
stencil_depth_floor);
|
||||
element_entity.SetClipDepth(element_entity.GetClipDepth() -
|
||||
clip_depth_floor);
|
||||
if (!element_entity.Render(renderer, *result.pass)) {
|
||||
VALIDATION_LOG << "Failed to render entity.";
|
||||
return false;
|
||||
@ -879,7 +878,7 @@ bool EntityPass::OnRender(
|
||||
backdrop_entity.SetContents(std::move(backdrop_filter_contents));
|
||||
backdrop_entity.SetTransformation(
|
||||
Matrix::MakeTranslation(Vector3(-local_pass_position)));
|
||||
backdrop_entity.SetStencilDepth(stencil_depth_floor);
|
||||
backdrop_entity.SetClipDepth(clip_depth_floor);
|
||||
|
||||
render_element(backdrop_entity);
|
||||
}
|
||||
@ -900,15 +899,15 @@ bool EntityPass::OnRender(
|
||||
}
|
||||
|
||||
EntityResult result =
|
||||
GetEntityForElement(element, // element
|
||||
renderer, // renderer
|
||||
capture, // capture
|
||||
pass_context, // pass_context
|
||||
root_pass_size, // root_pass_size
|
||||
global_pass_position, // global_pass_position
|
||||
pass_depth, // pass_depth
|
||||
stencil_coverage_stack, // stencil_coverage_stack
|
||||
stencil_depth_floor); // stencil_depth_floor
|
||||
GetEntityForElement(element, // element
|
||||
renderer, // renderer
|
||||
capture, // capture
|
||||
pass_context, // pass_context
|
||||
root_pass_size, // root_pass_size
|
||||
global_pass_position, // global_pass_position
|
||||
pass_depth, // pass_depth
|
||||
clip_coverage_stack, // clip_coverage_stack
|
||||
clip_depth_floor); // clip_depth_floor
|
||||
|
||||
switch (result.status) {
|
||||
case EntityResult::kSuccess:
|
||||
@ -1126,12 +1125,12 @@ void EntityPass::SetTransformation(Matrix xformation) {
|
||||
xformation_ = xformation;
|
||||
}
|
||||
|
||||
void EntityPass::SetStencilDepth(size_t stencil_depth) {
|
||||
stencil_depth_ = stencil_depth;
|
||||
void EntityPass::SetClipDepth(size_t clip_depth) {
|
||||
clip_depth_ = clip_depth;
|
||||
}
|
||||
|
||||
size_t EntityPass::GetStencilDepth() {
|
||||
return stencil_depth_;
|
||||
size_t EntityPass::GetClipDepth() {
|
||||
return clip_depth_;
|
||||
}
|
||||
|
||||
void EntityPass::SetBlendMode(BlendMode blend_mode) {
|
||||
|
||||
@ -43,12 +43,12 @@ class EntityPass {
|
||||
const Matrix& effect_transform,
|
||||
Entity::RenderingMode rendering_mode)>;
|
||||
|
||||
struct StencilCoverageLayer {
|
||||
struct ClipCoverageLayer {
|
||||
std::optional<Rect> coverage;
|
||||
size_t stencil_depth;
|
||||
size_t clip_depth;
|
||||
};
|
||||
|
||||
using StencilCoverageStack = std::vector<StencilCoverageLayer>;
|
||||
using ClipCoverageStack = std::vector<ClipCoverageLayer>;
|
||||
|
||||
EntityPass();
|
||||
|
||||
@ -129,9 +129,9 @@ class EntityPass {
|
||||
|
||||
void SetTransformation(Matrix xformation);
|
||||
|
||||
void SetStencilDepth(size_t stencil_depth);
|
||||
void SetClipDepth(size_t clip_depth);
|
||||
|
||||
size_t GetStencilDepth();
|
||||
size_t GetClipDepth();
|
||||
|
||||
void SetBlendMode(BlendMode blend_mode);
|
||||
|
||||
@ -182,8 +182,8 @@ class EntityPass {
|
||||
ISize root_pass_size,
|
||||
Point global_pass_position,
|
||||
uint32_t pass_depth,
|
||||
StencilCoverageStack& stencil_coverage_stack,
|
||||
size_t stencil_depth_floor) const;
|
||||
ClipCoverageStack& clip_coverage_stack,
|
||||
size_t clip_depth_floor) const;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// @brief OnRender is the internal command recording routine for
|
||||
@ -217,20 +217,20 @@ class EntityPass {
|
||||
/// and debugging purposes. This can vary
|
||||
/// depending on whether passes are
|
||||
/// collapsed or not.
|
||||
/// @param[in] stencil_coverage_stack A global stack of coverage rectangles
|
||||
/// for the stencil buffer at each depth.
|
||||
/// @param[in] clip_coverage_stack A global stack of coverage rectangles
|
||||
/// for the clip buffer at each depth.
|
||||
/// Higher depths are more restrictive.
|
||||
/// Used to cull Elements that we
|
||||
/// know won't result in a visible
|
||||
/// change.
|
||||
/// @param[in] stencil_depth_floor The stencil depth that a value of
|
||||
/// @param[in] clip_depth_floor The clip depth that a value of
|
||||
/// zero corresponds to in the given
|
||||
/// `pass_target` stencil buffer.
|
||||
/// `pass_target` clip buffer.
|
||||
/// When new `pass_target`s are created
|
||||
/// for subpasses, their stencils are
|
||||
/// for subpasses, their clip buffers are
|
||||
/// initialized at zero, and so this
|
||||
/// value is used to offset Entity clip
|
||||
/// depths to match the stencil.
|
||||
/// depths to match the clip buffer.
|
||||
/// @param[in] backdrop_filter_contents Optional. Is supplied, this contents
|
||||
/// is rendered prior to anything else in
|
||||
/// the `EntityPass`, offset by the
|
||||
@ -249,8 +249,8 @@ class EntityPass {
|
||||
Point global_pass_position,
|
||||
Point local_pass_position,
|
||||
uint32_t pass_depth,
|
||||
StencilCoverageStack& stencil_coverage_stack,
|
||||
size_t stencil_depth_floor = 0,
|
||||
ClipCoverageStack& clip_coverage_stack,
|
||||
size_t clip_depth_floor = 0,
|
||||
std::shared_ptr<Contents> backdrop_filter_contents = nullptr,
|
||||
const std::optional<InlinePassContext::RenderPassResult>&
|
||||
collapsed_parent_pass = std::nullopt) const;
|
||||
@ -261,7 +261,7 @@ class EntityPass {
|
||||
|
||||
EntityPass* superpass_ = nullptr;
|
||||
Matrix xformation_;
|
||||
size_t stencil_depth_ = 0u;
|
||||
size_t clip_depth_ = 0u;
|
||||
BlendMode blend_mode_ = BlendMode::kSourceOver;
|
||||
bool flood_clip_ = false;
|
||||
bool enable_offscreen_debug_checkerboard_ = false;
|
||||
|
||||
@ -1631,12 +1631,12 @@ TEST_P(EntityTest, ClipContentsShouldRenderIsCorrect) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(EntityTest, ClipContentsGetStencilCoverageIsCorrect) {
|
||||
TEST_P(EntityTest, ClipContentsGetClipCoverageIsCorrect) {
|
||||
// Intersection: No stencil coverage, no geometry.
|
||||
{
|
||||
auto clip = std::make_shared<ClipContents>();
|
||||
clip->SetClipOperation(Entity::ClipOperation::kIntersect);
|
||||
auto result = clip->GetStencilCoverage(Entity{}, Rect{});
|
||||
auto result = clip->GetClipCoverage(Entity{}, Rect{});
|
||||
|
||||
ASSERT_FALSE(result.coverage.has_value());
|
||||
}
|
||||
@ -1647,7 +1647,7 @@ TEST_P(EntityTest, ClipContentsGetStencilCoverageIsCorrect) {
|
||||
clip->SetClipOperation(Entity::ClipOperation::kIntersect);
|
||||
clip->SetGeometry(Geometry::MakeFillPath(
|
||||
PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
|
||||
auto result = clip->GetStencilCoverage(Entity{}, Rect{});
|
||||
auto result = clip->GetClipCoverage(Entity{}, Rect{});
|
||||
|
||||
ASSERT_FALSE(result.coverage.has_value());
|
||||
}
|
||||
@ -1657,7 +1657,7 @@ TEST_P(EntityTest, ClipContentsGetStencilCoverageIsCorrect) {
|
||||
auto clip = std::make_shared<ClipContents>();
|
||||
clip->SetClipOperation(Entity::ClipOperation::kIntersect);
|
||||
auto result =
|
||||
clip->GetStencilCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
|
||||
clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
|
||||
|
||||
ASSERT_FALSE(result.coverage.has_value());
|
||||
}
|
||||
@ -1669,11 +1669,11 @@ TEST_P(EntityTest, ClipContentsGetStencilCoverageIsCorrect) {
|
||||
clip->SetGeometry(Geometry::MakeFillPath(
|
||||
PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 50, 50)).TakePath()));
|
||||
auto result =
|
||||
clip->GetStencilCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
|
||||
clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
|
||||
|
||||
ASSERT_TRUE(result.coverage.has_value());
|
||||
ASSERT_RECT_NEAR(result.coverage.value(), Rect::MakeLTRB(0, 0, 50, 50));
|
||||
ASSERT_EQ(result.type, Contents::StencilCoverage::Type::kAppend);
|
||||
ASSERT_EQ(result.type, Contents::ClipCoverage::Type::kAppend);
|
||||
}
|
||||
|
||||
// Difference: With stencil coverage, with geometry.
|
||||
@ -1683,11 +1683,11 @@ TEST_P(EntityTest, ClipContentsGetStencilCoverageIsCorrect) {
|
||||
clip->SetGeometry(Geometry::MakeFillPath(
|
||||
PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 50, 50)).TakePath()));
|
||||
auto result =
|
||||
clip->GetStencilCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
|
||||
clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
|
||||
|
||||
ASSERT_TRUE(result.coverage.has_value());
|
||||
ASSERT_RECT_NEAR(result.coverage.value(), Rect::MakeLTRB(0, 0, 100, 100));
|
||||
ASSERT_EQ(result.type, Contents::StencilCoverage::Type::kAppend);
|
||||
ASSERT_EQ(result.type, Contents::ClipCoverage::Type::kAppend);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user