Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 56aa10f

Browse files
committed
[Impeller] fixed nested save layer mipmap counts
1 parent 205ed68 commit 56aa10f

File tree

3 files changed

+50
-19
lines changed

3 files changed

+50
-19
lines changed

impeller/aiks/aiks_unittests.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3794,5 +3794,31 @@ TEST_P(AiksTest, GaussianBlurAllocatesCorrectMipCountRenderTarget) {
37943794
EXPECT_EQ(max_mip_count, 1lu);
37953795
}
37963796

3797+
TEST_P(AiksTest, GaussianBlurMipMapNestedLayer) {
3798+
Canvas canvas;
3799+
canvas.DrawPaint({.color = Color::Wheat()});
3800+
canvas.SaveLayer({.blend_mode = BlendMode::kMultiply});
3801+
canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
3802+
canvas.SaveLayer({}, std::nullopt,
3803+
ImageFilter::MakeBlur(Sigma(30), Sigma(30),
3804+
FilterContents::BlurStyle::kNormal,
3805+
Entity::TileMode::kClamp));
3806+
canvas.DrawCircle({200, 200}, 50, {.color = Color::Chartreuse()});
3807+
3808+
Picture picture = canvas.EndRecordingAsPicture();
3809+
std::shared_ptr<RenderTargetCache> cache =
3810+
std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
3811+
AiksContext aiks_context(GetContext(), nullptr, cache);
3812+
picture.ToImage(aiks_context, {100, 100});
3813+
3814+
size_t max_mip_count = 0;
3815+
for (auto it = cache->GetTextureDataBegin(); it != cache->GetTextureDataEnd();
3816+
++it) {
3817+
max_mip_count =
3818+
std::max(it->texture->GetTextureDescriptor().mip_count, max_mip_count);
3819+
}
3820+
EXPECT_EQ(max_mip_count, 1lu);
3821+
}
3822+
37973823
} // namespace testing
37983824
} // namespace impeller

impeller/entity/entity_pass.cc

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -325,23 +325,13 @@ bool EntityPass::Render(ContentContext& renderer,
325325
Rect::MakeSize(root_render_target.GetRenderTargetSize()),
326326
{.readonly = true});
327327

328-
int32_t required_mip_count = 1;
329-
IterateAllElements(
330-
[&required_mip_count, lazy_glyph_atlas = renderer.GetLazyGlyphAtlas()](
331-
const Element& element) {
332-
if (auto entity = std::get_if<Entity>(&element)) {
333-
if (const auto& contents = entity->GetContents()) {
334-
contents->PopulateGlyphAtlas(lazy_glyph_atlas,
335-
entity->DeriveTextScale());
336-
}
337-
}
338-
if (auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
339-
const EntityPass* entity_pass = subpass->get();
340-
required_mip_count =
341-
std::max(required_mip_count, entity_pass->GetRequiredMipCount());
342-
}
343-
return true;
344-
});
328+
IterateAllEntities([lazy_glyph_atlas =
329+
renderer.GetLazyGlyphAtlas()](const Entity& entity) {
330+
if (const auto& contents = entity.GetContents()) {
331+
contents->PopulateGlyphAtlas(lazy_glyph_atlas, entity.DeriveTextScale());
332+
}
333+
return true;
334+
});
345335

346336
ClipCoverageStack clip_coverage_stack = {ClipCoverageLayer{
347337
.coverage = Rect::MakeSize(root_render_target.GetRenderTargetSize()),
@@ -353,7 +343,8 @@ bool EntityPass::Render(ContentContext& renderer,
353343
// there's no need to set up a stencil attachment on the root render target.
354344
if (reads_from_onscreen_backdrop) {
355345
EntityPassTarget offscreen_target = CreateRenderTarget(
356-
renderer, root_render_target.GetRenderTargetSize(), required_mip_count,
346+
renderer, root_render_target.GetRenderTargetSize(),
347+
GetChildrenRequiredMipCount(),
357348
GetClearColorOrDefault(render_target.GetRenderTargetSize()));
358349

359350
if (!OnRender(renderer, // renderer
@@ -615,7 +606,7 @@ EntityPass::EntityResult EntityPass::GetEntityForElement(
615606
auto subpass_target = CreateRenderTarget(
616607
renderer, // renderer
617608
subpass_size, // size
618-
/*mip_count=*/1,
609+
subpass->GetChildrenRequiredMipCount(),
619610
subpass->GetClearColorOrDefault(subpass_size)); // clear_color
620611

621612
if (!subpass_target.IsValid()) {
@@ -1200,6 +1191,16 @@ void EntityPass::SetEnableOffscreenCheckerboard(bool enabled) {
12001191
enable_offscreen_debug_checkerboard_ = enabled;
12011192
}
12021193

1194+
int32_t EntityPass::GetChildrenRequiredMipCount() const {
1195+
int32_t result = 1;
1196+
for (auto& element : elements_) {
1197+
if (auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
1198+
result = std::max(result, subpass->get()->GetRequiredMipCount());
1199+
}
1200+
}
1201+
return result;
1202+
}
1203+
12031204
EntityPassClipRecorder::EntityPassClipRecorder() {}
12041205

12051206
void EntityPassClipRecorder::RecordEntity(const Entity& entity,

impeller/entity/entity_pass.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ class EntityPass {
157157
required_mip_count_ = mip_count;
158158
}
159159

160+
/// Returns the mip map count that should be required for the render target
161+
/// receiving this EntityPass.
162+
int32_t GetChildrenRequiredMipCount() const;
163+
160164
//----------------------------------------------------------------------------
161165
/// @brief Computes the coverage of a given subpass. This is used to
162166
/// determine the texture size of a given subpass before it's rendered

0 commit comments

Comments
 (0)