From fc18d5bc59c8a7085bfae1f23472b843501ddda1 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 16 Jul 2024 16:17:17 -0700 Subject: [PATCH] [Impeller] Use depth transform in framebuffer blend entities. (flutter/engine#53951) \Without this the depth always ends up being a very large z depth of 0.5, which can cause clips to be ignored. --- .../display_list/aiks_dl_clip_unittests.cc | 25 +++++++++++++++++++ .../contents/filters/blend_filter_contents.cc | 6 +++-- .../testing/impeller_golden_tests_output.txt | 3 +++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/engine/src/flutter/impeller/display_list/aiks_dl_clip_unittests.cc b/engine/src/flutter/impeller/display_list/aiks_dl_clip_unittests.cc index 5576f343f99..543ee827487 100644 --- a/engine/src/flutter/impeller/display_list/aiks_dl_clip_unittests.cc +++ b/engine/src/flutter/impeller/display_list/aiks_dl_clip_unittests.cc @@ -117,5 +117,30 @@ TEST_P(AiksTest, ClipsUseCurrentTransform) { ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); } +/// If correct, this test should draw a green circle. If any red is visible, +/// there is a depth bug. +TEST_P(AiksTest, FramebufferBlendsRespectClips) { + DisplayListBuilder builder; + + // Clear the whole canvas with white. + DlPaint paint; + paint.setColor(DlColor::kWhite()); + builder.DrawPaint(paint); + + builder.ClipPath(SkPath::Circle(150, 150, 50), DlCanvas::ClipOp::kIntersect); + + // Draw a red rectangle that should not show through the circle clip. + paint.setColor(DlColor::kRed()); + paint.setBlendMode(DlBlendMode::kMultiply); + builder.DrawRect(SkRect::MakeXYWH(100, 100, 100, 100), paint); + + // Draw a green circle that shows through the clip. + paint.setColor(DlColor::kGreen()); + paint.setBlendMode(DlBlendMode::kSrcOver); + builder.DrawCircle(SkPoint::Make(150, 150), 50, paint); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + } // namespace testing } // namespace impeller diff --git a/engine/src/flutter/impeller/entity/contents/filters/blend_filter_contents.cc b/engine/src/flutter/impeller/entity/contents/filters/blend_filter_contents.cc index f7f3f2d94cd..2d5b61428d6 100644 --- a/engine/src/flutter/impeller/entity/contents/filters/blend_filter_contents.cc +++ b/engine/src/flutter/impeller/entity/contents/filters/blend_filter_contents.cc @@ -365,7 +365,8 @@ std::optional BlendFilterContents::CreateForegroundAdvancedBlend( FS::BindTextureSamplerDst(pass, dst_snapshot->texture, dst_sampler); frame_info.dst_y_coord_scale = dst_snapshot->texture->GetYCoordScale(); - frame_info.mvp = pass.GetOrthographicTransform() * dst_snapshot->transform; + frame_info.mvp = Entity::GetShaderTransform(entity.GetShaderClipDepth(), + pass, dst_snapshot->transform); blend_info.dst_input_alpha = absorb_opacity == ColorFilterContents::AbsorbOpacity::kYes @@ -454,7 +455,8 @@ std::optional BlendFilterContents::CreateForegroundPorterDuffBlend( FS::FragInfo frag_info; VS::FrameInfo frame_info; - frame_info.mvp = pass.GetOrthographicTransform() * dst_snapshot->transform; + frame_info.mvp = Entity::GetShaderTransform(entity.GetShaderClipDepth(), + pass, dst_snapshot->transform); auto dst_sampler_descriptor = dst_snapshot->sampler_descriptor; if (renderer.GetDeviceCapabilities().SupportsDecalSamplerAddressMode()) { diff --git a/engine/src/flutter/testing/impeller_golden_tests_output.txt b/engine/src/flutter/testing/impeller_golden_tests_output.txt index 82812e676a4..a7e803cc170 100644 --- a/engine/src/flutter/testing/impeller_golden_tests_output.txt +++ b/engine/src/flutter/testing/impeller_golden_tests_output.txt @@ -644,6 +644,9 @@ impeller_Play_AiksTest_ForegroundPipelineBlendAppliesTransformCorrectly_Vulkan.p impeller_Play_AiksTest_FramebufferAdvancedBlendCoverage_Metal.png impeller_Play_AiksTest_FramebufferAdvancedBlendCoverage_OpenGLES.png impeller_Play_AiksTest_FramebufferAdvancedBlendCoverage_Vulkan.png +impeller_Play_AiksTest_FramebufferBlendsRespectClips_Metal.png +impeller_Play_AiksTest_FramebufferBlendsRespectClips_OpenGLES.png +impeller_Play_AiksTest_FramebufferBlendsRespectClips_Vulkan.png impeller_Play_AiksTest_GaussianBlurAnimatedBackdrop_Metal.png impeller_Play_AiksTest_GaussianBlurAnimatedBackdrop_OpenGLES.png impeller_Play_AiksTest_GaussianBlurAnimatedBackdrop_Vulkan.png