diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index 96354f78d14c8..aef97c8855d18 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -3073,6 +3073,42 @@ TEST_P(AiksTest, MipmapGenerationWorksCorrectly) { ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } +TEST_P(AiksTest, DrawAtlasPlusWideGamut) { + if (GetParam() != PlaygroundBackend::kMetal) { + GTEST_SKIP_("This backend doesn't yet support wide gamut."); + } + + EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(), + PixelFormat::kR16G16B16A16Float); + + // Draws the image as four squares stiched together. + auto atlas = + std::make_shared(CreateTextureForFixture("bay_bridge.jpg")); + auto size = atlas->GetSize(); + // Divide image into four quadrants. + Scalar half_width = size.width / 2; + Scalar half_height = size.height / 2; + std::vector texture_coordinates = { + Rect::MakeLTRB(0, 0, half_width, half_height), + Rect::MakeLTRB(half_width, 0, size.width, half_height), + Rect::MakeLTRB(0, half_height, half_width, size.height), + Rect::MakeLTRB(half_width, half_height, size.width, size.height)}; + // Position quadrants adjacent to eachother. + std::vector transforms = { + Matrix::MakeTranslation({0, 0, 0}), + Matrix::MakeTranslation({half_width, 0, 0}), + Matrix::MakeTranslation({0, half_height, 0}), + Matrix::MakeTranslation({half_width, half_height, 0})}; + std::vector colors = {Color::Red(), Color::Green(), Color::Blue(), + Color::Yellow()}; + + Canvas canvas; + canvas.DrawAtlas(atlas, transforms, texture_coordinates, colors, + BlendMode::kPlus, {}, std::nullopt, {}); + + ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); +} + } // namespace testing } // namespace impeller diff --git a/impeller/entity/shaders/blending/porter_duff_blend.frag b/impeller/entity/shaders/blending/porter_duff_blend.frag index 2b6631f9d57f7..5f2629bb6f6ab 100644 --- a/impeller/entity/shaders/blending/porter_duff_blend.frag +++ b/impeller/entity/shaders/blending/porter_duff_blend.frag @@ -36,6 +36,12 @@ f16vec4 Sample(f16sampler2D texture_sampler, vec2 texture_coords) { return IPHalfSampleDecal(texture_sampler, texture_coords); } +float16_t ClampAlpha(float16_t alpha) { + float16_t min = 0.0hf; + float16_t max = 1.0hf; + return clamp(alpha, min, max); +} + void main() { f16vec4 dst = texture(texture_sampler_dst, v_texture_coords) * frag_info.input_alpha; @@ -45,4 +51,9 @@ void main() { dst * (frag_info.dst_coeff + src.a * frag_info.dst_coeff_src_alpha + src * frag_info.dst_coeff_src_color); frag_color *= frag_info.output_alpha; + // This currently needs a clamp so that floating point textures blend + // correctly in wide gamut. Remove if we switch to a fixed point extended + // range format. + // See https://github.com/flutter/flutter/issues/145933 . + frag_color.a = ClampAlpha(frag_color.a); } diff --git a/impeller/tools/malioc.json b/impeller/tools/malioc.json index ae4d808c54a69..028e2f9443f03 100644 --- a/impeller/tools/malioc.json +++ b/impeller/tools/malioc.json @@ -8434,8 +8434,8 @@ "varying" ], "longest_path_cycles": [ - 0.21875, - 0.21875, + 0.234375, + 0.234375, 0.0, 0.0, 0.0, @@ -8455,8 +8455,8 @@ "varying" ], "shortest_path_cycles": [ - 0.21875, - 0.21875, + 0.234375, + 0.234375, 0.0, 0.0, 0.0, @@ -8467,8 +8467,8 @@ "varying" ], "total_cycles": [ - 0.21875, - 0.21875, + 0.234375, + 0.234375, 0.0, 0.0, 0.0, diff --git a/testing/impeller_golden_tests_output.txt b/testing/impeller_golden_tests_output.txt index 47b290d6c968b..e6b25f7ae7151 100644 --- a/testing/impeller_golden_tests_output.txt +++ b/testing/impeller_golden_tests_output.txt @@ -436,6 +436,7 @@ impeller_Play_AiksTest_DrawAdvancedBlendPartlyOffscreen_Vulkan.png impeller_Play_AiksTest_DrawAtlasAdvancedAndTransform_Metal.png impeller_Play_AiksTest_DrawAtlasAdvancedAndTransform_OpenGLES.png impeller_Play_AiksTest_DrawAtlasAdvancedAndTransform_Vulkan.png +impeller_Play_AiksTest_DrawAtlasPlusWideGamut_Metal.png impeller_Play_AiksTest_DrawAtlasWithColorAdvancedAndTransform_Metal.png impeller_Play_AiksTest_DrawAtlasWithColorAdvancedAndTransform_OpenGLES.png impeller_Play_AiksTest_DrawAtlasWithColorAdvancedAndTransform_Vulkan.png