[Impeller] blur: removed ability to request out of bounds mip_counts (flutter/engine#50290)

b/323402168

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
gaaclarke
2024-02-02 12:44:54 -08:00
committed by GitHub
parent 35ff8e9b9e
commit 8a98a0be33
3 changed files with 68 additions and 2 deletions

View File

@@ -3968,5 +3968,61 @@ TEST_P(AiksTest, CorrectClipDepthAssignedToEntities) {
}
}
// This addresses a bug where tiny blurs could result in mip maps that beyond
// the limits for the textures used for blurring.
// See also: b/323402168
TEST_P(AiksTest, GaussianBlurSolidColorTinyMipMap) {
for (int32_t i = 1; i < 5; ++i) {
Canvas canvas;
Scalar fi = i;
canvas.DrawPath(
PathBuilder{}
.MoveTo({100, 100})
.LineTo({100.f + fi, 100.f + fi})
.TakePath(),
{.color = Color::Chartreuse(),
.image_filter = ImageFilter::MakeBlur(
Sigma(0.1), Sigma(0.1), FilterContents::BlurStyle::kNormal,
Entity::TileMode::kClamp)});
Picture picture = canvas.EndRecordingAsPicture();
std::shared_ptr<RenderTargetCache> cache =
std::make_shared<RenderTargetCache>(
GetContext()->GetResourceAllocator());
AiksContext aiks_context(GetContext(), nullptr, cache);
std::shared_ptr<Image> image = picture.ToImage(aiks_context, {1024, 768});
EXPECT_TRUE(image) << " length " << i;
}
}
// This addresses a bug where tiny blurs could result in mip maps that beyond
// the limits for the textures used for blurring.
// See also: b/323402168
TEST_P(AiksTest, GaussianBlurBackdropTinyMipMap) {
for (int32_t i = 0; i < 5; ++i) {
Canvas canvas;
ISize clip_size = ISize(i, i);
canvas.ClipRect(
Rect::MakeXYWH(400, 400, clip_size.width, clip_size.height));
canvas.DrawCircle(
{400, 400}, 200,
{
.color = Color::Green(),
.image_filter = ImageFilter::MakeBlur(
Sigma(0.1), Sigma(0.1), FilterContents::BlurStyle::kNormal,
Entity::TileMode::kDecal),
});
canvas.Restore();
Picture picture = canvas.EndRecordingAsPicture();
std::shared_ptr<RenderTargetCache> cache =
std::make_shared<RenderTargetCache>(
GetContext()->GetResourceAllocator());
AiksContext aiks_context(GetContext(), nullptr, cache);
std::shared_ptr<Image> image = picture.ToImage(aiks_context, {1024, 768});
EXPECT_TRUE(image) << " clip rect " << i;
}
}
} // namespace testing
} // namespace impeller

View File

@@ -55,6 +55,14 @@ std::shared_ptr<Texture> Allocator::CreateTexture(
return nullptr;
}
if (desc.mip_count > desc.size.MipCount()) {
VALIDATION_LOG << "Requested mip_count " << desc.mip_count
<< " exceeds maximum supported for size " << desc.size;
TextureDescriptor corrected_desc = desc;
corrected_desc.mip_count = desc.size.MipCount();
return OnCreateTexture(corrected_desc);
}
return OnCreateTexture(desc);
}

View File

@@ -80,8 +80,9 @@ std::optional<Snapshot> Contents::RenderToSnapshot(
}
}
ISize subpass_size = ISize::Ceil(coverage->GetSize());
fml::StatusOr<RenderTarget> render_target = renderer.MakeSubpass(
label, ISize::Ceil(coverage->GetSize()),
label, subpass_size,
[&contents = *this, &entity, &coverage](const ContentContext& renderer,
RenderPass& pass) -> bool {
Entity sub_entity;
@@ -91,7 +92,8 @@ std::optional<Snapshot> Contents::RenderToSnapshot(
entity.GetTransform());
return contents.Render(renderer, sub_entity, pass);
},
msaa_enabled, mip_count);
msaa_enabled,
std::min(mip_count, static_cast<int32_t>(subpass_size.MipCount())));
if (!render_target.ok()) {
return std::nullopt;