[Impeller] set stencil attachment descriptor for runtime effect. (flutter/engine#42054)

This fixes the correctness issues observed in https://github.com/flutter/flutter/issues/126701 . The missing stencil descriptor meant that the clips were always ignored.

Have not yet investigated the reported debug performance issues.
This commit is contained in:
Jonah Williams
2023-05-15 16:04:05 -07:00
committed by GitHub
parent 27b261266a
commit 5cbbce3e7e
5 changed files with 59 additions and 1 deletions

View File

@@ -2263,5 +2263,39 @@ TEST_P(AiksTest, CanRenderBackdropBlur) {
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}
// Regression test for https://github.com/flutter/flutter/issues/126701 .
TEST_P(AiksTest, CanRenderClippedRuntimeEffects) {
if (GetParam() != PlaygroundBackend::kMetal) {
GTEST_SKIP_("This backend doesn't support runtime effects.");
}
auto runtime_stage =
OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
ASSERT_TRUE(runtime_stage->IsDirty());
struct FragUniforms {
Vector2 iResolution;
Scalar iTime;
} frag_uniforms = {.iResolution = Vector2(400, 400), .iTime = 100.0};
auto uniform_data = std::make_shared<std::vector<uint8_t>>();
uniform_data->resize(sizeof(FragUniforms));
memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
Paint paint;
paint.color_source = ColorSource::MakeRuntimeEffect(
runtime_stage, uniform_data, texture_inputs);
Canvas canvas;
canvas.Save();
canvas.ClipRRect(Rect{0, 0, 400, 400}, 10.0,
Entity::ClipOperation::kIntersect);
canvas.DrawRect(Rect{0, 0, 400, 400}, paint);
canvas.Restore();
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}
} // namespace testing
} // namespace impeller

View File

@@ -124,7 +124,10 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer,
desc.SetVertexDescriptor(std::move(vertex_descriptor));
desc.SetColorAttachmentDescriptor(
0u, {.format = color_attachment_format, .blending_enabled = true});
desc.SetStencilAttachmentDescriptors({});
StencilAttachmentDescriptor stencil0;
stencil0.stencil_compare = CompareFunction::kEqual;
desc.SetStencilAttachmentDescriptors(stencil0);
desc.SetStencilPixelFormat(stencil_attachment_format);
auto options = OptionsFromPassAndEntity(pass, entity);

View File

@@ -36,6 +36,9 @@ class GoldenPlaygroundTest
const char* fixture_name,
bool enable_mipmapping = false) const;
std::shared_ptr<RuntimeStage> OpenAssetAsRuntimeStage(
const char* asset_name) const;
std::shared_ptr<Context> GetContext() const;
Point GetContentScale() const;

View File

@@ -147,6 +147,19 @@ std::shared_ptr<Texture> GoldenPlaygroundTest::CreateTextureForFixture(
return result;
}
std::shared_ptr<RuntimeStage> GoldenPlaygroundTest::OpenAssetAsRuntimeStage(
const char* asset_name) const {
auto fixture = flutter::testing::OpenFixtureAsMapping(asset_name);
if (!fixture || fixture->GetSize() == 0) {
return nullptr;
}
auto stage = std::make_unique<RuntimeStage>(std::move(fixture));
if (!stage->IsValid()) {
return nullptr;
}
return stage;
}
std::shared_ptr<Context> GoldenPlaygroundTest::GetContext() const {
return pimpl_->screenshoter->GetContext().GetContext();
}

View File

@@ -33,6 +33,11 @@ std::shared_ptr<Texture> GoldenPlaygroundTest::CreateTextureForFixture(
return nullptr;
}
std::shared_ptr<RuntimeStage> GoldenPlaygroundTest::OpenAssetAsRuntimeStage(
const char* asset_name) const {
return nullptr;
}
std::shared_ptr<Context> GoldenPlaygroundTest::GetContext() const {
return nullptr;
}