From 2e48a773d1f6b7d5f3547677d8478a25d0d9ec6a Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 25 Jan 2024 15:50:21 -0800 Subject: [PATCH 01/10] [Impeller] Fix alpha management in advanced blend paths. --- impeller/entity/shaders/blending/framebuffer_blend.frag | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/impeller/entity/shaders/blending/framebuffer_blend.frag b/impeller/entity/shaders/blending/framebuffer_blend.frag index 58cedbd56b4c0..73b96764b7fca 100644 --- a/impeller/entity/shaders/blending/framebuffer_blend.frag +++ b/impeller/entity/shaders/blending/framebuffer_blend.frag @@ -62,6 +62,11 @@ void main() { frag_info.src_input_alpha; f16vec3 blend_result = AdvancedBlend(dst.rgb, src.rgb, int(blend_type)); - f16vec4 blended = mix(src, f16vec4(blend_result, src.a), dst.a); - frag_color = vec4(mix(dst, blended, src.a)); + + // Mix the blended colors together, weighted by the destination alpha. This + // color becomes the new source color for the alpha composite. + f16vec3 blended = mix(src.rgb, blend_result, dst.a); + + // Source-over blend atop the destination color. + frag_color = f16vec4(blended, src.a) + dst * (1.0f - src.a); } From 60a7072a99d753c07f24cadac92d0742b6fe289f Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 25 Jan 2024 16:09:09 -0800 Subject: [PATCH 02/10] Apply to both cases --- .../compiler/shader_lib/impeller/blending.glsl | 9 +++++++++ .../entity/shaders/blending/advanced_blend.frag | 14 ++++++-------- .../entity/shaders/blending/framebuffer_blend.frag | 7 +------ 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/impeller/compiler/shader_lib/impeller/blending.glsl b/impeller/compiler/shader_lib/impeller/blending.glsl index dc2fd1382705e..f68743a24948c 100644 --- a/impeller/compiler/shader_lib/impeller/blending.glsl +++ b/impeller/compiler/shader_lib/impeller/blending.glsl @@ -9,6 +9,15 @@ #include #include +f16vec4 IPApplyBlendedColor(f16vec4 dst, f16vec4 src, f16vec3 blend_result) { + // Mix the blended colors together, weighted by the destination alpha. This + // color becomes the new source color for the alpha composite. + f16vec3 blended = mix(src.rgb, blend_result, dst.a); + + // Source-over blend atop the destination color. + return f16vec4(blended, src.a) + dst * (1.0f - src.a); +} + //------------------------------------------------------------------------------ /// HSV utilities. /// diff --git a/impeller/entity/shaders/blending/advanced_blend.frag b/impeller/entity/shaders/blending/advanced_blend.frag index b15c5db7fe06d..54cb9b6b2a44f 100644 --- a/impeller/entity/shaders/blending/advanced_blend.frag +++ b/impeller/entity/shaders/blending/advanced_blend.frag @@ -36,12 +36,10 @@ f16vec4 Sample(f16sampler2D texture_sampler, vec2 texture_coords) { } void main() { - f16vec4 dst_sample = Sample(texture_sampler_dst, // sampler - v_dst_texture_coords // texture coordinates - ) * - blend_info.dst_input_alpha; - - f16vec4 dst = dst_sample; + f16vec4 dst = Sample(texture_sampler_dst, // sampler + v_dst_texture_coords // texture coordinates + ) * + blend_info.dst_input_alpha; f16vec4 src = blend_info.color_factor > 0.0hf ? blend_info.color : Sample(texture_sampler_src, // sampler @@ -50,6 +48,6 @@ void main() { blend_info.src_input_alpha; f16vec3 blend_result = AdvancedBlend(dst.rgb, src.rgb, int(blend_type)); - f16vec4 blended = mix(src, f16vec4(blend_result, src.a), dst.a); - frag_color = mix(dst_sample, blended, src.a); + + frag_color = IPApplyBlendedColor(dst, src, blend_result); } diff --git a/impeller/entity/shaders/blending/framebuffer_blend.frag b/impeller/entity/shaders/blending/framebuffer_blend.frag index 73b96764b7fca..06d1da88b3a7a 100644 --- a/impeller/entity/shaders/blending/framebuffer_blend.frag +++ b/impeller/entity/shaders/blending/framebuffer_blend.frag @@ -63,10 +63,5 @@ void main() { f16vec3 blend_result = AdvancedBlend(dst.rgb, src.rgb, int(blend_type)); - // Mix the blended colors together, weighted by the destination alpha. This - // color becomes the new source color for the alpha composite. - f16vec3 blended = mix(src.rgb, blend_result, dst.a); - - // Source-over blend atop the destination color. - frag_color = f16vec4(blended, src.a) + dst * (1.0f - src.a); + frag_color = IPApplyBlendedColor(dst, src, blend_result); } From 8a7c6aa9f5bb741d346a9e2dffacca03604f09da Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 25 Jan 2024 17:12:05 -0800 Subject: [PATCH 03/10] Cleanup and fix CPU blends. --- .../shader_lib/impeller/blending.glsl | 10 ++++++--- impeller/geometry/color.cc | 22 +++++++++++++------ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/impeller/compiler/shader_lib/impeller/blending.glsl b/impeller/compiler/shader_lib/impeller/blending.glsl index f68743a24948c..5418b46fd8171 100644 --- a/impeller/compiler/shader_lib/impeller/blending.glsl +++ b/impeller/compiler/shader_lib/impeller/blending.glsl @@ -9,13 +9,17 @@ #include #include +/// Composite a blended color onto the destination. +/// +/// All three parameters are premultiplied, including `blend_result`, which +/// is assumed to already be premultiplied with `src.a`. f16vec4 IPApplyBlendedColor(f16vec4 dst, f16vec4 src, f16vec3 blend_result) { - // Mix the blended colors together, weighted by the destination alpha. This - // color becomes the new source color for the alpha composite. + // The destination alpha determines how blended the result looks. This + // color becomes the new source color for the alpha composite step. f16vec3 blended = mix(src.rgb, blend_result, dst.a); // Source-over blend atop the destination color. - return f16vec4(blended, src.a) + dst * (1.0f - src.a); + return f16vec4(blended, src.a) + dst * (1.0hf - src.a); } //------------------------------------------------------------------------------ diff --git a/impeller/geometry/color.cc b/impeller/geometry/color.cc index 2efe123c906f4..75ab5666ce320 100644 --- a/impeller/geometry/color.cc +++ b/impeller/geometry/color.cc @@ -193,15 +193,23 @@ static constexpr inline Color FromRGB(Vector3 color, Scalar alpha) { return {color.x, color.y, color.z, alpha}; } +/// This routine is the same as `IPApplyBlendedColor` in the Impeller shader +/// library, except all inputs are unpremultiplied. static constexpr inline Color DoColorBlend( - Color d, - Color s, + Color dst, + Color src, const std::function& blend_rgb_func) { - d = d.Premultiply(); - s = s.Premultiply(); - const Vector3 rgb = blend_rgb_func(ToRGB(d), ToRGB(s)); - const Color blended = Color::Lerp(s, FromRGB(rgb, d.alpha), d.alpha); - return Color::Lerp(d, blended, s.alpha).Unpremultiply(); + dst = dst.Premultiply(); + src = src.Premultiply(); + + // The destination alpha determines how blended the result looks. This + // color becomes the new source color for the alpha composite step. + const Vector3 blend_result = blend_rgb_func(ToRGB(dst), ToRGB(src)); + + // Source-over blend atop the destination color. + const Vector3 blended = ToRGB(src).Lerp(blend_result, dst.alpha); + return (FromRGB(blended, src.alpha) + dst * (1.0f - src.alpha)) + .Unpremultiply(); } static constexpr inline Color DoColorBlendComponents( From 7da9005ed040edda27c2eb4b945469d5800020c9 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 25 Jan 2024 21:07:32 -0800 Subject: [PATCH 04/10] tests --- impeller/aiks/aiks_unittests.cc | 2 +- impeller/geometry/geometry_unittests.cc | 152 ++++++++++++++++++++++++ 2 files changed, 153 insertions(+), 1 deletion(-) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index 9e36f2e3ed9a8..9c3a9be8202c6 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -3176,7 +3176,7 @@ TEST_P(AiksTest, SolidColorApplyColorFilter) { }); ASSERT_TRUE(result); ASSERT_COLOR_NEAR(contents.GetColor(), - Color(0.433247, 0.879523, 0.825324, 0.75)); + Color(0.435986, 0.899204, 0.818385, 0.9375)); } TEST_P(AiksTest, DrawScaledTextWithPerspectiveNoSaveLayer) { diff --git a/impeller/geometry/geometry_unittests.cc b/impeller/geometry/geometry_unittests.cc index 6b7f6951c8502..2d696ed46e1d1 100644 --- a/impeller/geometry/geometry_unittests.cc +++ b/impeller/geometry/geometry_unittests.cc @@ -1431,6 +1431,158 @@ TEST(GeometryTest, ColorSRGBToLinear) { } } +struct ColorBlendTestData { + static constexpr Color kDestinationColor = + Color::CornflowerBlue().WithAlpha(0.75); + static constexpr Color kSourceColors[] = {Color::White().WithAlpha(0.75), + Color::LimeGreen().WithAlpha(0.75), + Color::Black().WithAlpha(0.75)}; + + // THIS RESULT TABLE IS GENERATED! + // + // Uncomment the `GenerateColorBlendResults` test below to print a new table + // after making changes to `Color::Blend`. + static constexpr Color kExpectedResults + [sizeof(kSourceColors)] + [static_cast>(BlendMode::kLast) + 1] = { + { + {0, 0, 0, 0}, // Clear + {1, 1, 1, 0.75}, // Source + {0.392157, 0.584314, 0.929412, 0.75}, // Destination + {0.878431, 0.916863, 0.985882, 0.9375}, // SourceOver + {0.513726, 0.667451, 0.943529, 0.9375}, // DestinationOver + {1, 1, 1, 0.5625}, // SourceIn + {0.392157, 0.584314, 0.929412, 0.5625}, // DestinationIn + {1, 1, 1, 0.1875}, // SourceOut + {0.392157, 0.584314, 0.929412, 0.1875}, // DestinationOut + {0.848039, 0.896078, 0.982353, 0.75}, // SourceATop + {0.544118, 0.688235, 0.947059, 0.75}, // DestinationATop + {0.696078, 0.792157, 0.964706, 0.375}, // Xor + {1, 1, 1, 1}, // Plus + {0.392157, 0.584314, 0.929412, 0.5625}, // Modulate + {0.937255, 1.00451, 1.12529, 0.9375}, // Screen + {0.631373, 0.842745, 1.06471, 0.9375}, // Overlay + {0.513726, 0.667451, 0.943529, 0.9375}, // Darken + {0.878431, 0.916863, 0.985882, 0.9375}, // Lighten + {1.03554, 1.08358, 1.16985, 0.75}, // ColorDodge + {0.329657, 0.521814, 0.866912, 0.75}, // ColorBurn + {0.796078, 0.892157, 1.06471, 0.9375}, // HardLight + {0.613009, 0.756954, 0.998666, 0.9375}, // SoftLight + {0.643137, 0.566275, 0.428235, 0.9375}, // Difference + {0.760784, 0.741569, 0.707059, 0.9375}, // Exclusion + {0.454902, 0.579804, 0.804118, 0.9375}, // Multiply + {0.617208, 0.655639, 0.724659, 0.9375}, // Hue + {0.617208, 0.655639, 0.724659, 0.9375}, // Saturation + {0.617208, 0.655639, 0.724659, 0.9375}, // Color + {0.784215, 0.927617, 1.18515, 0.9375}, // Luminosity + }, + { + {0, 0, 0, 0}, // Clear + {0.196078, 0.803922, 0.196078, 0.75}, // Source + {0.392157, 0.584314, 0.929412, 0.75}, // Destination + {0.235294, 0.76, 0.342745, 0.9375}, // SourceOver + {0.352941, 0.628235, 0.782745, 0.9375}, // DestinationOver + {0.196078, 0.803922, 0.196078, 0.5625}, // SourceIn + {0.392157, 0.584314, 0.929412, 0.5625}, // DestinationIn + {0.196078, 0.803922, 0.196078, 0.1875}, // SourceOut + {0.392157, 0.584314, 0.929412, 0.1875}, // DestinationOut + {0.245098, 0.74902, 0.379412, 0.75}, // SourceATop + {0.343137, 0.639216, 0.746078, 0.75}, // DestinationATop + {0.294118, 0.694118, 0.562745, 0.375}, // Xor + {0.441176, 1, 0.844118, 1}, // Plus + {0.0768935, 0.469742, 0.182238, 0.5625}, // Modulate + {0.435986, 0.899204, 0.818385, 0.9375}, // Screen + {0.186851, 0.700415, 0.611672, 0.9375}, // Overlay + {0.235294, 0.628235, 0.342745, 0.9375}, // Darken + {0.352941, 0.76, 0.782745, 0.9375}, // Lighten + {0.393425, 1.04681, 0.882049, 0.75}, // ColorDodge + {0.134804, 0.348033, 0.269118, 0.75}, // ColorBurn + {0.186851, 0.720761, 0.389112, 0.9375}, // HardLight + {0.235701, 0.66509, 0.663497, 0.9375}, // SoftLight + {0.235294, 0.409412, 0.665098, 0.9375}, // Difference + {0.401384, 0.68782, 0.736378, 0.9375}, // Exclusion + {0.152249, 0.489031, 0.307105, 0.9375}, // Multiply + {0.266235, 0.748588, 0.373686, 0.9375}, // Hue + {0.339345, 0.629787, 0.811502, 0.9375}, // Saturation + {0.241247, 0.765953, 0.348698, 0.9375}, // Color + {0.346988, 0.622282, 0.776792, 0.9375}, // Luminosity + }, + { + {0, 0, 0, 0}, // Clear + {0, 0, 0, 0.75}, // Source + {0.392157, 0.584314, 0.929412, 0.75}, // Destination + {0.0784314, 0.116863, 0.185882, 0.9375}, // SourceOver + {0.313726, 0.467451, 0.743529, 0.9375}, // DestinationOver + {0, 0, 0, 0.5625}, // SourceIn + {0.392157, 0.584314, 0.929412, 0.5625}, // DestinationIn + {0, 0, 0, 0.1875}, // SourceOut + {0.392157, 0.584314, 0.929412, 0.1875}, // DestinationOut + {0.0980392, 0.146078, 0.232353, 0.75}, // SourceATop + {0.294118, 0.438235, 0.697059, 0.75}, // DestinationATop + {0.196078, 0.292157, 0.464706, 0.375}, // Xor + {0.294118, 0.438235, 0.697059, 1}, // Plus + {0, 0, 0, 0.5625}, // Modulate + {0.313726, 0.467451, 0.743529, 0.9375}, // Screen + {0.0784314, 0.116863, 0.501176, 0.9375}, // Overlay + {0.0784314, 0.116863, 0.185882, 0.9375}, // Darken + {0.313726, 0.467451, 0.743529, 0.9375}, // Lighten + {0.318627, 0.474755, 0.755147, 0.75}, // ColorDodge + {0.0980392, 0.146078, 0.232353, 0.75}, // ColorBurn + {0.0784314, 0.116863, 0.185882, 0.9375}, // HardLight + {0.147636, 0.270503, 0.574595, 0.9375}, // SoftLight + {0.313726, 0.467451, 0.743529, 0.9375}, // Difference + {0.313726, 0.467451, 0.743529, 0.9375}, // Exclusion + {0.0784314, 0.116863, 0.185882, 0.9375}, // Multiply + {0.417208, 0.455639, 0.524659, 0.9375}, // Hue + {0.417208, 0.455639, 0.524659, 0.9375}, // Saturation + {0.417208, 0.455639, 0.524659, 0.9375}, // Color + {0.0784314, 0.116863, 0.185882, 0.9375}, // Luminosity + }, + }; +}; + +/// To print a new ColorBlendTestData::kExpectedResults table, uncomment this +/// test and run with: +/// --gtest_filter="GeometryTest.GenerateColorBlendResults" +/* +TEST(GeometryTest, GenerateColorBlendResults) { + auto& o = std::cout; + using BlendT = std::underlying_type_t; + o << "{"; + for (const auto& source : ColorBlendTestData::kSourceColors) { + o << "{"; + for (BlendT blend_i = 0; + blend_i < static_cast(BlendMode::kLast) + 1; blend_i++) { + auto blend = static_cast(blend_i); + Color c = ColorBlendTestData::kDestinationColor.Blend(source, blend); + o << "{" << c.red << "," << c.green << "," << c.blue << "," << c.alpha + << "}, // " << BlendModeToString(blend) << std::endl; + } + o << "},"; + } + o << "};" << std::endl; +} +*/ + +#define _BLEND_MODE_RESULT_CHECK(blend_mode) \ + blend_i = static_cast(BlendMode::k##blend_mode); \ + expected = ColorBlendTestData::kExpectedResults[source_i][blend_i]; \ + EXPECT_COLOR_NEAR(dst.Blend(src, BlendMode::k##blend_mode), expected); + +TEST(GeometryTest, ColorBlendReturnsExpectedResults) { + using BlendT = std::underlying_type_t; + Color dst = ColorBlendTestData::kDestinationColor; + for (size_t source_i = 0; + source_i < sizeof(ColorBlendTestData::kSourceColors) / sizeof(Color); + source_i++) { + Color src = ColorBlendTestData::kSourceColors[source_i]; + + size_t blend_i; + Color expected; + IMPELLER_FOR_EACH_BLEND_MODE(_BLEND_MODE_RESULT_CHECK) + } +} + #define _BLEND_MODE_NAME_CHECK(blend_mode) \ case BlendMode::k##blend_mode: \ ASSERT_STREQ(result, #blend_mode); \ From e5bf54e462d55897846e872b88b26fda24d1ae02 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 25 Jan 2024 23:02:25 -0800 Subject: [PATCH 05/10] malioc --- impeller/tools/malioc.json | 40 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/impeller/tools/malioc.json b/impeller/tools/malioc.json index 377fe50b82df9..4f7b6e72ffa59 100644 --- a/impeller/tools/malioc.json +++ b/impeller/tools/malioc.json @@ -20,8 +20,8 @@ "texture" ], "longest_path_cycles": [ - 0.4375, - 0.4375, + 0.390625, + 0.390625, 0.015625, 0.0, 0.0, @@ -42,8 +42,8 @@ "arith_fma" ], "shortest_path_cycles": [ - 0.375, - 0.375, + 0.328125, + 0.328125, 0.09375, 0.0, 0.0, @@ -55,8 +55,8 @@ "texture" ], "total_cycles": [ - 0.4375, - 0.4375, + 0.390625, + 0.390625, 0.09375, 0.0, 0.0, @@ -67,7 +67,7 @@ "stack_spill_bytes": 0, "thread_occupancy": 100, "uniform_registers_used": 10, - "work_registers_used": 16 + "work_registers_used": 18 } } } @@ -1431,9 +1431,9 @@ "texture" ], "longest_path_cycles": [ - 0.4375, - 0.4375, - 0.0625, + 0.390625, + 0.390625, + 0.046875, 0.0, 0.0, 0.5, @@ -1453,9 +1453,9 @@ "arith_fma" ], "shortest_path_cycles": [ - 0.375, - 0.375, - 0.109375, + 0.328125, + 0.328125, + 0.09375, 0.0, 0.0, 0.25, @@ -1466,9 +1466,9 @@ "texture" ], "total_cycles": [ - 0.4375, - 0.4375, - 0.140625, + 0.390625, + 0.390625, + 0.125, 0.0, 0.0, 0.5, @@ -1495,7 +1495,7 @@ "arithmetic" ], "longest_path_cycles": [ - 2.9700000286102295, + 2.640000104904175, 2.0, 2.0 ], @@ -1508,7 +1508,7 @@ "arithmetic" ], "shortest_path_cycles": [ - 2.640000104904175, + 2.309999942779541, 1.0, 1.0 ], @@ -1516,14 +1516,14 @@ "arithmetic" ], "total_cycles": [ - 3.3333332538604736, + 3.0, 2.0, 2.0 ] }, "thread_occupancy": 100, "uniform_registers_used": 2, - "work_registers_used": 4 + "work_registers_used": 3 } } } From 7b3825672202cc85d4c63cd6297cfa52dff7b89c Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Fri, 26 Jan 2024 17:38:01 -0800 Subject: [PATCH 06/10] Fixes --- impeller/aiks/aiks_unittests.cc | 2 +- .../shader_lib/impeller/blending.glsl | 12 ++- impeller/geometry/color.cc | 50 +++++++----- impeller/geometry/geometry_unittests.cc | 80 +++++++++---------- 4 files changed, 78 insertions(+), 66 deletions(-) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index 9c3a9be8202c6..0b8fececa29c9 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -3176,7 +3176,7 @@ TEST_P(AiksTest, SolidColorApplyColorFilter) { }); ASSERT_TRUE(result); ASSERT_COLOR_NEAR(contents.GetColor(), - Color(0.435986, 0.899204, 0.818385, 0.9375)); + Color(0.385813, 0.864403, 0.699475, 0.9375)); } TEST_P(AiksTest, DrawScaledTextWithPerspectiveNoSaveLayer) { diff --git a/impeller/compiler/shader_lib/impeller/blending.glsl b/impeller/compiler/shader_lib/impeller/blending.glsl index 5418b46fd8171..75ac09385828f 100644 --- a/impeller/compiler/shader_lib/impeller/blending.glsl +++ b/impeller/compiler/shader_lib/impeller/blending.glsl @@ -13,13 +13,17 @@ /// /// All three parameters are premultiplied, including `blend_result`, which /// is assumed to already be premultiplied with `src.a`. +/// +/// This routine is identical to `ApplyBlendedColor` in +/// `impeller/geometry/color.cc`. f16vec4 IPApplyBlendedColor(f16vec4 dst, f16vec4 src, f16vec3 blend_result) { - // The destination alpha determines how blended the result looks. This - // color becomes the new source color for the alpha composite step. - f16vec3 blended = mix(src.rgb, blend_result, dst.a); + // The source and destination alpha modulates the amount that the colors + // should get blended. This color becomes the new source color for the alpha + // composite step. + f16vec3 blended_src = mix(src.rgb, blend_result, dst.a * src.a); // Source-over blend atop the destination color. - return f16vec4(blended, src.a) + dst * (1.0hf - src.a); + return f16vec4(blended_src, src.a) + dst * (1.0hf - src.a); } //------------------------------------------------------------------------------ diff --git a/impeller/geometry/color.cc b/impeller/geometry/color.cc index 75ab5666ce320..15763bfa8e9fb 100644 --- a/impeller/geometry/color.cc +++ b/impeller/geometry/color.cc @@ -193,38 +193,46 @@ static constexpr inline Color FromRGB(Vector3 color, Scalar alpha) { return {color.x, color.y, color.z, alpha}; } -/// This routine is the same as `IPApplyBlendedColor` in the Impeller shader -/// library, except all inputs are unpremultiplied. +/// Composite a blended color onto the destination. +/// +/// All three parameters are premultiplied, including `blend_result`, which +/// is assumed to already be premultiplied with `src.a`. +/// +/// This routine is identical to `IPApplyBlendedColor` in the Impeller shader +/// library. +static constexpr inline Color ApplyBlendedColor(Color dst, + Color src, + Vector3 blend_result) { + // The source and destination alpha modulates the amount that the colors + // should get blended. This color becomes the new source color for the alpha + // composite step. + const Vector3 blended_src = + ToRGB(src).Lerp(blend_result, dst.alpha * src.alpha); + + // Source-over blend atop the destination color. + return FromRGB(blended_src, src.alpha) + dst * (1.0f - src.alpha); +} + static constexpr inline Color DoColorBlend( Color dst, Color src, const std::function& blend_rgb_func) { dst = dst.Premultiply(); src = src.Premultiply(); - - // The destination alpha determines how blended the result looks. This - // color becomes the new source color for the alpha composite step. const Vector3 blend_result = blend_rgb_func(ToRGB(dst), ToRGB(src)); - - // Source-over blend atop the destination color. - const Vector3 blended = ToRGB(src).Lerp(blend_result, dst.alpha); - return (FromRGB(blended, src.alpha) + dst * (1.0f - src.alpha)) - .Unpremultiply(); + return ApplyBlendedColor(dst, src, blend_result).Unpremultiply(); } static constexpr inline Color DoColorBlendComponents( - Color d, - Color s, + Color dst, + Color src, const std::function& blend_func) { - d = d.Premultiply(); - s = s.Premultiply(); - const Color blended = Color::Lerp(s, - Color(blend_func(d.red, s.red), // - blend_func(d.green, s.green), // - blend_func(d.blue, s.blue), // - d.alpha), - d.alpha); - return Color::Lerp(d, blended, s.alpha).Unpremultiply(); + dst = dst.Premultiply(); + src = src.Premultiply(); + Vector3 blend_result = Vector3(blend_func(dst.red, src.red), // + blend_func(dst.green, src.green), // + blend_func(dst.blue, src.blue)); // + return ApplyBlendedColor(dst, src, blend_result).Unpremultiply(); } Color Color::Blend(Color src, BlendMode blend_mode) const { diff --git a/impeller/geometry/geometry_unittests.cc b/impeller/geometry/geometry_unittests.cc index 2d696ed46e1d1..3e8679bf38cad 100644 --- a/impeller/geometry/geometry_unittests.cc +++ b/impeller/geometry/geometry_unittests.cc @@ -1460,21 +1460,21 @@ struct ColorBlendTestData { {0.696078, 0.792157, 0.964706, 0.375}, // Xor {1, 1, 1, 1}, // Plus {0.392157, 0.584314, 0.929412, 0.5625}, // Modulate - {0.937255, 1.00451, 1.12529, 0.9375}, // Screen - {0.631373, 0.842745, 1.06471, 0.9375}, // Overlay - {0.513726, 0.667451, 0.943529, 0.9375}, // Darken + {0.922549, 0.982598, 1.09044, 0.9375}, // Screen + {0.693137, 0.861275, 1.045, 0.9375}, // Overlay + {0.604902, 0.729804, 0.954118, 0.9375}, // Darken {0.878431, 0.916863, 0.985882, 0.9375}, // Lighten - {1.03554, 1.08358, 1.16985, 0.75}, // ColorDodge - {0.329657, 0.521814, 0.866912, 0.75}, // ColorBurn - {0.796078, 0.892157, 1.06471, 0.9375}, // HardLight - {0.613009, 0.756954, 0.998666, 0.9375}, // SoftLight - {0.643137, 0.566275, 0.428235, 0.9375}, // Difference - {0.760784, 0.741569, 0.707059, 0.9375}, // Exclusion - {0.454902, 0.579804, 0.804118, 0.9375}, // Multiply - {0.617208, 0.655639, 0.724659, 0.9375}, // Hue - {0.617208, 0.655639, 0.724659, 0.9375}, // Saturation - {0.617208, 0.655639, 0.724659, 0.9375}, // Color - {0.784215, 0.927617, 1.18515, 0.9375}, // Luminosity + {1.02843, 1.06686, 1.13588, 0.9375}, // ColorDodge + {0.463726, 0.617451, 0.893529, 0.9375}, // ColorBurn + {0.816667, 0.898333, 1.045, 0.9375}, // HardLight + {0.679365, 0.796931, 0.99547, 0.9375}, // SoftLight + {0.701961, 0.653922, 0.567647, 0.9375}, // Difference + {0.790196, 0.785392, 0.776765, 0.9375}, // Exclusion + {0.560784, 0.664069, 0.849559, 0.9375}, // Multiply + {0.682514, 0.720945, 0.789965, 0.9375}, // Hue + {0.682514, 0.720945, 0.789965, 0.9375}, // Saturation + {0.682514, 0.720945, 0.789965, 0.9375}, // Color + {0.807769, 0.924928, 1.13534, 0.9375}, // Luminosity }, { {0, 0, 0, 0}, // Clear @@ -1491,21 +1491,21 @@ struct ColorBlendTestData { {0.294118, 0.694118, 0.562745, 0.375}, // Xor {0.441176, 1, 0.844118, 1}, // Plus {0.0768935, 0.469742, 0.182238, 0.5625}, // Modulate - {0.435986, 0.899204, 0.818385, 0.9375}, // Screen - {0.186851, 0.700415, 0.611672, 0.9375}, // Overlay - {0.235294, 0.628235, 0.342745, 0.9375}, // Darken - {0.352941, 0.76, 0.782745, 0.9375}, // Lighten - {0.393425, 1.04681, 0.882049, 0.75}, // ColorDodge - {0.134804, 0.348033, 0.269118, 0.75}, // ColorBurn - {0.186851, 0.720761, 0.389112, 0.9375}, // HardLight - {0.235701, 0.66509, 0.663497, 0.9375}, // SoftLight - {0.235294, 0.409412, 0.665098, 0.9375}, // Difference - {0.401384, 0.68782, 0.736378, 0.9375}, // Exclusion - {0.152249, 0.489031, 0.307105, 0.9375}, // Multiply - {0.266235, 0.748588, 0.373686, 0.9375}, // Hue - {0.339345, 0.629787, 0.811502, 0.9375}, // Saturation - {0.241247, 0.765953, 0.348698, 0.9375}, // Color - {0.346988, 0.622282, 0.776792, 0.9375}, // Luminosity + {0.385813, 0.864403, 0.699475, 0.9375}, // Screen + {0.198962, 0.715311, 0.544441, 0.9375}, // Overlay + {0.235294, 0.661177, 0.342745, 0.9375}, // Darken + {0.323529, 0.76, 0.672745, 0.9375}, // Lighten + {0.353955, 0.998235, 0.744855, 0.9375}, // ColorDodge + {0.147059, 0.439211, 0.25451, 0.9375}, // ColorBurn + {0.198962, 0.730571, 0.37752, 0.9375}, // HardLight + {0.235599, 0.688817, 0.583309, 0.9375}, // SoftLight + {0.235294, 0.497059, 0.58451, 0.9375}, // Difference + {0.359862, 0.705865, 0.63797, 0.9375}, // Exclusion + {0.17301, 0.556773, 0.316015, 0.9375}, // Multiply + {0.2585, 0.751441, 0.365951, 0.9375}, // Hue + {0.313332, 0.66234, 0.694313, 0.9375}, // Saturation + {0.239759, 0.764465, 0.34721, 0.9375}, // Color + {0.319065, 0.656712, 0.66828, 0.9375}, // Luminosity }, { {0, 0, 0, 0}, // Clear @@ -1522,20 +1522,20 @@ struct ColorBlendTestData { {0.196078, 0.292157, 0.464706, 0.375}, // Xor {0.294118, 0.438235, 0.697059, 1}, // Plus {0, 0, 0, 0.5625}, // Modulate - {0.313726, 0.467451, 0.743529, 0.9375}, // Screen - {0.0784314, 0.116863, 0.501176, 0.9375}, // Overlay + {0.254902, 0.379804, 0.604118, 0.9375}, // Screen + {0.0784314, 0.116863, 0.422353, 0.9375}, // Overlay {0.0784314, 0.116863, 0.185882, 0.9375}, // Darken - {0.313726, 0.467451, 0.743529, 0.9375}, // Lighten - {0.318627, 0.474755, 0.755147, 0.75}, // ColorDodge - {0.0980392, 0.146078, 0.232353, 0.75}, // ColorBurn + {0.254902, 0.379804, 0.604118, 0.9375}, // Lighten + {0.254902, 0.379804, 0.604118, 0.9375}, // ColorDodge + {0.0784314, 0.116863, 0.185882, 0.9375}, // ColorBurn {0.0784314, 0.116863, 0.185882, 0.9375}, // HardLight - {0.147636, 0.270503, 0.574595, 0.9375}, // SoftLight - {0.313726, 0.467451, 0.743529, 0.9375}, // Difference - {0.313726, 0.467451, 0.743529, 0.9375}, // Exclusion + {0.130334, 0.232093, 0.477417, 0.9375}, // SoftLight + {0.254902, 0.379804, 0.604118, 0.9375}, // Difference + {0.254902, 0.379804, 0.604118, 0.9375}, // Exclusion {0.0784314, 0.116863, 0.185882, 0.9375}, // Multiply - {0.417208, 0.455639, 0.524659, 0.9375}, // Hue - {0.417208, 0.455639, 0.524659, 0.9375}, // Saturation - {0.417208, 0.455639, 0.524659, 0.9375}, // Color + {0.332514, 0.370945, 0.439965, 0.9375}, // Hue + {0.332514, 0.370945, 0.439965, 0.9375}, // Saturation + {0.332514, 0.370945, 0.439965, 0.9375}, // Color {0.0784314, 0.116863, 0.185882, 0.9375}, // Luminosity }, }; From 3999403bca02ef6b43be8f3ccb32ea8c3c1e30ac Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Fri, 26 Jan 2024 18:18:55 -0800 Subject: [PATCH 07/10] malioc --- impeller/tools/malioc.json | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/impeller/tools/malioc.json b/impeller/tools/malioc.json index 4f7b6e72ffa59..56668a14f4441 100644 --- a/impeller/tools/malioc.json +++ b/impeller/tools/malioc.json @@ -20,8 +20,8 @@ "texture" ], "longest_path_cycles": [ - 0.390625, - 0.390625, + 0.40625, + 0.40625, 0.015625, 0.0, 0.0, @@ -42,8 +42,8 @@ "arith_fma" ], "shortest_path_cycles": [ - 0.328125, - 0.328125, + 0.34375, + 0.34375, 0.09375, 0.0, 0.0, @@ -55,8 +55,8 @@ "texture" ], "total_cycles": [ - 0.390625, - 0.390625, + 0.40625, + 0.40625, 0.09375, 0.0, 0.0, @@ -1431,9 +1431,9 @@ "texture" ], "longest_path_cycles": [ - 0.390625, - 0.390625, - 0.046875, + 0.40625, + 0.40625, + 0.0625, 0.0, 0.0, 0.5, @@ -1453,9 +1453,9 @@ "arith_fma" ], "shortest_path_cycles": [ - 0.328125, - 0.328125, - 0.09375, + 0.34375, + 0.34375, + 0.109375, 0.0, 0.0, 0.25, @@ -1466,9 +1466,9 @@ "texture" ], "total_cycles": [ - 0.390625, - 0.390625, - 0.125, + 0.40625, + 0.40625, + 0.140625, 0.0, 0.0, 0.5, @@ -1478,7 +1478,7 @@ "stack_spill_bytes": 0, "thread_occupancy": 100, "uniform_registers_used": 12, - "work_registers_used": 24 + "work_registers_used": 25 } } }, From 1c462e5ec30b4172803c946fc7cf1c994f793af5 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Sat, 27 Jan 2024 02:34:49 -0800 Subject: [PATCH 08/10] Fix all the things --- impeller/aiks/aiks_unittests.cc | 18 +++-- .../shader_lib/impeller/blending.glsl | 24 +++--- .../shaders/blending/advanced_blend.frag | 22 +++--- .../shaders/blending/framebuffer_blend.frag | 11 +-- impeller/geometry/color.cc | 28 +++---- impeller/geometry/geometry_unittests.cc | 78 +++++++++---------- 6 files changed, 93 insertions(+), 88 deletions(-) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index 0b8fececa29c9..817f56aae227a 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -2208,6 +2208,9 @@ static Picture BlendModeTest(Vector2 content_scale, Canvas canvas; canvas.DrawPaint({.color = Color::Black()}); + // TODO(bdero): Why does this cause the left image to double scale on high DPI + // displays. + // canvas.Scale(content_scale); //---------------------------------------------------------------------------- /// 1. Save layer blending (top squares). @@ -2245,7 +2248,6 @@ static Picture BlendModeTest(Vector2 content_scale, canvas.Save(); canvas.Translate({0, 100}); - // Perform the blend in a SaveLayer so that the initial backdrop color is // fully transparent black. SourceOver blend the result onto the parent pass. canvas.SaveLayer({}); @@ -2256,7 +2258,8 @@ static Picture BlendModeTest(Vector2 content_scale, .blend_mode = BlendMode::kSourceOver}); canvas.Translate(Vector2(100, 0)); } - canvas.RestoreToCount(0); + canvas.Restore(); + canvas.Restore(); //---------------------------------------------------------------------------- /// 3. Image blending (bottom images). @@ -2278,16 +2281,17 @@ static Picture BlendModeTest(Vector2 content_scale, } } - // Uploaded image source (unpremultiplied source texture). + // Uploaded image source (left image). canvas.Save(); canvas.SaveLayer({.blend_mode = BlendMode::kSourceOver}); { canvas.DrawImage(dst_image, {0, 0}, {.blend_mode = BlendMode::kSourceOver}); canvas.DrawImage(src_image, {0, 0}, {.blend_mode = blend_mode}); } - canvas.RestoreToCount(0); + canvas.Restore(); + canvas.Restore(); - // Rendered image source (premultiplied source texture). + // Rendered image source (right image). canvas.Save(); canvas.SaveLayer({.blend_mode = BlendMode::kSourceOver}); { @@ -2301,7 +2305,7 @@ static Picture BlendModeTest(Vector2 content_scale, canvas.Restore(); } canvas.Restore(); - canvas.RestoreToCount(0); + canvas.Restore(); return canvas.EndRecordingAsPicture(); } @@ -3176,7 +3180,7 @@ TEST_P(AiksTest, SolidColorApplyColorFilter) { }); ASSERT_TRUE(result); ASSERT_COLOR_NEAR(contents.GetColor(), - Color(0.385813, 0.864403, 0.699475, 0.9375)); + Color(0.424452, 0.828743, 0.79105, 0.9375)); } TEST_P(AiksTest, DrawScaledTextWithPerspectiveNoSaveLayer) { diff --git a/impeller/compiler/shader_lib/impeller/blending.glsl b/impeller/compiler/shader_lib/impeller/blending.glsl index 75ac09385828f..59352f2bd22d2 100644 --- a/impeller/compiler/shader_lib/impeller/blending.glsl +++ b/impeller/compiler/shader_lib/impeller/blending.glsl @@ -6,24 +6,26 @@ #define BLENDING_GLSL_ #include +#include #include #include /// Composite a blended color onto the destination. +/// All three parameters are unpremultiplied. Returns a premultiplied result. /// -/// All three parameters are premultiplied, including `blend_result`, which -/// is assumed to already be premultiplied with `src.a`. -/// -/// This routine is identical to `ApplyBlendedColor` in +/// This routine is the same as `ApplyBlendedColor` in /// `impeller/geometry/color.cc`. f16vec4 IPApplyBlendedColor(f16vec4 dst, f16vec4 src, f16vec3 blend_result) { - // The source and destination alpha modulates the amount that the colors - // should get blended. This color becomes the new source color for the alpha - // composite step. - f16vec3 blended_src = mix(src.rgb, blend_result, dst.a * src.a); - - // Source-over blend atop the destination color. - return f16vec4(blended_src, src.a) + dst * (1.0hf - src.a); + dst = IPHalfPremultiply(dst); + src = + // Use the blended color for areas where the source and destination + // colors overlap. + IPHalfPremultiply(f16vec4(blend_result, src.a * dst.a)) + + // Use the original source color for any remaining non-overlapping areas. + IPHalfPremultiply(src) * (1.0hf - dst.a); + + // Source-over composite the blended source color atop the destination. + return src + dst * (1.0hf - src.a); } //------------------------------------------------------------------------------ diff --git a/impeller/entity/shaders/blending/advanced_blend.frag b/impeller/entity/shaders/blending/advanced_blend.frag index 54cb9b6b2a44f..3a8175de64ef5 100644 --- a/impeller/entity/shaders/blending/advanced_blend.frag +++ b/impeller/entity/shaders/blending/advanced_blend.frag @@ -36,16 +36,18 @@ f16vec4 Sample(f16sampler2D texture_sampler, vec2 texture_coords) { } void main() { - f16vec4 dst = Sample(texture_sampler_dst, // sampler - v_dst_texture_coords // texture coordinates - ) * - blend_info.dst_input_alpha; - f16vec4 src = blend_info.color_factor > 0.0hf - ? blend_info.color - : Sample(texture_sampler_src, // sampler - v_src_texture_coords // texture coordinates - ) * - blend_info.src_input_alpha; + f16vec4 dst = + IPUnpremultiply(Sample(texture_sampler_dst, // sampler + v_dst_texture_coords // texture coordinates + )); + dst *= blend_info.dst_input_alpha; + f16vec4 src = + IPUnpremultiply(blend_info.color_factor > 0.0hf + ? blend_info.color + : Sample(texture_sampler_src, // sampler + v_src_texture_coords // texture coordinates + )); + src *= blend_info.src_input_alpha; f16vec3 blend_result = AdvancedBlend(dst.rgb, src.rgb, int(blend_type)); diff --git a/impeller/entity/shaders/blending/framebuffer_blend.frag b/impeller/entity/shaders/blending/framebuffer_blend.frag index 06d1da88b3a7a..06160e432593b 100644 --- a/impeller/entity/shaders/blending/framebuffer_blend.frag +++ b/impeller/entity/shaders/blending/framebuffer_blend.frag @@ -55,11 +55,12 @@ vec4 Sample(sampler2D texture_sampler, vec2 texture_coords) { } void main() { - f16vec4 dst = f16vec4(ReadDestination()); - f16vec4 src = f16vec4(Sample(texture_sampler_src, // sampler - v_src_texture_coords // texture coordinates - )) * - frag_info.src_input_alpha; + f16vec4 dst = IPUnpremultiply(f16vec4(ReadDestination())); + f16vec4 src = IPUnpremultiply( + f16vec4(Sample(texture_sampler_src, // sampler + v_src_texture_coords // texture coordinates + ))); + src.a *= frag_info.src_input_alpha; f16vec3 blend_result = AdvancedBlend(dst.rgb, src.rgb, int(blend_type)); diff --git a/impeller/geometry/color.cc b/impeller/geometry/color.cc index 15763bfa8e9fb..d2565e6e6fd1d 100644 --- a/impeller/geometry/color.cc +++ b/impeller/geometry/color.cc @@ -194,31 +194,29 @@ static constexpr inline Color FromRGB(Vector3 color, Scalar alpha) { } /// Composite a blended color onto the destination. +/// All three parameters are unpremultiplied. Returns a premultiplied result. /// -/// All three parameters are premultiplied, including `blend_result`, which -/// is assumed to already be premultiplied with `src.a`. -/// -/// This routine is identical to `IPApplyBlendedColor` in the Impeller shader +/// This routine is the same as `IPApplyBlendedColor` in the Impeller shader /// library. static constexpr inline Color ApplyBlendedColor(Color dst, Color src, Vector3 blend_result) { - // The source and destination alpha modulates the amount that the colors - // should get blended. This color becomes the new source color for the alpha - // composite step. - const Vector3 blended_src = - ToRGB(src).Lerp(blend_result, dst.alpha * src.alpha); - - // Source-over blend atop the destination color. - return FromRGB(blended_src, src.alpha) + dst * (1.0f - src.alpha); + dst = dst.Premultiply(); + src = + // Use the blended color for areas where the source and destination + // colors overlap. + FromRGB(blend_result, src.alpha * dst.alpha).Premultiply() + + // Use the original source color for any remaining non-overlapping areas. + src.Premultiply() * (1.0f - dst.alpha); + + // Source-over composite the blended source color atop the destination. + return src + dst * (1.0f - src.alpha); } static constexpr inline Color DoColorBlend( Color dst, Color src, const std::function& blend_rgb_func) { - dst = dst.Premultiply(); - src = src.Premultiply(); const Vector3 blend_result = blend_rgb_func(ToRGB(dst), ToRGB(src)); return ApplyBlendedColor(dst, src, blend_result).Unpremultiply(); } @@ -227,8 +225,6 @@ static constexpr inline Color DoColorBlendComponents( Color dst, Color src, const std::function& blend_func) { - dst = dst.Premultiply(); - src = src.Premultiply(); Vector3 blend_result = Vector3(blend_func(dst.red, src.red), // blend_func(dst.green, src.green), // blend_func(dst.blue, src.blue)); // diff --git a/impeller/geometry/geometry_unittests.cc b/impeller/geometry/geometry_unittests.cc index 3e8679bf38cad..d9df8d1bf0893 100644 --- a/impeller/geometry/geometry_unittests.cc +++ b/impeller/geometry/geometry_unittests.cc @@ -1460,21 +1460,21 @@ struct ColorBlendTestData { {0.696078, 0.792157, 0.964706, 0.375}, // Xor {1, 1, 1, 1}, // Plus {0.392157, 0.584314, 0.929412, 0.5625}, // Modulate - {0.922549, 0.982598, 1.09044, 0.9375}, // Screen - {0.693137, 0.861275, 1.045, 0.9375}, // Overlay - {0.604902, 0.729804, 0.954118, 0.9375}, // Darken + {0.878431, 0.916863, 0.985882, 0.9375}, // Screen + {0.74902, 0.916863, 0.985882, 0.9375}, // Overlay + {0.513726, 0.667451, 0.943529, 0.9375}, // Darken {0.878431, 0.916863, 0.985882, 0.9375}, // Lighten - {1.02843, 1.06686, 1.13588, 0.9375}, // ColorDodge - {0.463726, 0.617451, 0.893529, 0.9375}, // ColorBurn - {0.816667, 0.898333, 1.045, 0.9375}, // HardLight - {0.679365, 0.796931, 0.99547, 0.9375}, // SoftLight - {0.701961, 0.653922, 0.567647, 0.9375}, // Difference - {0.790196, 0.785392, 0.776765, 0.9375}, // Exclusion - {0.560784, 0.664069, 0.849559, 0.9375}, // Multiply - {0.682514, 0.720945, 0.789965, 0.9375}, // Hue - {0.682514, 0.720945, 0.789965, 0.9375}, // Saturation - {0.682514, 0.720945, 0.789965, 0.9375}, // Color - {0.807769, 0.924928, 1.13534, 0.9375}, // Luminosity + {0.878431, 0.916863, 0.985882, 0.9375}, // ColorDodge + {0.513725, 0.667451, 0.943529, 0.9375}, // ColorBurn + {0.878431, 0.916863, 0.985882, 0.9375}, // HardLight + {0.654166, 0.775505, 0.964318, 0.9375}, // SoftLight + {0.643137, 0.566275, 0.428235, 0.9375}, // Difference + {0.643137, 0.566275, 0.428235, 0.9375}, // Exclusion + {0.513726, 0.667451, 0.943529, 0.9375}, // Multiply + {0.617208, 0.655639, 0.724659, 0.9375}, // Hue + {0.617208, 0.655639, 0.724659, 0.9375}, // Saturation + {0.617208, 0.655639, 0.724659, 0.9375}, // Color + {0.878431, 0.916863, 0.985882, 0.9375}, // Luminosity }, { {0, 0, 0, 0}, // Clear @@ -1491,21 +1491,21 @@ struct ColorBlendTestData { {0.294118, 0.694118, 0.562745, 0.375}, // Xor {0.441176, 1, 0.844118, 1}, // Plus {0.0768935, 0.469742, 0.182238, 0.5625}, // Modulate - {0.385813, 0.864403, 0.699475, 0.9375}, // Screen - {0.198962, 0.715311, 0.544441, 0.9375}, // Overlay - {0.235294, 0.661177, 0.342745, 0.9375}, // Darken - {0.323529, 0.76, 0.672745, 0.9375}, // Lighten - {0.353955, 0.998235, 0.744855, 0.9375}, // ColorDodge - {0.147059, 0.439211, 0.25451, 0.9375}, // ColorBurn - {0.198962, 0.730571, 0.37752, 0.9375}, // HardLight - {0.235599, 0.688817, 0.583309, 0.9375}, // SoftLight - {0.235294, 0.497059, 0.58451, 0.9375}, // Difference - {0.359862, 0.705865, 0.63797, 0.9375}, // Exclusion - {0.17301, 0.556773, 0.316015, 0.9375}, // Multiply - {0.2585, 0.751441, 0.365951, 0.9375}, // Hue - {0.313332, 0.66234, 0.694313, 0.9375}, // Saturation - {0.239759, 0.764465, 0.34721, 0.9375}, // Color - {0.319065, 0.656712, 0.66828, 0.9375}, // Luminosity + {0.424452, 0.828743, 0.79105, 0.9375}, // Screen + {0.209919, 0.779839, 0.757001, 0.9375}, // Overlay + {0.235294, 0.628235, 0.342745, 0.9375}, // Darken + {0.352941, 0.76, 0.782745, 0.9375}, // Lighten + {0.41033, 0.877647, 0.825098, 0.9375}, // ColorDodge + {0.117647, 0.567403, 0.609098, 0.9375}, // ColorBurn + {0.209919, 0.779839, 0.443783, 0.9375}, // HardLight + {0.266006, 0.693915, 0.758818, 0.9375}, // SoftLight + {0.235294, 0.409412, 0.665098, 0.9375}, // Difference + {0.378316, 0.546897, 0.681707, 0.9375}, // Exclusion + {0.163783, 0.559493, 0.334441, 0.9375}, // Multiply + {0.266235, 0.748588, 0.373686, 0.9375}, // Hue + {0.339345, 0.629787, 0.811502, 0.9375}, // Saturation + {0.241247, 0.765953, 0.348698, 0.9375}, // Color + {0.346988, 0.622282, 0.776792, 0.9375}, // Luminosity }, { {0, 0, 0, 0}, // Clear @@ -1522,20 +1522,20 @@ struct ColorBlendTestData { {0.196078, 0.292157, 0.464706, 0.375}, // Xor {0.294118, 0.438235, 0.697059, 1}, // Plus {0, 0, 0, 0.5625}, // Modulate - {0.254902, 0.379804, 0.604118, 0.9375}, // Screen - {0.0784314, 0.116863, 0.422353, 0.9375}, // Overlay + {0.313726, 0.467451, 0.743529, 0.9375}, // Screen + {0.0784314, 0.218039, 0.701176, 0.9375}, // Overlay {0.0784314, 0.116863, 0.185882, 0.9375}, // Darken - {0.254902, 0.379804, 0.604118, 0.9375}, // Lighten - {0.254902, 0.379804, 0.604118, 0.9375}, // ColorDodge + {0.313726, 0.467451, 0.743529, 0.9375}, // Lighten + {0.313726, 0.467451, 0.743529, 0.9375}, // ColorDodge {0.0784314, 0.116863, 0.185882, 0.9375}, // ColorBurn {0.0784314, 0.116863, 0.185882, 0.9375}, // HardLight - {0.130334, 0.232093, 0.477417, 0.9375}, // SoftLight - {0.254902, 0.379804, 0.604118, 0.9375}, // Difference - {0.254902, 0.379804, 0.604118, 0.9375}, // Exclusion + {0.170704, 0.321716, 0.704166, 0.9375}, // SoftLight + {0.313726, 0.467451, 0.743529, 0.9375}, // Difference + {0.313726, 0.467451, 0.743529, 0.9375}, // Exclusion {0.0784314, 0.116863, 0.185882, 0.9375}, // Multiply - {0.332514, 0.370945, 0.439965, 0.9375}, // Hue - {0.332514, 0.370945, 0.439965, 0.9375}, // Saturation - {0.332514, 0.370945, 0.439965, 0.9375}, // Color + {0.417208, 0.455639, 0.524659, 0.9375}, // Hue + {0.417208, 0.455639, 0.524659, 0.9375}, // Saturation + {0.417208, 0.455639, 0.524659, 0.9375}, // Color {0.0784314, 0.116863, 0.185882, 0.9375}, // Luminosity }, }; From 04cbac2489baae2c0e09dd1d81290761698bc112 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Sat, 27 Jan 2024 03:53:01 -0800 Subject: [PATCH 09/10] half --- .../shaders/blending/advanced_blend.frag | 18 +++++++++--------- .../shaders/blending/framebuffer_blend.frag | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/impeller/entity/shaders/blending/advanced_blend.frag b/impeller/entity/shaders/blending/advanced_blend.frag index 3a8175de64ef5..0e7f80958ccac 100644 --- a/impeller/entity/shaders/blending/advanced_blend.frag +++ b/impeller/entity/shaders/blending/advanced_blend.frag @@ -37,16 +37,16 @@ f16vec4 Sample(f16sampler2D texture_sampler, vec2 texture_coords) { void main() { f16vec4 dst = - IPUnpremultiply(Sample(texture_sampler_dst, // sampler - v_dst_texture_coords // texture coordinates - )); + IPHalfUnpremultiply(Sample(texture_sampler_dst, // sampler + v_dst_texture_coords // texture coordinates + )); dst *= blend_info.dst_input_alpha; - f16vec4 src = - IPUnpremultiply(blend_info.color_factor > 0.0hf - ? blend_info.color - : Sample(texture_sampler_src, // sampler - v_src_texture_coords // texture coordinates - )); + f16vec4 src = IPHalfUnpremultiply( + blend_info.color_factor > 0.0hf + ? blend_info.color + : Sample(texture_sampler_src, // sampler + v_src_texture_coords // texture coordinates + )); src *= blend_info.src_input_alpha; f16vec3 blend_result = AdvancedBlend(dst.rgb, src.rgb, int(blend_type)); diff --git a/impeller/entity/shaders/blending/framebuffer_blend.frag b/impeller/entity/shaders/blending/framebuffer_blend.frag index 06160e432593b..095d5e5bd66d0 100644 --- a/impeller/entity/shaders/blending/framebuffer_blend.frag +++ b/impeller/entity/shaders/blending/framebuffer_blend.frag @@ -55,8 +55,8 @@ vec4 Sample(sampler2D texture_sampler, vec2 texture_coords) { } void main() { - f16vec4 dst = IPUnpremultiply(f16vec4(ReadDestination())); - f16vec4 src = IPUnpremultiply( + f16vec4 dst = IPHalfUnpremultiply(f16vec4(ReadDestination())); + f16vec4 src = IPHalfUnpremultiply( f16vec4(Sample(texture_sampler_src, // sampler v_src_texture_coords // texture coordinates ))); From caf0d80f4351ebaf471c0c12fe670ac6f042f366 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Sat, 27 Jan 2024 04:26:55 -0800 Subject: [PATCH 10/10] malioc --- impeller/tools/malioc.json | 76 +++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/impeller/tools/malioc.json b/impeller/tools/malioc.json index 56668a14f4441..8cf4183c4f6ac 100644 --- a/impeller/tools/malioc.json +++ b/impeller/tools/malioc.json @@ -16,14 +16,14 @@ "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ - "varying", - "texture" + "arith_total", + "arith_fma" ], "longest_path_cycles": [ - 0.40625, - 0.40625, - 0.015625, - 0.0, + 0.625, + 0.625, + 0.21875, + 0.125, 0.0, 0.5, 0.5 @@ -42,23 +42,23 @@ "arith_fma" ], "shortest_path_cycles": [ - 0.34375, - 0.34375, - 0.09375, - 0.0, + 0.625, + 0.625, + 0.234375, + 0.125, 0.0, 0.25, 0.25 ], "total_bound_pipelines": [ - "varying", - "texture" + "arith_total", + "arith_fma" ], "total_cycles": [ - 0.40625, - 0.40625, - 0.09375, - 0.0, + 0.625, + 0.625, + 0.296875, + 0.125, 0.0, 0.5, 0.5 @@ -67,7 +67,7 @@ "stack_spill_bytes": 0, "thread_occupancy": 100, "uniform_registers_used": 10, - "work_registers_used": 18 + "work_registers_used": 24 } } } @@ -1427,14 +1427,14 @@ "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ - "varying", - "texture" + "arith_total", + "arith_fma" ], "longest_path_cycles": [ - 0.40625, - 0.40625, - 0.0625, - 0.0, + 0.625, + 0.625, + 0.265625, + 0.125, 0.0, 0.5, 0.5 @@ -1453,23 +1453,23 @@ "arith_fma" ], "shortest_path_cycles": [ - 0.34375, - 0.34375, - 0.109375, - 0.0, + 0.625, + 0.625, + 0.25, + 0.125, 0.0, 0.25, 0.25 ], "total_bound_pipelines": [ - "varying", - "texture" + "arith_total", + "arith_fma" ], "total_cycles": [ - 0.40625, - 0.40625, - 0.140625, - 0.0, + 0.625, + 0.625, + 0.34375, + 0.125, 0.0, 0.5, 0.5 @@ -1478,7 +1478,7 @@ "stack_spill_bytes": 0, "thread_occupancy": 100, "uniform_registers_used": 12, - "work_registers_used": 25 + "work_registers_used": 22 } } }, @@ -1495,7 +1495,7 @@ "arithmetic" ], "longest_path_cycles": [ - 2.640000104904175, + 3.630000114440918, 2.0, 2.0 ], @@ -1508,7 +1508,7 @@ "arithmetic" ], "shortest_path_cycles": [ - 2.309999942779541, + 3.299999952316284, 1.0, 1.0 ], @@ -1516,14 +1516,14 @@ "arithmetic" ], "total_cycles": [ - 3.0, + 4.0, 2.0, 2.0 ] }, "thread_occupancy": 100, "uniform_registers_used": 2, - "work_registers_used": 3 + "work_registers_used": 4 } } }