diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index a689d303fc3f1..31aaf2b574e4a 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -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>(); + uniform_data->resize(sizeof(FragUniforms)); + memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms)); + + std::vector 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 diff --git a/impeller/entity/contents/runtime_effect_contents.cc b/impeller/entity/contents/runtime_effect_contents.cc index 20b0c1e36a60d..bd021af3a76d7 100644 --- a/impeller/entity/contents/runtime_effect_contents.cc +++ b/impeller/entity/contents/runtime_effect_contents.cc @@ -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); diff --git a/impeller/golden_tests/golden_playground_test.h b/impeller/golden_tests/golden_playground_test.h index 067d4052a316f..e220d5c4b618d 100644 --- a/impeller/golden_tests/golden_playground_test.h +++ b/impeller/golden_tests/golden_playground_test.h @@ -36,6 +36,9 @@ class GoldenPlaygroundTest const char* fixture_name, bool enable_mipmapping = false) const; + std::shared_ptr OpenAssetAsRuntimeStage( + const char* asset_name) const; + std::shared_ptr GetContext() const; Point GetContentScale() const; diff --git a/impeller/golden_tests/golden_playground_test_mac.cc b/impeller/golden_tests/golden_playground_test_mac.cc index 72ef1d0ef2f9b..55209e7836746 100644 --- a/impeller/golden_tests/golden_playground_test_mac.cc +++ b/impeller/golden_tests/golden_playground_test_mac.cc @@ -147,6 +147,19 @@ std::shared_ptr GoldenPlaygroundTest::CreateTextureForFixture( return result; } +std::shared_ptr 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(std::move(fixture)); + if (!stage->IsValid()) { + return nullptr; + } + return stage; +} + std::shared_ptr GoldenPlaygroundTest::GetContext() const { return pimpl_->screenshoter->GetContext().GetContext(); } diff --git a/impeller/golden_tests/golden_playground_test_stub.cc b/impeller/golden_tests/golden_playground_test_stub.cc index 392f759b7722d..054dc5553e624 100644 --- a/impeller/golden_tests/golden_playground_test_stub.cc +++ b/impeller/golden_tests/golden_playground_test_stub.cc @@ -33,6 +33,11 @@ std::shared_ptr GoldenPlaygroundTest::CreateTextureForFixture( return nullptr; } +std::shared_ptr GoldenPlaygroundTest::OpenAssetAsRuntimeStage( + const char* asset_name) const { + return nullptr; +} + std::shared_ptr GoldenPlaygroundTest::GetContext() const { return nullptr; }