[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:
Brandon DeRosier 2023-10-03 15:06:07 -07:00 committed by GitHub
parent 06f2bee3bf
commit 4b271e17c5
34 changed files with 224 additions and 229 deletions

View File

@ -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));

View File

@ -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);

View File

@ -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));

View File

@ -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.

View File

@ -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,

View File

@ -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) {

View File

@ -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) {

View File

@ -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.

View File

@ -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) \

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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(

View File

@ -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;
}

View File

@ -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

View File

@ -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(

View File

@ -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(

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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:

View File

@ -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);

View File

@ -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) {

View File

@ -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);
//--------------------------------------------------------------------------

View File

@ -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);

View File

@ -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()));

View File

@ -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) {

View File

@ -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;

View File

@ -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) {

View File

@ -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) {

View File

@ -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;

View File

@ -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) {

View File

@ -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_;
};

View File

@ -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) {

View File

@ -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;

View File

@ -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);
}
}