Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions impeller/aiks/aiks_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2264,6 +2264,30 @@ TEST_P(AiksTest, DrawPaintAbsorbsClears) {
ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
}

// This is important to enforce with texture reuse, since cached textures need
// to be cleared before reuse.
TEST_P(AiksTest,
ParentSaveLayerCreatesRenderPassWhenChildBackdropFilterIsPresent) {
Canvas canvas;
canvas.SaveLayer({}, std::nullopt, ImageFilter::MakeMatrix(Matrix(), {}));
canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
.blend_mode = BlendMode::kSourceOver});
canvas.Restore();

Picture picture = canvas.EndRecordingAsPicture();

std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
std::shared_ptr<Context> real_context = GetContext();
std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
AiksContext renderer(mock_context, nullptr);
std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});

ASSERT_EQ(spy->render_passes_.size(), 3llu);
std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
}

TEST_P(AiksTest, DrawRectAbsorbsClears) {
Canvas canvas;
canvas.DrawRect({0, 0, 300, 300},
Expand Down
8 changes: 8 additions & 0 deletions impeller/entity/entity_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,14 @@ EntityPass::EntityResult EntityPass::GetEntityForElement(
proc(FilterInput::Make(std::move(texture)),
subpass->xformation_.Basis(), Entity::RenderingMode::kSubpass);

// If the very first thing we render in this EntityPass is a subpass that
// happens to have a backdrop filter, than that backdrop filter will end
// may wind up sampling from the raw, uncleared texture that came straight
// out of the texture cache. By calling `pass_context.GetRenderPass` here,
// we force the texture to pass through at least one RenderPass with the
// correct clear configuration before any sampling occurs.
pass_context.GetRenderPass(pass_depth);

// The subpass will need to read from the current pass texture when
// rendering the backdrop, so if there's an active pass, end it prior to
// rendering the subpass.
Expand Down