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
26 changes: 26 additions & 0 deletions impeller/aiks/aiks_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3794,5 +3794,31 @@ TEST_P(AiksTest, GaussianBlurAllocatesCorrectMipCountRenderTarget) {
EXPECT_EQ(max_mip_count, 1lu);
}

TEST_P(AiksTest, GaussianBlurMipMapNestedLayer) {
Canvas canvas;
canvas.DrawPaint({.color = Color::Wheat()});
canvas.SaveLayer({.blend_mode = BlendMode::kMultiply});
canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
canvas.SaveLayer({}, std::nullopt,
ImageFilter::MakeBlur(Sigma(30), Sigma(30),
FilterContents::BlurStyle::kNormal,
Entity::TileMode::kClamp));
canvas.DrawCircle({200, 200}, 50, {.color = Color::Chartreuse()});

Picture picture = canvas.EndRecordingAsPicture();
std::shared_ptr<RenderTargetCache> cache =
std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
AiksContext aiks_context(GetContext(), nullptr, cache);
picture.ToImage(aiks_context, {100, 100});

size_t max_mip_count = 0;
for (auto it = cache->GetTextureDataBegin(); it != cache->GetTextureDataEnd();
++it) {
max_mip_count =
std::max(it->texture->GetTextureDescriptor().mip_count, max_mip_count);
}
EXPECT_EQ(max_mip_count, 1lu);
}

} // namespace testing
} // namespace impeller
39 changes: 20 additions & 19 deletions impeller/entity/entity_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -325,23 +325,13 @@ bool EntityPass::Render(ContentContext& renderer,
Rect::MakeSize(root_render_target.GetRenderTargetSize()),
{.readonly = true});

int32_t required_mip_count = 1;
IterateAllElements(
[&required_mip_count, lazy_glyph_atlas = renderer.GetLazyGlyphAtlas()](
const Element& element) {
if (auto entity = std::get_if<Entity>(&element)) {
if (const auto& contents = entity->GetContents()) {
contents->PopulateGlyphAtlas(lazy_glyph_atlas,
entity->DeriveTextScale());
}
}
if (auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
const EntityPass* entity_pass = subpass->get();
required_mip_count =
std::max(required_mip_count, entity_pass->GetRequiredMipCount());
}
return true;
});
IterateAllEntities([lazy_glyph_atlas =
renderer.GetLazyGlyphAtlas()](const Entity& entity) {
if (const auto& contents = entity.GetContents()) {
contents->PopulateGlyphAtlas(lazy_glyph_atlas, entity.DeriveTextScale());
}
return true;
});

ClipCoverageStack clip_coverage_stack = {ClipCoverageLayer{
.coverage = Rect::MakeSize(root_render_target.GetRenderTargetSize()),
Expand All @@ -353,7 +343,8 @@ bool EntityPass::Render(ContentContext& renderer,
// there's no need to set up a stencil attachment on the root render target.
if (reads_from_onscreen_backdrop) {
EntityPassTarget offscreen_target = CreateRenderTarget(
renderer, root_render_target.GetRenderTargetSize(), required_mip_count,
renderer, root_render_target.GetRenderTargetSize(),
GetBackdropFilterMipCount(),
GetClearColorOrDefault(render_target.GetRenderTargetSize()));

if (!OnRender(renderer, // renderer
Expand Down Expand Up @@ -615,7 +606,7 @@ EntityPass::EntityResult EntityPass::GetEntityForElement(
auto subpass_target = CreateRenderTarget(
renderer, // renderer
subpass_size, // size
/*mip_count=*/1,
subpass->GetBackdropFilterMipCount(),
subpass->GetClearColorOrDefault(subpass_size)); // clear_color

if (!subpass_target.IsValid()) {
Expand Down Expand Up @@ -1200,6 +1191,16 @@ void EntityPass::SetEnableOffscreenCheckerboard(bool enabled) {
enable_offscreen_debug_checkerboard_ = enabled;
}

int32_t EntityPass::GetBackdropFilterMipCount() const {
int32_t result = 1;
for (auto& element : elements_) {
if (auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
result = std::max(result, subpass->get()->GetRequiredMipCount());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're gonna keep GetRequiredMipCount around, we should just rename it to GetBackdropFilterMipCount since that's what it currently is.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}
}
return result;
}

EntityPassClipRecorder::EntityPassClipRecorder() {}

void EntityPassClipRecorder::RecordEntity(const Entity& entity,
Expand Down
4 changes: 4 additions & 0 deletions impeller/entity/entity_pass.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ class EntityPass {
required_mip_count_ = mip_count;
}

/// Returns the mip map count that should be required for the render target
/// receiving this EntityPass.
int32_t GetBackdropFilterMipCount() const;

//----------------------------------------------------------------------------
/// @brief Computes the coverage of a given subpass. This is used to
/// determine the texture size of a given subpass before it's rendered
Expand Down