From f1589cc18208b67fc9ce5c0e77af42805d138b00 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 2 Jun 2022 17:05:54 -0700 Subject: [PATCH 1/4] Add seperable advanced blend shaders --- impeller/entity/BUILD.gn | 8 ++++++ .../blending/advanced_blend_colorburn.frag | 4 +-- .../blending/advanced_blend_colordodge.frag | 14 +++++++++++ .../blending/advanced_blend_darken.frag | 9 +++++++ .../blending/advanced_blend_difference.frag | 9 +++++++ .../blending/advanced_blend_exclusion.frag | 9 +++++++ .../blending/advanced_blend_hardlight.frag | 11 ++++++++ .../blending/advanced_blend_lighten.frag | 9 +++++++ .../blending/advanced_blend_overlay.frag | 12 +++++++++ .../blending/advanced_blend_screen.frag | 4 ++- .../blending/advanced_blend_softlight.frag | 17 +++++++++++++ .../blending/advanced_blend_utils.glsl | 25 +++++++++++++++++++ 12 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 impeller/entity/shaders/blending/advanced_blend_colordodge.frag create mode 100644 impeller/entity/shaders/blending/advanced_blend_darken.frag create mode 100644 impeller/entity/shaders/blending/advanced_blend_difference.frag create mode 100644 impeller/entity/shaders/blending/advanced_blend_exclusion.frag create mode 100644 impeller/entity/shaders/blending/advanced_blend_hardlight.frag create mode 100644 impeller/entity/shaders/blending/advanced_blend_lighten.frag create mode 100644 impeller/entity/shaders/blending/advanced_blend_overlay.frag create mode 100644 impeller/entity/shaders/blending/advanced_blend_softlight.frag create mode 100644 impeller/entity/shaders/blending/advanced_blend_utils.glsl diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 3de1d3f68363c..f7f6d0988efd5 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -10,7 +10,15 @@ impeller_shaders("entity_shaders") { shaders = [ "shaders/blending/advanced_blend.vert", "shaders/blending/advanced_blend_colorburn.frag", + "shaders/blending/advanced_blend_colordodge.frag", + "shaders/blending/advanced_blend_darken.frag", + "shaders/blending/advanced_blend_difference.frag", + "shaders/blending/advanced_blend_exclusion.frag", + "shaders/blending/advanced_blend_hardlight.frag", + "shaders/blending/advanced_blend_lighten.frag", + "shaders/blending/advanced_blend_overlay.frag", "shaders/blending/advanced_blend_screen.frag", + "shaders/blending/advanced_blend_softlight.frag", "shaders/blending/blend.frag", "shaders/blending/blend.vert", "shaders/border_mask_blur.frag", diff --git a/impeller/entity/shaders/blending/advanced_blend_colorburn.frag b/impeller/entity/shaders/blending/advanced_blend_colorburn.frag index 57e962da533f1..ca39e490e0577 100644 --- a/impeller/entity/shaders/blending/advanced_blend_colorburn.frag +++ b/impeller/entity/shaders/blending/advanced_blend_colorburn.frag @@ -2,9 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -vec3 ComponentIsValue(vec3 n, float value) { - return vec3(n.r == value, n.g == value, n.b == value); -} +#include "advanced_blend_utils.glsl" vec3 Blend(vec3 dst, vec3 src) { vec3 color = 1 - min(vec3(1), (1 - dst) / src); diff --git a/impeller/entity/shaders/blending/advanced_blend_colordodge.frag b/impeller/entity/shaders/blending/advanced_blend_colordodge.frag new file mode 100644 index 0000000000000..1f4294c4bea00 --- /dev/null +++ b/impeller/entity/shaders/blending/advanced_blend_colordodge.frag @@ -0,0 +1,14 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "advanced_blend_utils.glsl" + +vec3 Blend(vec3 dst, vec3 src) { + vec3 color = min(vec3(1), dst / (1 - src)); + color = mix(color, vec3(1), ComponentIsValue(dst, 1.0)); + color = mix(color, vec3(0), ComponentIsValue(src, 0.0)); + return color; +} + +#include "advanced_blend.glsl" diff --git a/impeller/entity/shaders/blending/advanced_blend_darken.frag b/impeller/entity/shaders/blending/advanced_blend_darken.frag new file mode 100644 index 0000000000000..ca7ff86c16012 --- /dev/null +++ b/impeller/entity/shaders/blending/advanced_blend_darken.frag @@ -0,0 +1,9 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +vec3 Blend(vec3 dst, vec3 src) { + return min(dst, src); +} + +#include "advanced_blend.glsl" diff --git a/impeller/entity/shaders/blending/advanced_blend_difference.frag b/impeller/entity/shaders/blending/advanced_blend_difference.frag new file mode 100644 index 0000000000000..6332866914736 --- /dev/null +++ b/impeller/entity/shaders/blending/advanced_blend_difference.frag @@ -0,0 +1,9 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +vec3 Blend(vec3 dst, vec3 src) { + return abs(dst - src); +} + +#include "advanced_blend.glsl" diff --git a/impeller/entity/shaders/blending/advanced_blend_exclusion.frag b/impeller/entity/shaders/blending/advanced_blend_exclusion.frag new file mode 100644 index 0000000000000..165f8287cb0e5 --- /dev/null +++ b/impeller/entity/shaders/blending/advanced_blend_exclusion.frag @@ -0,0 +1,9 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +vec3 Blend(vec3 dst, vec3 src) { + return dst + src - 2 * dst * src; +} + +#include "advanced_blend.glsl" diff --git a/impeller/entity/shaders/blending/advanced_blend_hardlight.frag b/impeller/entity/shaders/blending/advanced_blend_hardlight.frag new file mode 100644 index 0000000000000..16975d3cb8ae7 --- /dev/null +++ b/impeller/entity/shaders/blending/advanced_blend_hardlight.frag @@ -0,0 +1,11 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "advanced_blend_utils.glsl" + +vec3 Blend(vec3 dst, vec3 src) { + return BlendHardLight(dst, src); +} + +#include "advanced_blend.glsl" \ No newline at end of file diff --git a/impeller/entity/shaders/blending/advanced_blend_lighten.frag b/impeller/entity/shaders/blending/advanced_blend_lighten.frag new file mode 100644 index 0000000000000..2891754cc06dd --- /dev/null +++ b/impeller/entity/shaders/blending/advanced_blend_lighten.frag @@ -0,0 +1,9 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +vec3 Blend(vec3 dst, vec3 src) { + return max(dst, src); +} + +#include "advanced_blend.glsl" diff --git a/impeller/entity/shaders/blending/advanced_blend_overlay.frag b/impeller/entity/shaders/blending/advanced_blend_overlay.frag new file mode 100644 index 0000000000000..d822569d551c7 --- /dev/null +++ b/impeller/entity/shaders/blending/advanced_blend_overlay.frag @@ -0,0 +1,12 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "advanced_blend_utils.glsl" + +vec3 Blend(vec3 dst, vec3 src) { + // HardLight, but with reversed parameters. + return BlendHardLight(src, dst); +} + +#include "advanced_blend.glsl" diff --git a/impeller/entity/shaders/blending/advanced_blend_screen.frag b/impeller/entity/shaders/blending/advanced_blend_screen.frag index 09988e27be9dd..a3a941215ce25 100644 --- a/impeller/entity/shaders/blending/advanced_blend_screen.frag +++ b/impeller/entity/shaders/blending/advanced_blend_screen.frag @@ -2,8 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "advanced_blend_utils.glsl" + vec3 Blend(vec3 dst, vec3 src) { - return dst + src - (dst * src); + return BlendScreen(dst, src); } #include "advanced_blend.glsl" diff --git a/impeller/entity/shaders/blending/advanced_blend_softlight.frag b/impeller/entity/shaders/blending/advanced_blend_softlight.frag new file mode 100644 index 0000000000000..ee893aedd69ca --- /dev/null +++ b/impeller/entity/shaders/blending/advanced_blend_softlight.frag @@ -0,0 +1,17 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "advanced_blend_utils.glsl" + +vec3 Blend(vec3 dst, vec3 src) { + vec3 D = mix(((16 * dst - 12) * dst + 4) * dst, // + sqrt(dst), // + 0.25); + + return MixHalf(dst - (1 - 2 * src) * dst * (1 - dst), // + dst + (2 * src - 1) * (D - dst), // + src); +} + +#include "advanced_blend.glsl" diff --git a/impeller/entity/shaders/blending/advanced_blend_utils.glsl b/impeller/entity/shaders/blending/advanced_blend_utils.glsl new file mode 100644 index 0000000000000..f35a3c6f82664 --- /dev/null +++ b/impeller/entity/shaders/blending/advanced_blend_utils.glsl @@ -0,0 +1,25 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +vec3 ComponentIsValue(vec3 n, float value) { + return vec3(n.r == value, n.g == value, n.b == value); +} + +vec3 MixComponents(vec3 a, vec3 b, vec3 weight, float cutoff) { + return vec3(mix(a.x, b.x, weight.x > cutoff), // + mix(a.y, b.y, weight.y > cutoff), // + mix(a.z, b.z, weight.z > cutoff)); +} + +vec3 MixHalf(vec3 a, vec3 b, vec3 weight) { + return MixComponents(a, b, weight, 0.5); +} + +vec3 BlendScreen(vec3 dst, vec3 src) { + return dst + src - (dst * src); +} + +vec3 BlendHardLight(vec3 dst, vec3 src) { + return MixHalf(dst * (2 * src), BlendScreen(dst, 2 * src - 1), src); +} From 8a6b30da14f4c4f49be697569adb99b2fa3767a0 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Fri, 3 Jun 2022 17:04:46 -0700 Subject: [PATCH 2/4] Hook up separable advanced blends --- impeller/aiks/aiks_unittests.cc | 9 ++ .../display_list/display_list_dispatcher.cc | 13 +- impeller/entity/BUILD.gn | 1 + impeller/entity/contents/content_context.cc | 22 +++- impeller/entity/contents/content_context.h | 112 +++++++++++++++--- .../contents/filters/blend_filter_contents.cc | 47 ++++---- impeller/entity/entity.h | 11 +- .../blending/advanced_blend_colordodge.frag | 4 +- .../blending/advanced_blend_multiply.frag | 9 ++ .../blending/advanced_blend_softlight.frag | 7 +- .../blending/advanced_blend_utils.glsl | 3 +- 11 files changed, 190 insertions(+), 48 deletions(-) create mode 100644 impeller/entity/shaders/blending/advanced_blend_multiply.frag diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index 7a1acabc8408f..1adcd168faa62 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -534,7 +534,16 @@ TEST_P(AiksTest, ColorWheel) { {"Modulate", Entity::BlendMode::kModulate}, // Advanced blends (color component blends) {"Screen", Entity::BlendMode::kScreen}, + {"Overlay", Entity::BlendMode::kOverlay}, + {"Darken", Entity::BlendMode::kDarken}, + {"Lighten", Entity::BlendMode::kLighten}, + {"ColorDodge", Entity::BlendMode::kColorDodge}, {"ColorBurn", Entity::BlendMode::kColorBurn}, + {"HardLight", Entity::BlendMode::kHardLight}, + {"SoftLight", Entity::BlendMode::kSoftLight}, + {"Difference", Entity::BlendMode::kDifference}, + {"Exclusion", Entity::BlendMode::kExclusion}, + {"Multiply", Entity::BlendMode::kMultiply}, }; assert(blends.size() == static_cast(Entity::BlendMode::kLastAdvancedBlendMode) + 1); diff --git a/impeller/display_list/display_list_dispatcher.cc b/impeller/display_list/display_list_dispatcher.cc index ec25ec44ebfcf..02b3414b8e0a3 100644 --- a/impeller/display_list/display_list_dispatcher.cc +++ b/impeller/display_list/display_list_dispatcher.cc @@ -66,17 +66,26 @@ static std::optional ToBlendMode(flutter::DlBlendMode mode) { return Entity::BlendMode::kModulate; case flutter::DlBlendMode::kScreen: return Entity::BlendMode::kScreen; - case flutter::DlBlendMode::kColorBurn: - return Entity::BlendMode::kColorBurn; case flutter::DlBlendMode::kOverlay: + return Entity::BlendMode::kOverlay; case flutter::DlBlendMode::kDarken: + return Entity::BlendMode::kDarken; case flutter::DlBlendMode::kLighten: + return Entity::BlendMode::kLighten; case flutter::DlBlendMode::kColorDodge: + return Entity::BlendMode::kColorDodge; + case flutter::DlBlendMode::kColorBurn: + return Entity::BlendMode::kColorBurn; case flutter::DlBlendMode::kHardLight: + return Entity::BlendMode::kHardLight; case flutter::DlBlendMode::kSoftLight: + return Entity::BlendMode::kSoftLight; case flutter::DlBlendMode::kDifference: + return Entity::BlendMode::kDifference; case flutter::DlBlendMode::kExclusion: + return Entity::BlendMode::kExclusion; case flutter::DlBlendMode::kMultiply: + return Entity::BlendMode::kMultiply; case flutter::DlBlendMode::kHue: case flutter::DlBlendMode::kSaturation: case flutter::DlBlendMode::kColor: diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index f7f6d0988efd5..b15c495aa2214 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -16,6 +16,7 @@ impeller_shaders("entity_shaders") { "shaders/blending/advanced_blend_exclusion.frag", "shaders/blending/advanced_blend_hardlight.frag", "shaders/blending/advanced_blend_lighten.frag", + "shaders/blending/advanced_blend_multiply.frag", "shaders/blending/advanced_blend_overlay.frag", "shaders/blending/advanced_blend_screen.frag", "shaders/blending/advanced_blend_softlight.frag", diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index 2ccd0232f69e7..318ed476d8260 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -155,10 +155,28 @@ ContentContext::ContentContext(std::shared_ptr context) CreateDefaultPipeline(*context_); texture_blend_pipelines_[{}] = CreateDefaultPipeline(*context_); + blend_colorburn_pipelines_[{}] = + CreateDefaultPipeline(*context_); + blend_colordodge_pipelines_[{}] = + CreateDefaultPipeline(*context_); + blend_darken_pipelines_[{}] = + CreateDefaultPipeline(*context_); + blend_difference_pipelines_[{}] = + CreateDefaultPipeline(*context_); + blend_exclusion_pipelines_[{}] = + CreateDefaultPipeline(*context_); + blend_hardlight_pipelines_[{}] = + CreateDefaultPipeline(*context_); + blend_lighten_pipelines_[{}] = + CreateDefaultPipeline(*context_); + blend_multiply_pipelines_[{}] = + CreateDefaultPipeline(*context_); + blend_overlay_pipelines_[{}] = + CreateDefaultPipeline(*context_); blend_screen_pipelines_[{}] = CreateDefaultPipeline(*context_); - blend_colorburn_pipelines_[{}] = - CreateDefaultPipeline(*context_); + blend_softlight_pipelines_[{}] = + CreateDefaultPipeline(*context_); texture_pipelines_[{}] = CreateDefaultPipeline(*context_); gaussian_blur_pipelines_[{}] = CreateDefaultPipeline(*context_); diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 91c6bdbd9c253..3c26d738c8800 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -13,7 +13,16 @@ #include "impeller/base/validation.h" #include "impeller/entity/advanced_blend.vert.h" #include "impeller/entity/advanced_blend_colorburn.frag.h" +#include "impeller/entity/advanced_blend_colordodge.frag.h" +#include "impeller/entity/advanced_blend_darken.frag.h" +#include "impeller/entity/advanced_blend_difference.frag.h" +#include "impeller/entity/advanced_blend_exclusion.frag.h" +#include "impeller/entity/advanced_blend_hardlight.frag.h" +#include "impeller/entity/advanced_blend_lighten.frag.h" +#include "impeller/entity/advanced_blend_multiply.frag.h" +#include "impeller/entity/advanced_blend_overlay.frag.h" #include "impeller/entity/advanced_blend_screen.frag.h" +#include "impeller/entity/advanced_blend_softlight.frag.h" #include "impeller/entity/blend.frag.h" #include "impeller/entity/blend.vert.h" #include "impeller/entity/border_mask_blur.frag.h" @@ -42,10 +51,28 @@ using GradientFillPipeline = using SolidFillPipeline = PipelineT; using BlendPipeline = PipelineT; +using BlendColorBurnPipeline = + PipelineT; +using BlendColorDodgePipeline = + PipelineT; +using BlendDarkenPipeline = + PipelineT; +using BlendDifferencePipeline = + PipelineT; +using BlendExclusionPipeline = + PipelineT; +using BlendHardLightPipeline = + PipelineT; +using BlendLightenPipeline = + PipelineT; +using BlendMultiplyPipeline = + PipelineT; +using BlendOverlayPipeline = + PipelineT; using BlendScreenPipeline = PipelineT; -using BlendColorburnPipeline = - PipelineT; +using BlendSoftLightPipeline = + PipelineT; using TexturePipeline = PipelineT; using GaussianBlurPipeline = @@ -110,16 +137,6 @@ class ContentContext { return GetPipeline(texture_blend_pipelines_, opts); } - std::shared_ptr GetBlendScreenPipeline( - ContentContextOptions opts) const { - return GetPipeline(blend_screen_pipelines_, opts); - } - - std::shared_ptr GetBlendColorburnPipeline( - ContentContextOptions opts) const { - return GetPipeline(blend_colorburn_pipelines_, opts); - } - std::shared_ptr GetTexturePipeline( ContentContextOptions opts) const { return GetPipeline(texture_pipelines_, opts); @@ -154,6 +171,63 @@ class ContentContext { return GetPipeline(vertices_pipelines_, opts); } + // Advanced blends. + + std::shared_ptr GetBlendColorBurnPipeline( + ContentContextOptions opts) const { + return GetPipeline(blend_colorburn_pipelines_, opts); + } + + std::shared_ptr GetBlendColorDodgePipeline( + ContentContextOptions opts) const { + return GetPipeline(blend_colordodge_pipelines_, opts); + } + + std::shared_ptr GetBlendDarkenPipeline( + ContentContextOptions opts) const { + return GetPipeline(blend_darken_pipelines_, opts); + } + + std::shared_ptr GetBlendDifferencePipeline( + ContentContextOptions opts) const { + return GetPipeline(blend_difference_pipelines_, opts); + } + + std::shared_ptr GetBlendExclusionPipeline( + ContentContextOptions opts) const { + return GetPipeline(blend_exclusion_pipelines_, opts); + } + + std::shared_ptr GetBlendHardLightPipeline( + ContentContextOptions opts) const { + return GetPipeline(blend_hardlight_pipelines_, opts); + } + + std::shared_ptr GetBlendLightenPipeline( + ContentContextOptions opts) const { + return GetPipeline(blend_lighten_pipelines_, opts); + } + + std::shared_ptr GetBlendMultiplyPipeline( + ContentContextOptions opts) const { + return GetPipeline(blend_multiply_pipelines_, opts); + } + + std::shared_ptr GetBlendOverlayPipeline( + ContentContextOptions opts) const { + return GetPipeline(blend_overlay_pipelines_, opts); + } + + std::shared_ptr GetBlendScreenPipeline( + ContentContextOptions opts) const { + return GetPipeline(blend_screen_pipelines_, opts); + } + + std::shared_ptr GetBlendSoftLightPipeline( + ContentContextOptions opts) const { + return GetPipeline(blend_softlight_pipelines_, opts); + } + std::shared_ptr GetContext() const; using SubpassCallback = @@ -179,8 +253,6 @@ class ContentContext { mutable Variants gradient_fill_pipelines_; mutable Variants solid_fill_pipelines_; mutable Variants texture_blend_pipelines_; - mutable Variants blend_screen_pipelines_; - mutable Variants blend_colorburn_pipelines_; mutable Variants texture_pipelines_; mutable Variants gaussian_blur_pipelines_; mutable Variants border_mask_blur_pipelines_; @@ -188,6 +260,18 @@ class ContentContext { mutable Variants clip_pipelines_; mutable Variants glyph_atlas_pipelines_; mutable Variants vertices_pipelines_; + // Advanced blends. + mutable Variants blend_colorburn_pipelines_; + mutable Variants blend_colordodge_pipelines_; + mutable Variants blend_darken_pipelines_; + mutable Variants blend_difference_pipelines_; + mutable Variants blend_exclusion_pipelines_; + mutable Variants blend_hardlight_pipelines_; + mutable Variants blend_lighten_pipelines_; + mutable Variants blend_multiply_pipelines_; + mutable Variants blend_overlay_pipelines_; + mutable Variants blend_screen_pipelines_; + mutable Variants blend_softlight_pipelines_; template std::shared_ptr GetPipeline(Variants& container, diff --git a/impeller/entity/contents/filters/blend_filter_contents.cc b/impeller/entity/contents/filters/blend_filter_contents.cc index d108b65abde49..1c0988c8969e2 100644 --- a/impeller/entity/contents/filters/blend_filter_contents.cc +++ b/impeller/entity/contents/filters/blend_filter_contents.cc @@ -216,6 +216,18 @@ static bool PipelineBlend(const FilterInput::Vector& inputs, return true; } +#define BLEND_CASE(mode) \ + case Entity::BlendMode::k##mode: \ + advanced_blend_proc_ = \ + [](const FilterInput::Vector& inputs, const ContentContext& renderer, \ + const Entity& entity, RenderPass& pass, const Rect& coverage, \ + std::optional fg_color) { \ + PipelineProc p = &ContentContext::GetBlend##mode##Pipeline; \ + return AdvancedBlend( \ + inputs, renderer, entity, pass, coverage, fg_color, p); \ + }; \ + break; + void BlendFilterContents::SetBlendMode(Entity::BlendMode blend_mode) { if (blend_mode > Entity::BlendMode::kLastAdvancedBlendMode) { VALIDATION_LOG << "Invalid blend mode " << static_cast(blend_mode) @@ -226,31 +238,20 @@ void BlendFilterContents::SetBlendMode(Entity::BlendMode blend_mode) { if (blend_mode > Entity::BlendMode::kLastPipelineBlendMode) { static_assert(Entity::BlendMode::kLastAdvancedBlendMode == - Entity::BlendMode::kColorBurn); + Entity::BlendMode::kMultiply); switch (blend_mode) { - case Entity::BlendMode::kScreen: - advanced_blend_proc_ = [](const FilterInput::Vector& inputs, - const ContentContext& renderer, - const Entity& entity, RenderPass& pass, - const Rect& coverage, - std::optional fg_color) { - PipelineProc p = &ContentContext::GetBlendScreenPipeline; - return AdvancedBlend( - inputs, renderer, entity, pass, coverage, fg_color, p); - }; - break; - case Entity::BlendMode::kColorBurn: - advanced_blend_proc_ = [](const FilterInput::Vector& inputs, - const ContentContext& renderer, - const Entity& entity, RenderPass& pass, - const Rect& coverage, - std::optional fg_color) { - PipelineProc p = &ContentContext::GetBlendColorburnPipeline; - return AdvancedBlend( - inputs, renderer, entity, pass, coverage, fg_color, p); - }; - break; + BLEND_CASE(Screen) + BLEND_CASE(Overlay) + BLEND_CASE(Darken) + BLEND_CASE(Lighten) + BLEND_CASE(ColorDodge) + BLEND_CASE(ColorBurn) + BLEND_CASE(HardLight) + BLEND_CASE(SoftLight) + BLEND_CASE(Difference) + BLEND_CASE(Exclusion) + BLEND_CASE(Multiply) default: FML_UNREACHABLE(); } diff --git a/impeller/entity/entity.h b/impeller/entity/entity.h index f1fea96b3e7b6..dec0c15605dd8 100644 --- a/impeller/entity/entity.h +++ b/impeller/entity/entity.h @@ -43,10 +43,19 @@ class Entity { // pipelines on most graphics devices without extensions, and so they are // only able to be used via `BlendFilterContents`. kScreen, + kOverlay, + kDarken, + kLighten, + kColorDodge, kColorBurn, + kHardLight, + kSoftLight, + kDifference, + kExclusion, + kMultiply, kLastPipelineBlendMode = kModulate, - kLastAdvancedBlendMode = kColorBurn, + kLastAdvancedBlendMode = kMultiply, }; enum class ClipOperation { diff --git a/impeller/entity/shaders/blending/advanced_blend_colordodge.frag b/impeller/entity/shaders/blending/advanced_blend_colordodge.frag index 1f4294c4bea00..e59e14e638346 100644 --- a/impeller/entity/shaders/blending/advanced_blend_colordodge.frag +++ b/impeller/entity/shaders/blending/advanced_blend_colordodge.frag @@ -6,8 +6,8 @@ vec3 Blend(vec3 dst, vec3 src) { vec3 color = min(vec3(1), dst / (1 - src)); - color = mix(color, vec3(1), ComponentIsValue(dst, 1.0)); - color = mix(color, vec3(0), ComponentIsValue(src, 0.0)); + color = mix(color, vec3(0), ComponentIsValue(dst, 0.0)); + color = mix(color, vec3(1), ComponentIsValue(src, 1.0)); return color; } diff --git a/impeller/entity/shaders/blending/advanced_blend_multiply.frag b/impeller/entity/shaders/blending/advanced_blend_multiply.frag new file mode 100644 index 0000000000000..d8b89cefa8580 --- /dev/null +++ b/impeller/entity/shaders/blending/advanced_blend_multiply.frag @@ -0,0 +1,9 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +vec3 Blend(vec3 dst, vec3 src) { + return dst * src; +} + +#include "advanced_blend.glsl" diff --git a/impeller/entity/shaders/blending/advanced_blend_softlight.frag b/impeller/entity/shaders/blending/advanced_blend_softlight.frag index ee893aedd69ca..ae3bf7349ed84 100644 --- a/impeller/entity/shaders/blending/advanced_blend_softlight.frag +++ b/impeller/entity/shaders/blending/advanced_blend_softlight.frag @@ -5,9 +5,10 @@ #include "advanced_blend_utils.glsl" vec3 Blend(vec3 dst, vec3 src) { - vec3 D = mix(((16 * dst - 12) * dst + 4) * dst, // - sqrt(dst), // - 0.25); + vec3 D = MixComponents(((16 * dst - 12) * dst + 4) * dst, // + sqrt(dst), // + dst, // + 0.25); return MixHalf(dst - (1 - 2 * src) * dst * (1 - dst), // dst + (2 * src - 1) * (D - dst), // diff --git a/impeller/entity/shaders/blending/advanced_blend_utils.glsl b/impeller/entity/shaders/blending/advanced_blend_utils.glsl index f35a3c6f82664..94ec9b6e03e66 100644 --- a/impeller/entity/shaders/blending/advanced_blend_utils.glsl +++ b/impeller/entity/shaders/blending/advanced_blend_utils.glsl @@ -3,7 +3,8 @@ // found in the LICENSE file. vec3 ComponentIsValue(vec3 n, float value) { - return vec3(n.r == value, n.g == value, n.b == value); + vec3 diff = abs(n - value); + return vec3(diff.r < 0.0001, diff.g < 0.0001, diff.b < 0.0001); } vec3 MixComponents(vec3 a, vec3 b, vec3 weight, float cutoff) { From dc06b6f00d007c6f150df555219d7d735ace4c2d Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Fri, 3 Jun 2022 17:28:24 -0700 Subject: [PATCH 3/4] Licenses --- ci/licenses_golden/licenses_flutter | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index e034878aaf2d7..36079fa1b8430 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -570,7 +570,17 @@ FILE: ../../../flutter/impeller/entity/entity_unittests.cc FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.glsl FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.vert FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_colorburn.frag +FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_colordodge.frag +FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_darken.frag +FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_difference.frag +FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_exclusion.frag +FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_hardlight.frag +FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_lighten.frag +FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_multiply.frag +FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_overlay.frag FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_screen.frag +FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_softlight.frag +FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_utils.glsl FILE: ../../../flutter/impeller/entity/shaders/blending/blend.frag FILE: ../../../flutter/impeller/entity/shaders/blending/blend.vert FILE: ../../../flutter/impeller/entity/shaders/border_mask_blur.frag From ae5cb9d04f6bfea2782df55264ebc49b30291fa9 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Fri, 3 Jun 2022 18:59:16 -0700 Subject: [PATCH 4/4] address comments --- impeller/entity/shaders/blending/advanced_blend_colorburn.frag | 1 + impeller/entity/shaders/blending/advanced_blend_colordodge.frag | 1 + impeller/entity/shaders/blending/advanced_blend_darken.frag | 1 + impeller/entity/shaders/blending/advanced_blend_difference.frag | 1 + impeller/entity/shaders/blending/advanced_blend_exclusion.frag | 1 + impeller/entity/shaders/blending/advanced_blend_hardlight.frag | 2 +- impeller/entity/shaders/blending/advanced_blend_lighten.frag | 1 + impeller/entity/shaders/blending/advanced_blend_multiply.frag | 1 + impeller/entity/shaders/blending/advanced_blend_overlay.frag | 1 + impeller/entity/shaders/blending/advanced_blend_screen.frag | 1 + impeller/entity/shaders/blending/advanced_blend_softlight.frag | 2 ++ 11 files changed, 12 insertions(+), 1 deletion(-) diff --git a/impeller/entity/shaders/blending/advanced_blend_colorburn.frag b/impeller/entity/shaders/blending/advanced_blend_colorburn.frag index ca39e490e0577..3449f5d6e9c49 100644 --- a/impeller/entity/shaders/blending/advanced_blend_colorburn.frag +++ b/impeller/entity/shaders/blending/advanced_blend_colorburn.frag @@ -5,6 +5,7 @@ #include "advanced_blend_utils.glsl" vec3 Blend(vec3 dst, vec3 src) { + // https://www.w3.org/TR/compositing-1/#blendingcolorburn vec3 color = 1 - min(vec3(1), (1 - dst) / src); color = mix(color, vec3(1), ComponentIsValue(dst, 1.0)); color = mix(color, vec3(0), ComponentIsValue(src, 0.0)); diff --git a/impeller/entity/shaders/blending/advanced_blend_colordodge.frag b/impeller/entity/shaders/blending/advanced_blend_colordodge.frag index e59e14e638346..6fca72bea7990 100644 --- a/impeller/entity/shaders/blending/advanced_blend_colordodge.frag +++ b/impeller/entity/shaders/blending/advanced_blend_colordodge.frag @@ -5,6 +5,7 @@ #include "advanced_blend_utils.glsl" vec3 Blend(vec3 dst, vec3 src) { + // https://www.w3.org/TR/compositing-1/#blendingcolordodge vec3 color = min(vec3(1), dst / (1 - src)); color = mix(color, vec3(0), ComponentIsValue(dst, 0.0)); color = mix(color, vec3(1), ComponentIsValue(src, 1.0)); diff --git a/impeller/entity/shaders/blending/advanced_blend_darken.frag b/impeller/entity/shaders/blending/advanced_blend_darken.frag index ca7ff86c16012..bfc8cb20e22b9 100644 --- a/impeller/entity/shaders/blending/advanced_blend_darken.frag +++ b/impeller/entity/shaders/blending/advanced_blend_darken.frag @@ -3,6 +3,7 @@ // found in the LICENSE file. vec3 Blend(vec3 dst, vec3 src) { + // https://www.w3.org/TR/compositing-1/#blendingdarken return min(dst, src); } diff --git a/impeller/entity/shaders/blending/advanced_blend_difference.frag b/impeller/entity/shaders/blending/advanced_blend_difference.frag index 6332866914736..7545bc08b55cd 100644 --- a/impeller/entity/shaders/blending/advanced_blend_difference.frag +++ b/impeller/entity/shaders/blending/advanced_blend_difference.frag @@ -3,6 +3,7 @@ // found in the LICENSE file. vec3 Blend(vec3 dst, vec3 src) { + // https://www.w3.org/TR/compositing-1/#blendingdifference return abs(dst - src); } diff --git a/impeller/entity/shaders/blending/advanced_blend_exclusion.frag b/impeller/entity/shaders/blending/advanced_blend_exclusion.frag index 165f8287cb0e5..a12e47e3d043b 100644 --- a/impeller/entity/shaders/blending/advanced_blend_exclusion.frag +++ b/impeller/entity/shaders/blending/advanced_blend_exclusion.frag @@ -3,6 +3,7 @@ // found in the LICENSE file. vec3 Blend(vec3 dst, vec3 src) { + // https://www.w3.org/TR/compositing-1/#blendingexclusion return dst + src - 2 * dst * src; } diff --git a/impeller/entity/shaders/blending/advanced_blend_hardlight.frag b/impeller/entity/shaders/blending/advanced_blend_hardlight.frag index 16975d3cb8ae7..186f5ecbcdef8 100644 --- a/impeller/entity/shaders/blending/advanced_blend_hardlight.frag +++ b/impeller/entity/shaders/blending/advanced_blend_hardlight.frag @@ -8,4 +8,4 @@ vec3 Blend(vec3 dst, vec3 src) { return BlendHardLight(dst, src); } -#include "advanced_blend.glsl" \ No newline at end of file +#include "advanced_blend.glsl" diff --git a/impeller/entity/shaders/blending/advanced_blend_lighten.frag b/impeller/entity/shaders/blending/advanced_blend_lighten.frag index 2891754cc06dd..1aca8cc4b7fcd 100644 --- a/impeller/entity/shaders/blending/advanced_blend_lighten.frag +++ b/impeller/entity/shaders/blending/advanced_blend_lighten.frag @@ -3,6 +3,7 @@ // found in the LICENSE file. vec3 Blend(vec3 dst, vec3 src) { + // https://www.w3.org/TR/compositing-1/#blendinglighten return max(dst, src); } diff --git a/impeller/entity/shaders/blending/advanced_blend_multiply.frag b/impeller/entity/shaders/blending/advanced_blend_multiply.frag index d8b89cefa8580..92656d23fa0a7 100644 --- a/impeller/entity/shaders/blending/advanced_blend_multiply.frag +++ b/impeller/entity/shaders/blending/advanced_blend_multiply.frag @@ -3,6 +3,7 @@ // found in the LICENSE file. vec3 Blend(vec3 dst, vec3 src) { + // https://www.w3.org/TR/compositing-1/#blendingmultiply return dst * src; } diff --git a/impeller/entity/shaders/blending/advanced_blend_overlay.frag b/impeller/entity/shaders/blending/advanced_blend_overlay.frag index d822569d551c7..d6197f1103147 100644 --- a/impeller/entity/shaders/blending/advanced_blend_overlay.frag +++ b/impeller/entity/shaders/blending/advanced_blend_overlay.frag @@ -5,6 +5,7 @@ #include "advanced_blend_utils.glsl" vec3 Blend(vec3 dst, vec3 src) { + // https://www.w3.org/TR/compositing-1/#blendinghardlight // HardLight, but with reversed parameters. return BlendHardLight(src, dst); } diff --git a/impeller/entity/shaders/blending/advanced_blend_screen.frag b/impeller/entity/shaders/blending/advanced_blend_screen.frag index a3a941215ce25..7f059766abcf7 100644 --- a/impeller/entity/shaders/blending/advanced_blend_screen.frag +++ b/impeller/entity/shaders/blending/advanced_blend_screen.frag @@ -5,6 +5,7 @@ #include "advanced_blend_utils.glsl" vec3 Blend(vec3 dst, vec3 src) { + // https://www.w3.org/TR/compositing-1/#blendingscreen return BlendScreen(dst, src); } diff --git a/impeller/entity/shaders/blending/advanced_blend_softlight.frag b/impeller/entity/shaders/blending/advanced_blend_softlight.frag index ae3bf7349ed84..e646a304054d9 100644 --- a/impeller/entity/shaders/blending/advanced_blend_softlight.frag +++ b/impeller/entity/shaders/blending/advanced_blend_softlight.frag @@ -5,6 +5,8 @@ #include "advanced_blend_utils.glsl" vec3 Blend(vec3 dst, vec3 src) { + // https://www.w3.org/TR/compositing-1/#blendingsoftlight + vec3 D = MixComponents(((16 * dst - 12) * dst + 4) * dst, // sqrt(dst), // dst, //