diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 9b121e80d4edb..94c8d01005f64 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -218,7 +218,7 @@ void Canvas::Save(bool create_subpass, auto entry = CanvasStackEntry{}; entry.transform = transform_stack_.back().transform; entry.cull_rect = transform_stack_.back().cull_rect; - entry.clip_depth = transform_stack_.back().clip_depth; + entry.clip_height = transform_stack_.back().clip_height; if (create_subpass) { entry.rendering_mode = Entity::RenderingMode::kSubpass; auto subpass = std::make_unique(); @@ -244,7 +244,7 @@ void Canvas::Save(bool create_subpass, subpass->SetBlendMode(blend_mode); current_pass_ = GetCurrentPass().AddSubpass(std::move(subpass)); current_pass_->SetTransform(transform_stack_.back().transform); - current_pass_->SetClipDepth(transform_stack_.back().clip_depth); + current_pass_->SetClipDepth(transform_stack_.back().clip_height); } transform_stack_.emplace_back(entry); } @@ -336,7 +336,7 @@ void Canvas::RestoreToCount(size_t count) { void Canvas::DrawPath(const Path& path, const Paint& paint) { Entity entity; entity.SetTransform(GetCurrentTransform()); - entity.SetClipDepth(GetClipDepth()); + entity.SetClipDepth(GetClipHeight()); entity.SetBlendMode(paint.blend_mode); entity.SetContents(CreatePathContentsWithFilters(paint, path)); @@ -346,7 +346,7 @@ void Canvas::DrawPath(const Path& path, const Paint& paint) { void Canvas::DrawPaint(const Paint& paint) { Entity entity; entity.SetTransform(GetCurrentTransform()); - entity.SetClipDepth(GetClipDepth()); + entity.SetClipDepth(GetClipHeight()); entity.SetBlendMode(paint.blend_mode); entity.SetContents(CreateCoverContentsWithFilters(paint)); @@ -427,7 +427,7 @@ bool Canvas::AttemptDrawBlurredRRect(const Rect& rect, Entity blurred_rrect_entity; blurred_rrect_entity.SetTransform(GetCurrentTransform()); - blurred_rrect_entity.SetClipDepth(GetClipDepth()); + blurred_rrect_entity.SetClipDepth(GetClipHeight()); blurred_rrect_entity.SetBlendMode(rrect_paint.blend_mode); rrect_paint.mask_blur_descriptor = std::nullopt; @@ -447,7 +447,7 @@ bool Canvas::AttemptDrawBlurredRRect(const Rect& rect, // Then, draw the non-blurred RRect on top. Entity entity; entity.SetTransform(GetCurrentTransform()); - entity.SetClipDepth(GetClipDepth()); + entity.SetClipDepth(GetClipHeight()); entity.SetBlendMode(rrect_paint.blend_mode); entity.SetContents(CreateContentsForGeometryWithFilters( rrect_paint, Geometry::MakeRoundRect(rect, corner_radii))); @@ -474,7 +474,7 @@ bool Canvas::AttemptDrawBlurredRRect(const Rect& rect, void Canvas::DrawLine(const Point& p0, const Point& p1, const Paint& paint) { Entity entity; entity.SetTransform(GetCurrentTransform()); - entity.SetClipDepth(GetClipDepth()); + entity.SetClipDepth(GetClipHeight()); entity.SetBlendMode(paint.blend_mode); entity.SetContents(CreateContentsForGeometryWithFilters( paint, Geometry::MakeLine(p0, p1, paint.stroke_width, paint.stroke_cap))); @@ -494,7 +494,7 @@ void Canvas::DrawRect(const Rect& rect, const Paint& paint) { Entity entity; entity.SetTransform(GetCurrentTransform()); - entity.SetClipDepth(GetClipDepth()); + entity.SetClipDepth(GetClipHeight()); entity.SetBlendMode(paint.blend_mode); entity.SetContents( CreateContentsForGeometryWithFilters(paint, Geometry::MakeRect(rect))); @@ -521,7 +521,7 @@ void Canvas::DrawOval(const Rect& rect, const Paint& paint) { Entity entity; entity.SetTransform(GetCurrentTransform()); - entity.SetClipDepth(GetClipDepth()); + entity.SetClipDepth(GetClipHeight()); entity.SetBlendMode(paint.blend_mode); entity.SetContents( CreateContentsForGeometryWithFilters(paint, Geometry::MakeOval(rect))); @@ -539,7 +539,7 @@ void Canvas::DrawRRect(const Rect& rect, if (paint.style == Paint::Style::kFill) { Entity entity; entity.SetTransform(GetCurrentTransform()); - entity.SetClipDepth(GetClipDepth()); + entity.SetClipDepth(GetClipHeight()); entity.SetBlendMode(paint.blend_mode); entity.SetContents(CreateContentsForGeometryWithFilters( paint, Geometry::MakeRoundRect(rect, corner_radii))); @@ -568,7 +568,7 @@ void Canvas::DrawCircle(const Point& center, Entity entity; entity.SetTransform(GetCurrentTransform()); - entity.SetClipDepth(GetClipDepth()); + entity.SetClipDepth(GetClipHeight()); entity.SetBlendMode(paint.blend_mode); auto geometry = paint.style == Paint::Style::kStroke @@ -680,11 +680,11 @@ void Canvas::ClipGeometry(const std::shared_ptr& geometry, Entity entity; entity.SetTransform(GetCurrentTransform()); entity.SetContents(std::move(contents)); - entity.SetClipDepth(GetClipDepth()); + entity.SetClipDepth(GetClipHeight()); GetCurrentPass().PushClip(std::move(entity)); - ++transform_stack_.back().clip_depth; + ++transform_stack_.back().clip_height; ++transform_stack_.back().num_clips; } @@ -718,8 +718,9 @@ void Canvas::RestoreClip() { entity.SetTransform(GetCurrentTransform()); // This path is empty because ClipRestoreContents just generates a quad that // takes up the full render target. - entity.SetContents(std::make_shared()); - entity.SetClipDepth(GetClipDepth()); + auto clip_restore = std::make_shared(); + clip_restore->SetRestoreHeight(GetClipHeight()); + entity.SetContents(std::move(clip_restore)); AddEntityToCurrentPass(std::move(entity)); } @@ -734,7 +735,7 @@ void Canvas::DrawPoints(std::vector points, Entity entity; entity.SetTransform(GetCurrentTransform()); - entity.SetClipDepth(GetClipDepth()); + entity.SetClipDepth(GetClipHeight()); entity.SetBlendMode(paint.blend_mode); entity.SetContents(CreateContentsForGeometryWithFilters( paint, @@ -790,7 +791,7 @@ void Canvas::DrawImageRect(const std::shared_ptr& image, Entity entity; entity.SetBlendMode(paint.blend_mode); - entity.SetClipDepth(GetClipDepth()); + entity.SetClipDepth(GetClipHeight()); entity.SetContents(paint.WithFilters(contents)); entity.SetTransform(GetCurrentTransform()); @@ -818,8 +819,8 @@ EntityPass& Canvas::GetCurrentPass() { return *current_pass_; } -size_t Canvas::GetClipDepth() const { - return transform_stack_.back().clip_depth; +size_t Canvas::GetClipHeight() const { + return transform_stack_.back().clip_height; } void Canvas::AddEntityToCurrentPass(Entity entity) { @@ -866,7 +867,7 @@ void Canvas::DrawTextFrame(const std::shared_ptr& text_frame, Point position, const Paint& paint) { Entity entity; - entity.SetClipDepth(GetClipDepth()); + entity.SetClipDepth(GetClipHeight()); entity.SetBlendMode(paint.blend_mode); auto text_contents = std::make_shared(); @@ -918,7 +919,7 @@ void Canvas::DrawVertices(const std::shared_ptr& vertices, Entity entity; entity.SetTransform(GetCurrentTransform()); - entity.SetClipDepth(GetClipDepth()); + entity.SetClipDepth(GetClipHeight()); entity.SetBlendMode(paint.blend_mode); // If there are no vertex color or texture coordinates. Or if there @@ -1011,7 +1012,7 @@ void Canvas::DrawAtlas(const std::shared_ptr& atlas, Entity entity; entity.SetTransform(GetCurrentTransform()); - entity.SetClipDepth(GetClipDepth()); + entity.SetClipDepth(GetClipHeight()); entity.SetBlendMode(paint.blend_mode); entity.SetContents(paint.WithFilters(contents)); diff --git a/impeller/aiks/canvas.h b/impeller/aiks/canvas.h index 36ba4639b264d..eb2c14de7821a 100644 --- a/impeller/aiks/canvas.h +++ b/impeller/aiks/canvas.h @@ -32,7 +32,7 @@ struct CanvasStackEntry { Matrix transform; // |cull_rect| is conservative screen-space bounds of the clipped output area std::optional cull_rect; - size_t clip_depth = 0u; + size_t clip_height = 0u; // The number of clips tracked for this canvas stack entry. size_t num_clips = 0u; Entity::RenderingMode rendering_mode = Entity::RenderingMode::kDirect; @@ -192,7 +192,7 @@ class Canvas { EntityPass& GetCurrentPass(); - size_t GetClipDepth() const; + size_t GetClipHeight() const; void AddEntityToCurrentPass(Entity entity); diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc index ebad55f96c35c..9e01411f56a76 100644 --- a/impeller/entity/contents/atlas_contents.cc +++ b/impeller/entity/contents/atlas_contents.cc @@ -240,7 +240,6 @@ bool AtlasContents::Render(const ContentContext& renderer, SPrintF("DrawAtlas Blend (%s)", BlendModeToString(blend_mode_))); #endif // IMPELLER_DEBUG pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer)); - pass.SetStencilReference(entity.GetClipDepth()); pass.SetPipeline( renderer.GetPorterDuffBlendPipeline(OptionsFromPass(pass))); @@ -410,7 +409,6 @@ bool AtlasTextureContents::Render(const ContentContext& renderer, auto options = OptionsFromPassAndEntity(pass, entity); pass.SetPipeline(renderer.GetTexturePipeline(options)); - pass.SetStencilReference(entity.GetClipDepth()); pass.SetVertexBuffer(vertex_builder.CreateVertexBuffer(host_buffer)); VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info)); FS::BindTextureSampler(pass, texture, @@ -498,7 +496,6 @@ bool AtlasColorContents::Render(const ContentContext& renderer, auto opts = OptionsFromPassAndEntity(pass, entity); opts.blend_mode = BlendMode::kSourceOver; pass.SetPipeline(renderer.GetGeometryColorPipeline(opts)); - pass.SetStencilReference(entity.GetClipDepth()); pass.SetVertexBuffer(vertex_builder.CreateVertexBuffer(host_buffer)); VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info)); FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info)); diff --git a/impeller/entity/contents/clip_contents.cc b/impeller/entity/contents/clip_contents.cc index c1140b851ac7f..e38e73cbb1d3f 100644 --- a/impeller/entity/contents/clip_contents.cc +++ b/impeller/entity/contents/clip_contents.cc @@ -191,6 +191,14 @@ ClipRestoreContents::ClipRestoreContents() = default; ClipRestoreContents::~ClipRestoreContents() = default; +void ClipRestoreContents::SetRestoreHeight(size_t clip_height) { + restore_height_ = clip_height; +} + +size_t ClipRestoreContents::GetRestoreHeight() const { + return restore_height_; +} + void ClipRestoreContents::SetRestoreCoverage( std::optional restore_coverage) { restore_coverage_ = restore_coverage; @@ -230,7 +238,7 @@ bool ClipRestoreContents::Render(const ContentContext& renderer, options.stencil_mode = ContentContextOptions::StencilMode::kLegacyClipRestore; options.primitive_type = PrimitiveType::kTriangleStrip; pass.SetPipeline(renderer.GetClipPipeline(options)); - pass.SetStencilReference(entity.GetClipDepth()); + pass.SetStencilReference(0); // Create a rect that covers either the given restore area, or the whole // render target texture. diff --git a/impeller/entity/contents/clip_contents.h b/impeller/entity/contents/clip_contents.h index b519cc255e112..6044692c6962a 100644 --- a/impeller/entity/contents/clip_contents.h +++ b/impeller/entity/contents/clip_contents.h @@ -63,6 +63,10 @@ class ClipRestoreContents final : public Contents { ~ClipRestoreContents(); + void SetRestoreHeight(size_t clip_height); + + size_t GetRestoreHeight() const; + /// @brief The area on the pass texture where this clip restore will be /// applied. If unset, the entire pass texture will be restored. /// @@ -94,6 +98,7 @@ class ClipRestoreContents final : public Contents { private: std::optional restore_coverage_; + size_t restore_height_ = 0; ClipRestoreContents(const ClipRestoreContents&) = delete; diff --git a/impeller/entity/contents/color_source_contents.h b/impeller/entity/contents/color_source_contents.h index 6ec10f3507063..3c5b932100444 100644 --- a/impeller/entity/contents/color_source_contents.h +++ b/impeller/entity/contents/color_source_contents.h @@ -229,7 +229,6 @@ class ColorSourceContents : public Contents { auto restore = ClipRestoreContents(); restore.SetRestoreCoverage(GetCoverage(entity)); Entity restore_entity = entity.Clone(); - restore_entity.SetClipDepth(0); return restore.Render(renderer, restore_entity, pass); } return true; diff --git a/impeller/entity/contents/filters/blend_filter_contents.cc b/impeller/entity/contents/filters/blend_filter_contents.cc index 9a8e059331e80..2af8be96bb97f 100644 --- a/impeller/entity/contents/filters/blend_filter_contents.cc +++ b/impeller/entity/contents/filters/blend_filter_contents.cc @@ -111,16 +111,14 @@ static std::optional AdvancedBlend( if (!dst_snapshot.has_value()) { return std::nullopt; } - return Entity::FromSnapshot(dst_snapshot.value(), entity.GetBlendMode(), - entity.GetClipDepth()); + return Entity::FromSnapshot(dst_snapshot.value(), entity.GetBlendMode()); } auto maybe_src_uvs = src_snapshot->GetCoverageUVs(coverage); if (!maybe_src_uvs.has_value()) { if (!dst_snapshot.has_value()) { return std::nullopt; } - return Entity::FromSnapshot(dst_snapshot.value(), entity.GetBlendMode(), - entity.GetClipDepth()); + return Entity::FromSnapshot(dst_snapshot.value(), entity.GetBlendMode()); } src_uvs = maybe_src_uvs.value(); } @@ -253,7 +251,7 @@ static std::optional AdvancedBlend( ? 1.0f : dst_snapshot->opacity) * alpha.value_or(1.0)}, - entity.GetBlendMode(), entity.GetClipDepth()); + entity.GetBlendMode()); } std::optional BlendFilterContents::CreateForegroundAdvancedBlend( @@ -295,7 +293,6 @@ std::optional BlendFilterContents::CreateForegroundAdvancedBlend( BlendModeToString(blend_mode))); #endif // IMPELLER_DEBUG pass.SetVertexBuffer(std::move(vtx_buffer)); - pass.SetStencilReference(entity.GetClipDepth()); auto options = OptionsFromPass(pass); options.primitive_type = PrimitiveType::kTriangleStrip; @@ -397,7 +394,6 @@ std::optional BlendFilterContents::CreateForegroundAdvancedBlend( Entity sub_entity; sub_entity.SetContents(std::move(contents)); - sub_entity.SetClipDepth(entity.GetClipDepth()); return sub_entity; } @@ -422,8 +418,7 @@ std::optional BlendFilterContents::CreateForegroundPorterDuffBlend( } if (blend_mode == BlendMode::kDestination) { - return Entity::FromSnapshot(dst_snapshot.value(), entity.GetBlendMode(), - entity.GetClipDepth()); + return Entity::FromSnapshot(dst_snapshot.value(), entity.GetBlendMode()); } RenderProc render_proc = [foreground_color, dst_snapshot, blend_mode, @@ -450,7 +445,6 @@ std::optional BlendFilterContents::CreateForegroundPorterDuffBlend( BlendModeToString(blend_mode))); #endif // IMPELLER_DEBUG pass.SetVertexBuffer(std::move(vtx_buffer)); - pass.SetStencilReference(entity.GetClipDepth()); auto options = OptionsFromPass(pass); options.primitive_type = PrimitiveType::kTriangleStrip; pass.SetPipeline(renderer.GetPorterDuffBlendPipeline(options)); @@ -501,7 +495,6 @@ std::optional BlendFilterContents::CreateForegroundPorterDuffBlend( Entity sub_entity; sub_entity.SetContents(std::move(contents)); - sub_entity.SetClipDepth(entity.GetClipDepth()); return sub_entity; } @@ -667,7 +660,7 @@ static std::optional PipelineBlend( ? 1.0f : dst_snapshot->opacity) * alpha.value_or(1.0)}, - entity.GetBlendMode(), entity.GetClipDepth()); + entity.GetBlendMode()); } #define BLEND_CASE(mode) \ diff --git a/impeller/entity/contents/filters/border_mask_blur_filter_contents.cc b/impeller/entity/contents/filters/border_mask_blur_filter_contents.cc index 3179ad3c3bfe8..4510b31596c70 100644 --- a/impeller/entity/contents/filters/border_mask_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/border_mask_blur_filter_contents.cc @@ -118,7 +118,6 @@ std::optional BorderMaskBlurFilterContents::RenderFilter( pass.SetCommandLabel("Border Mask Blur Filter"); pass.SetPipeline(renderer.GetBorderMaskBlurPipeline(options)); pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer)); - pass.SetStencilReference(entity.GetClipDepth()); FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info)); VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info)); @@ -139,7 +138,6 @@ std::optional BorderMaskBlurFilterContents::RenderFilter( Entity sub_entity; sub_entity.SetContents(std::move(contents)); - sub_entity.SetClipDepth(entity.GetClipDepth()); sub_entity.SetBlendMode(entity.GetBlendMode()); return sub_entity; } diff --git a/impeller/entity/contents/filters/color_matrix_filter_contents.cc b/impeller/entity/contents/filters/color_matrix_filter_contents.cc index 9d5aa125471b2..6fb57717d3f1f 100644 --- a/impeller/entity/contents/filters/color_matrix_filter_contents.cc +++ b/impeller/entity/contents/filters/color_matrix_filter_contents.cc @@ -56,7 +56,6 @@ std::optional ColorMatrixFilterContents::RenderFilter( const ContentContext& renderer, const Entity& entity, RenderPass& pass) -> bool { pass.SetCommandLabel("Color Matrix Filter"); - pass.SetStencilReference(entity.GetClipDepth()); auto options = OptionsFromPassAndEntity(pass, entity); options.primitive_type = PrimitiveType::kTriangleStrip; @@ -116,7 +115,6 @@ std::optional ColorMatrixFilterContents::RenderFilter( Entity sub_entity; sub_entity.SetContents(std::move(contents)); - sub_entity.SetClipDepth(entity.GetClipDepth()); sub_entity.SetBlendMode(entity.GetBlendMode()); return sub_entity; } diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc index d589594856b3b..0840679de597f 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc @@ -264,8 +264,8 @@ Entity ApplyBlurStyle(FilterContents::BlurStyle blur_style, input, input_snapshot, std::move(blur_entity), geometry); case FilterContents::BlurStyle::kSolid: { - Entity snapshot_entity = Entity::FromSnapshot( - input_snapshot, entity.GetBlendMode(), entity.GetClipDepth()); + Entity snapshot_entity = + Entity::FromSnapshot(input_snapshot, entity.GetBlendMode()); Entity result; Matrix blurred_transform = blur_entity.GetTransform(); Matrix snapshot_transform = snapshot_entity.GetTransform(); @@ -423,8 +423,8 @@ std::optional GaussianBlurFilterContents::RenderFilter( } if (scaled_sigma.x < kEhCloseEnough && scaled_sigma.y < kEhCloseEnough) { - return Entity::FromSnapshot(input_snapshot.value(), entity.GetBlendMode(), - entity.GetClipDepth()); // No blur to render. + return Entity::FromSnapshot(input_snapshot.value(), + entity.GetBlendMode()); // No blur to render. } // In order to avoid shimmering in downsampling step, we should have mips. @@ -559,7 +559,7 @@ std::optional GaussianBlurFilterContents::RenderFilter( Matrix::MakeScale(1 / effective_scalar), .sampler_descriptor = sampler_desc, .opacity = input_snapshot->opacity}, - entity.GetBlendMode(), entity.GetClipDepth()); + entity.GetBlendMode()); return ApplyBlurStyle(mask_blur_style_, entity, inputs[0], input_snapshot.value(), std::move(blur_output_entity), diff --git a/impeller/entity/contents/filters/linear_to_srgb_filter_contents.cc b/impeller/entity/contents/filters/linear_to_srgb_filter_contents.cc index 937d9367e9319..f501e5d711f2f 100644 --- a/impeller/entity/contents/filters/linear_to_srgb_filter_contents.cc +++ b/impeller/entity/contents/filters/linear_to_srgb_filter_contents.cc @@ -45,7 +45,6 @@ std::optional LinearToSrgbFilterContents::RenderFilter( const ContentContext& renderer, const Entity& entity, RenderPass& pass) -> bool { pass.SetCommandLabel("Linear to sRGB Filter"); - pass.SetStencilReference(entity.GetClipDepth()); auto options = OptionsFromPassAndEntity(pass, entity); options.primitive_type = PrimitiveType::kTriangleStrip; @@ -96,7 +95,6 @@ std::optional LinearToSrgbFilterContents::RenderFilter( Entity sub_entity; sub_entity.SetContents(std::move(contents)); - sub_entity.SetClipDepth(entity.GetClipDepth()); sub_entity.SetBlendMode(entity.GetBlendMode()); return sub_entity; } diff --git a/impeller/entity/contents/filters/local_matrix_filter_contents.cc b/impeller/entity/contents/filters/local_matrix_filter_contents.cc index d5b52ef615349..568346b9a3694 100644 --- a/impeller/entity/contents/filters/local_matrix_filter_contents.cc +++ b/impeller/entity/contents/filters/local_matrix_filter_contents.cc @@ -42,8 +42,7 @@ std::optional LocalMatrixFilterContents::RenderFilter( if (!snapshot.has_value()) { return std::nullopt; } - return Entity::FromSnapshot(snapshot.value(), entity.GetBlendMode(), - entity.GetClipDepth()); + return Entity::FromSnapshot(snapshot.value(), entity.GetBlendMode()); } } // namespace impeller diff --git a/impeller/entity/contents/filters/matrix_filter_contents.cc b/impeller/entity/contents/filters/matrix_filter_contents.cc index 7fe455c79d387..9681e8a6d6ad5 100644 --- a/impeller/entity/contents/filters/matrix_filter_contents.cc +++ b/impeller/entity/contents/filters/matrix_filter_contents.cc @@ -67,8 +67,7 @@ std::optional MatrixFilterContents::RenderFilter( if (!snapshot.has_value()) { return std::nullopt; } - return Entity::FromSnapshot(snapshot.value(), entity.GetBlendMode(), - entity.GetClipDepth()); + return Entity::FromSnapshot(snapshot.value(), entity.GetBlendMode()); } std::optional MatrixFilterContents::GetFilterSourceCoverage( diff --git a/impeller/entity/contents/filters/morphology_filter_contents.cc b/impeller/entity/contents/filters/morphology_filter_contents.cc index 72557c8d54115..dcade050e00b4 100644 --- a/impeller/entity/contents/filters/morphology_filter_contents.cc +++ b/impeller/entity/contents/filters/morphology_filter_contents.cc @@ -59,8 +59,7 @@ std::optional DirectionalMorphologyFilterContents::RenderFilter( } if (radius_.radius < kEhCloseEnough) { - return Entity::FromSnapshot(input_snapshot.value(), entity.GetBlendMode(), - entity.GetClipDepth()); + return Entity::FromSnapshot(input_snapshot.value(), entity.GetBlendMode()); } auto maybe_input_uvs = input_snapshot->GetCoverageUVs(coverage); @@ -162,7 +161,7 @@ std::optional DirectionalMorphologyFilterContents::RenderFilter( .transform = Matrix::MakeTranslation(coverage.GetOrigin()), .sampler_descriptor = sampler_desc, .opacity = input_snapshot->opacity}, - entity.GetBlendMode(), entity.GetClipDepth()); + entity.GetBlendMode()); } std::optional DirectionalMorphologyFilterContents::GetFilterCoverage( diff --git a/impeller/entity/contents/filters/srgb_to_linear_filter_contents.cc b/impeller/entity/contents/filters/srgb_to_linear_filter_contents.cc index 0351ee710d5b0..eca7cb051763d 100644 --- a/impeller/entity/contents/filters/srgb_to_linear_filter_contents.cc +++ b/impeller/entity/contents/filters/srgb_to_linear_filter_contents.cc @@ -45,7 +45,6 @@ std::optional SrgbToLinearFilterContents::RenderFilter( const ContentContext& renderer, const Entity& entity, RenderPass& pass) -> bool { pass.SetCommandLabel("sRGB to Linear Filter"); - pass.SetStencilReference(entity.GetClipDepth()); auto options = OptionsFromPassAndEntity(pass, entity); options.primitive_type = PrimitiveType::kTriangleStrip; @@ -96,7 +95,6 @@ std::optional SrgbToLinearFilterContents::RenderFilter( Entity sub_entity; sub_entity.SetContents(std::move(contents)); - sub_entity.SetClipDepth(entity.GetClipDepth()); sub_entity.SetBlendMode(entity.GetBlendMode()); return sub_entity; } diff --git a/impeller/entity/contents/filters/yuv_to_rgb_filter_contents.cc b/impeller/entity/contents/filters/yuv_to_rgb_filter_contents.cc index b81328c616b0c..62b79658f70e3 100644 --- a/impeller/entity/contents/filters/yuv_to_rgb_filter_contents.cc +++ b/impeller/entity/contents/filters/yuv_to_rgb_filter_contents.cc @@ -74,7 +74,6 @@ std::optional YUVToRGBFilterContents::RenderFilter( const ContentContext& renderer, const Entity& entity, RenderPass& pass) -> bool { pass.SetCommandLabel("YUV to RGB Filter"); - pass.SetStencilReference(entity.GetClipDepth()); auto options = OptionsFromPassAndEntity(pass, entity); options.primitive_type = PrimitiveType::kTriangleStrip; @@ -132,7 +131,6 @@ std::optional YUVToRGBFilterContents::RenderFilter( Entity sub_entity; sub_entity.SetContents(std::move(contents)); - sub_entity.SetClipDepth(entity.GetClipDepth()); sub_entity.SetBlendMode(entity.GetBlendMode()); return sub_entity; } diff --git a/impeller/entity/contents/framebuffer_blend_contents.cc b/impeller/entity/contents/framebuffer_blend_contents.cc index cee9b5a904e4c..8cba7107d307c 100644 --- a/impeller/entity/contents/framebuffer_blend_contents.cc +++ b/impeller/entity/contents/framebuffer_blend_contents.cc @@ -73,7 +73,6 @@ bool FramebufferBlendContents::Render(const ContentContext& renderer, pass.SetCommandLabel("Framebuffer Advanced Blend Filter"); pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer)); - pass.SetStencilReference(entity.GetClipDepth()); switch (blend_mode_) { case BlendMode::kScreen: diff --git a/impeller/entity/contents/solid_rrect_blur_contents.cc b/impeller/entity/contents/solid_rrect_blur_contents.cc index a38a462563d75..4d0c8cb0e33f6 100644 --- a/impeller/entity/contents/solid_rrect_blur_contents.cc +++ b/impeller/entity/contents/solid_rrect_blur_contents.cc @@ -114,7 +114,6 @@ bool SolidRRectBlurContents::Render(const ContentContext& renderer, pass.SetCommandLabel("RRect Shadow"); pass.SetPipeline(renderer.GetRRectBlurPipeline(opts)); - pass.SetStencilReference(entity.GetClipDepth()); pass.SetVertexBuffer( vtx_builder.CreateVertexBuffer(renderer.GetTransientsBuffer())); VS::BindFrameInfo(pass, diff --git a/impeller/entity/contents/text_contents.cc b/impeller/entity/contents/text_contents.cc index 9265f16d067d4..3bcb882e2c308 100644 --- a/impeller/entity/contents/text_contents.cc +++ b/impeller/entity/contents/text_contents.cc @@ -88,7 +88,6 @@ bool TextContents::Render(const ContentContext& renderer, } else { pass.SetPipeline(renderer.GetGlyphAtlasColorPipeline(opts)); } - pass.SetStencilReference(entity.GetClipDepth()); using VS = GlyphAtlasPipeline::VertexShader; using FS = GlyphAtlasPipeline::FragmentShader; diff --git a/impeller/entity/contents/texture_contents.cc b/impeller/entity/contents/texture_contents.cc index 035c09a1bd7ac..f2f10207bf4be 100644 --- a/impeller/entity/contents/texture_contents.cc +++ b/impeller/entity/contents/texture_contents.cc @@ -176,7 +176,6 @@ bool TextureContents::Render(const ContentContext& renderer, } pass.SetPipeline(pipeline); - pass.SetStencilReference(entity.GetClipDepth()); pass.SetVertexBuffer(vertex_builder.CreateVertexBuffer(host_buffer)); VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info)); if (is_external_texture) { diff --git a/impeller/entity/contents/vertices_contents.cc b/impeller/entity/contents/vertices_contents.cc index c94e306533e3b..2db730e4e815a 100644 --- a/impeller/entity/contents/vertices_contents.cc +++ b/impeller/entity/contents/vertices_contents.cc @@ -163,7 +163,6 @@ bool VerticesUVContents::Render(const ContentContext& renderer, auto opts = OptionsFromPassAndEntity(pass, entity); opts.primitive_type = geometry_result.type; pass.SetPipeline(renderer.GetTexturePipeline(opts)); - pass.SetStencilReference(entity.GetClipDepth()); pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer)); VS::FrameInfo frame_info; @@ -212,7 +211,6 @@ bool VerticesColorContents::Render(const ContentContext& renderer, auto opts = OptionsFromPassAndEntity(pass, entity); opts.primitive_type = geometry_result.type; pass.SetPipeline(renderer.GetGeometryColorPipeline(opts)); - pass.SetStencilReference(entity.GetClipDepth()); pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer)); VS::FrameInfo frame_info; @@ -294,7 +292,6 @@ bool VerticesSimpleBlendContents::Render(const ContentContext& renderer, BlendModeToString(blend_mode_))); #endif // IMPELLER_DEBUG pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer)); - pass.SetStencilReference(entity.GetClipDepth()); auto options = OptionsFromPassAndEntity(pass, entity); options.primitive_type = geometry_result.type; diff --git a/impeller/entity/entity.cc b/impeller/entity/entity.cc index 4385ffb8ddc5b..add98062557ef 100644 --- a/impeller/entity/entity.cc +++ b/impeller/entity/entity.cc @@ -19,9 +19,7 @@ namespace impeller { -Entity Entity::FromSnapshot(const Snapshot& snapshot, - BlendMode blend_mode, - uint32_t clip_depth) { +Entity Entity::FromSnapshot(const Snapshot& snapshot, BlendMode blend_mode) { auto texture_rect = Rect::MakeSize(snapshot.texture->GetSize()); auto contents = TextureContents::MakeRect(texture_rect); @@ -32,7 +30,6 @@ Entity Entity::FromSnapshot(const Snapshot& snapshot, Entity entity; entity.SetBlendMode(blend_mode); - entity.SetClipDepth(clip_depth); entity.SetTransform(snapshot.transform); entity.SetContents(contents); return entity; diff --git a/impeller/entity/entity.h b/impeller/entity/entity.h index d3c532333217b..27e748489c69b 100644 --- a/impeller/entity/entity.h +++ b/impeller/entity/entity.h @@ -65,8 +65,7 @@ class Entity { /// @brief Create an entity that can be used to render a given snapshot. static Entity FromSnapshot(const Snapshot& snapshot, - BlendMode blend_mode = BlendMode::kSourceOver, - uint32_t clip_depth = 0); + BlendMode blend_mode = BlendMode::kSourceOver); Entity(); diff --git a/impeller/entity/entity_pass.cc b/impeller/entity/entity_pass.cc index 33c4b10c19641..74c8c6b52e256 100644 --- a/impeller/entity/entity_pass.cc +++ b/impeller/entity/entity_pass.cc @@ -549,7 +549,7 @@ EntityPass::EntityResult EntityPass::GetEntityForElement( Point global_pass_position, uint32_t pass_depth, EntityPassClipStack& clip_coverage_stack, - size_t clip_depth_floor) const { + size_t clip_height_floor) const { //-------------------------------------------------------------------------- /// Setup entity element. /// @@ -591,7 +591,7 @@ EntityPass::EntityResult EntityPass::GetEntityForElement( Point(), // local_pass_position pass_depth, // pass_depth clip_coverage_stack, // clip_coverage_stack - clip_depth_, // clip_depth_floor + clip_depth_, // clip_height_floor nullptr, // backdrop_filter_contents pass_context.GetRenderPass(pass_depth) // collapsed_parent_pass )) { @@ -704,7 +704,7 @@ EntityPass::EntityResult EntityPass::GetEntityForElement( global_pass_position, // local_pass_position ++pass_depth, // pass_depth clip_coverage_stack, // clip_coverage_stack - subpass->clip_depth_, // clip_depth_floor + subpass->clip_depth_, // clip_height_floor subpass_backdrop_filter_contents // backdrop_filter_contents )) { // Validation error messages are triggered for all `OnRender()` failure @@ -770,7 +770,7 @@ static void SetClipScissor(std::optional clip_coverage, } bool EntityPass::RenderElement(Entity& element_entity, - size_t clip_depth_floor, + size_t clip_height_floor, InlinePassContext& pass_context, int32_t pass_depth, ContentContext& renderer, @@ -847,7 +847,7 @@ bool EntityPass::RenderElement(Entity& element_entity, EntityPassClipStack::ClipStateResult clip_state_result = clip_coverage_stack.ApplyClipState(clip_coverage, element_entity, - clip_depth_floor, + clip_height_floor, global_pass_position); if (clip_state_result.clip_did_change) { @@ -876,7 +876,7 @@ bool EntityPass::OnRender( Point local_pass_position, uint32_t pass_depth, EntityPassClipStack& clip_coverage_stack, - size_t clip_depth_floor, + size_t clip_height_floor, std::shared_ptr backdrop_filter_contents, const std::optional& collapsed_parent_pass) const { @@ -919,10 +919,10 @@ bool EntityPass::OnRender( backdrop_entity.SetContents(std::move(backdrop_filter_contents)); backdrop_entity.SetTransform( Matrix::MakeTranslation(Vector3(-local_pass_position))); - backdrop_entity.SetClipDepth(clip_depth_floor); + backdrop_entity.SetClipDepth(clip_height_floor); backdrop_entity.SetNewClipDepth(std::numeric_limits::max()); - RenderElement(backdrop_entity, clip_depth_floor, pass_context, pass_depth, + RenderElement(backdrop_entity, clip_height_floor, pass_context, pass_depth, renderer, clip_coverage_stack, global_pass_position); } @@ -950,7 +950,7 @@ bool EntityPass::OnRender( global_pass_position, // global_pass_position pass_depth, // pass_depth clip_coverage_stack, // clip_coverage_stack - clip_depth_floor); // clip_depth_floor + clip_height_floor); // clip_height_floor switch (result.status) { case EntityResult::kSuccess: @@ -1023,7 +1023,7 @@ bool EntityPass::OnRender( //-------------------------------------------------------------------------- /// Render the Element. /// - if (!RenderElement(result.entity, clip_depth_floor, pass_context, + if (!RenderElement(result.entity, clip_height_floor, pass_context, pass_depth, renderer, clip_coverage_stack, global_pass_position)) { // Specific validation logs are handled in `render_element()`. diff --git a/impeller/entity/entity_pass.h b/impeller/entity/entity_pass.h index fd9d99bf6b1b4..5fc017b873ee7 100644 --- a/impeller/entity/entity_pass.h +++ b/impeller/entity/entity_pass.h @@ -238,7 +238,7 @@ class EntityPass { }; bool RenderElement(Entity& element_entity, - size_t clip_depth_floor, + size_t clip_height_floor, InlinePassContext& pass_context, int32_t pass_depth, ContentContext& renderer, @@ -253,7 +253,7 @@ class EntityPass { Point global_pass_position, uint32_t pass_depth, EntityPassClipStack& clip_coverage_stack, - size_t clip_depth_floor) const; + size_t clip_height_floor) const; //---------------------------------------------------------------------------- /// @brief OnRender is the internal command recording routine for @@ -293,7 +293,7 @@ class EntityPass { /// Used to cull Elements that we /// know won't result in a visible /// change. - /// @param[in] clip_depth_floor The clip depth that a value of + /// @param[in] clip_height_floor The clip depth that a value of /// zero corresponds to in the given /// `pass_target` clip buffer. /// When new `pass_target`s are created @@ -320,7 +320,7 @@ class EntityPass { Point local_pass_position, uint32_t pass_depth, EntityPassClipStack& clip_coverage_stack, - size_t clip_depth_floor = 0, + size_t clip_height_floor = 0, std::shared_ptr backdrop_filter_contents = nullptr, const std::optional& collapsed_parent_pass = std::nullopt) const; diff --git a/impeller/entity/entity_pass_clip_stack.cc b/impeller/entity/entity_pass_clip_stack.cc index a817847947b45..94fe9b70137d6 100644 --- a/impeller/entity/entity_pass_clip_stack.cc +++ b/impeller/entity/entity_pass_clip_stack.cc @@ -15,7 +15,7 @@ EntityPassClipStack::EntityPassClipStack(const Rect& initial_coverage_rect) { { {ClipCoverageLayer{ .coverage = initial_coverage_rect, - .clip_depth = 0, + .clip_height = 0, }}, }, }); @@ -30,12 +30,12 @@ bool EntityPassClipStack::HasCoverage() const { } void EntityPassClipStack::PushSubpass(std::optional subpass_coverage, - size_t clip_depth) { + size_t clip_height) { subpass_state_.push_back(SubpassState{ .clip_coverage = { ClipCoverageLayer{.coverage = subpass_coverage, - .clip_depth = clip_depth}, + .clip_height = clip_height}, }, }); } @@ -52,7 +52,7 @@ EntityPassClipStack::GetClipCoverageLayers() const { EntityPassClipStack::ClipStateResult EntityPassClipStack::ApplyClipState( Contents::ClipCoverage global_clip_coverage, Entity& entity, - size_t clip_depth_floor, + size_t clip_height_floor, Point global_pass_position) { ClipStateResult result = {.should_render = false, .clip_did_change = false}; @@ -62,13 +62,24 @@ EntityPassClipStack::ClipStateResult EntityPassClipStack::ApplyClipState( break; case Contents::ClipCoverage::Type::kAppend: { auto op = CurrentClipCoverage(); + + // Compute the previous clip height. + size_t previous_clip_height = 0; + if (!subpass_state.clip_coverage.empty()) { + previous_clip_height = subpass_state.clip_coverage.back().clip_height; + } else { + // If there is no clip coverage, then the previous clip height is the + // clip height floor. + previous_clip_height = clip_height_floor; + } + subpass_state.clip_coverage.push_back( ClipCoverageLayer{.coverage = global_clip_coverage.coverage, - .clip_depth = entity.GetClipDepth() + 1}); + .clip_height = previous_clip_height + 1}); result.clip_did_change = true; - FML_DCHECK(subpass_state.clip_coverage.back().clip_depth == - subpass_state.clip_coverage.front().clip_depth + + FML_DCHECK(subpass_state.clip_coverage.back().clip_height == + subpass_state.clip_coverage.front().clip_height + subpass_state.clip_coverage.size() - 1); if (!op.has_value()) { @@ -78,14 +89,17 @@ EntityPassClipStack::ClipStateResult EntityPassClipStack::ApplyClipState( } } break; case Contents::ClipCoverage::Type::kRestore: { - if (subpass_state.clip_coverage.back().clip_depth <= - entity.GetClipDepth()) { + ClipRestoreContents* restore_contents = + reinterpret_cast(entity.GetContents().get()); + size_t restore_height = restore_contents->GetRestoreHeight(); + + if (subpass_state.clip_coverage.back().clip_height <= restore_height) { // Drop clip restores that will do nothing. return result; } - auto restoration_index = entity.GetClipDepth() - - subpass_state.clip_coverage.front().clip_depth; + auto restoration_index = + restore_height - subpass_state.clip_coverage.front().clip_height; FML_DCHECK(restoration_index < subpass_state.clip_coverage.size()); // We only need to restore the area that covers the coverage of the @@ -122,7 +136,6 @@ EntityPassClipStack::ClipStateResult EntityPassClipStack::ApplyClipState( } #endif - entity.SetClipDepth(entity.GetClipDepth() - clip_depth_floor); RecordEntity(entity, global_clip_coverage.type, subpass_state.clip_coverage.back().coverage); diff --git a/impeller/entity/entity_pass_clip_stack.h b/impeller/entity/entity_pass_clip_stack.h index d5181d86b9907..de1f1c9eee070 100644 --- a/impeller/entity/entity_pass_clip_stack.h +++ b/impeller/entity/entity_pass_clip_stack.h @@ -13,7 +13,7 @@ namespace impeller { struct ClipCoverageLayer { std::optional coverage; - size_t clip_depth; + size_t clip_height = 0; }; /// @brief A class that tracks all clips that have been recorded in the current @@ -44,7 +44,7 @@ class EntityPassClipStack { std::optional CurrentClipCoverage() const; - void PushSubpass(std::optional subpass_coverage, size_t clip_depth); + void PushSubpass(std::optional subpass_coverage, size_t clip_height); void PopSubpass(); @@ -54,7 +54,7 @@ class EntityPassClipStack { /// is a clip operation, then the clip state is updated accordingly. ClipStateResult ApplyClipState(Contents::ClipCoverage global_clip_coverage, Entity& entity, - size_t clip_depth_floor, + size_t clip_height_floor, Point global_pass_position); // Visible for testing. diff --git a/impeller/entity/entity_pass_unittests.cc b/impeller/entity/entity_pass_unittests.cc index 137cbd2e4ad22..b2897ed9d1c1f 100644 --- a/impeller/entity/entity_pass_unittests.cc +++ b/impeller/entity/entity_pass_unittests.cc @@ -2,8 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include + #include "flutter/testing/testing.h" #include "gtest/gtest.h" +#include "impeller/entity/contents/clip_contents.h" #include "impeller/entity/entity.h" #include "impeller/entity/entity_pass_clip_stack.h" @@ -69,7 +72,7 @@ TEST(EntityPassClipStackTest, AppendCoverageNoChange) { EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage, Rect::MakeSize(Size::MakeWH(100, 100))); - EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_depth, 0u); + EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_height, 0u); Entity entity; EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState( @@ -83,7 +86,7 @@ TEST(EntityPassClipStackTest, AppendCoverageNoChange) { EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage, Rect::MakeSize(Size::MakeWH(100, 100))); - EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_depth, 0u); + EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_height, 0u); } TEST(EntityPassClipStackTest, AppendAndRestoreClipCoverage) { @@ -107,11 +110,13 @@ TEST(EntityPassClipStackTest, AppendAndRestoreClipCoverage) { ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 2u); EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage, Rect::MakeLTRB(50, 50, 55, 55)); - EXPECT_EQ(recorder.GetClipCoverageLayers()[1].clip_depth, 1u); + EXPECT_EQ(recorder.GetClipCoverageLayers()[1].clip_height, 1u); EXPECT_EQ(recorder.GetReplayEntities().size(), 1u); // Restore the clip. - entity.SetClipDepth(0); + auto restore_clip = std::make_shared(); + restore_clip->SetRestoreHeight(0); + entity.SetContents(std::move(restore_clip)); recorder.ApplyClipState( Contents::ClipCoverage{ .type = Contents::ClipCoverage::Type::kRestore, @@ -122,7 +127,7 @@ TEST(EntityPassClipStackTest, AppendAndRestoreClipCoverage) { ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u); EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage, Rect::MakeSize(Size::MakeWH(100, 100))); - EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_depth, 0u); + EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_height, 0u); EXPECT_EQ(recorder.GetReplayEntities().size(), 0u); } @@ -134,7 +139,9 @@ TEST(EntityPassClipStackTest, UnbalancedRestore) { // Restore the clip. Entity entity; - entity.SetClipDepth(0); + auto restore_clip = std::make_shared(); + restore_clip->SetRestoreHeight(0); + entity.SetContents(std::move(restore_clip)); EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState( Contents::ClipCoverage{ .type = Contents::ClipCoverage::Type::kRestore, @@ -147,7 +154,7 @@ TEST(EntityPassClipStackTest, UnbalancedRestore) { ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u); EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage, Rect::MakeSize(Size::MakeWH(100, 100))); - EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_depth, 0u); + EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_height, 0u); EXPECT_EQ(recorder.GetReplayEntities().size(), 0u); } @@ -174,7 +181,7 @@ TEST(EntityPassClipStackTest, ClipAndRestoreWithSubpasses) { ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 2u); EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage, Rect::MakeLTRB(50, 50, 55, 55)); - EXPECT_EQ(recorder.GetClipCoverageLayers()[1].clip_depth, 1u); + EXPECT_EQ(recorder.GetClipCoverageLayers()[1].clip_height, 1u); EXPECT_EQ(recorder.GetReplayEntities().size(), 1u); // Begin a subpass.