From d63c2ee3d004a2151660c9d863cb9309b15b6e34 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 8 Jun 2023 13:33:36 -0700 Subject: [PATCH] [Impeller] Specify blend mode on blend filter commands --- .../contents/filters/blend_filter_contents.cc | 48 +++++++++++-------- .../contents/filters/blend_filter_contents.h | 1 + impeller/geometry/color.cc | 11 +++++ impeller/geometry/color.h | 4 +- impeller/geometry/geometry_unittests.cc | 16 +++++++ 5 files changed, 58 insertions(+), 22 deletions(-) diff --git a/impeller/entity/contents/filters/blend_filter_contents.cc b/impeller/entity/contents/filters/blend_filter_contents.cc index 287ec60ee3628..4fb81ce6fa80b 100644 --- a/impeller/entity/contents/filters/blend_filter_contents.cc +++ b/impeller/entity/contents/filters/blend_filter_contents.cc @@ -8,6 +8,7 @@ #include #include +#include "impeller/base/strings.h" #include "impeller/core/formats.h" #include "impeller/entity/contents/anonymous_contents.h" #include "impeller/entity/contents/content_context.h" @@ -15,6 +16,7 @@ #include "impeller/entity/contents/filters/inputs/filter_input.h" #include "impeller/entity/contents/solid_color_contents.h" #include "impeller/entity/entity.h" +#include "impeller/geometry/color.h" #include "impeller/geometry/path_builder.h" #include "impeller/renderer/render_pass.h" #include "impeller/renderer/sampler_library.h" @@ -37,6 +39,7 @@ static std::optional AdvancedBlend( const ContentContext& renderer, const Entity& entity, const Rect& coverage, + BlendMode blend_mode, std::optional foreground_color, bool absorb_opacity, PipelineProc pipeline_proc, @@ -114,7 +117,8 @@ static std::optional AdvancedBlend( std::invoke(pipeline_proc, renderer, options); Command cmd; - cmd.label = "Advanced Blend Filter"; + cmd.label = + SPrintF("Advanced Blend Filter (%s)", BlendModeToString(blend_mode)); cmd.BindVertices(vtx_buffer); cmd.pipeline = std::move(pipeline); @@ -228,7 +232,8 @@ std::optional BlendFilterContents::CreateForegroundAdvancedBlend( auto vtx_buffer = vtx_builder.CreateVertexBuffer(host_buffer); Command cmd; - cmd.label = "Foreground Advanced Blend Filter"; + cmd.label = SPrintF("Foreground Advanced Blend Filter (%s)", + BlendModeToString(blend_mode)); cmd.BindVertices(vtx_buffer); cmd.stencil_reference = entity.GetStencilDepth(); auto options = OptionsFromPass(pass); @@ -413,7 +418,8 @@ std::optional BlendFilterContents::CreateForegroundPorterDuffBlend( auto vtx_buffer = vtx_builder.CreateVertexBuffer(host_buffer); Command cmd; - cmd.label = "Foreground PorterDuff Blend Filter"; + cmd.label = SPrintF("Foreground PorterDuff Blend Filter (%s)", + BlendModeToString(blend_mode)); cmd.BindVertices(vtx_buffer); cmd.stencil_reference = entity.GetStencilDepth(); auto options = OptionsFromPass(pass); @@ -475,7 +481,7 @@ static std::optional PipelineBlend( const ContentContext& renderer, const Entity& entity, const Rect& coverage, - BlendMode pipeline_blend, + BlendMode blend_mode, std::optional foreground_color, bool absorb_opacity, std::optional alpha) { @@ -493,7 +499,8 @@ static std::optional PipelineBlend( auto& host_buffer = pass.GetTransientsBuffer(); Command cmd; - cmd.label = "Pipeline Blend Filter"; + cmd.label = + SPrintF("Pipeline Blend Filter (%s)", BlendModeToString(blend_mode)); auto options = OptionsFromPass(pass); auto add_blend_command = [&](std::optional input) { @@ -548,7 +555,7 @@ static std::optional PipelineBlend( // Write subsequent textures using the selected blend mode. if (inputs.size() >= 2) { - options.blend_mode = pipeline_blend; + options.blend_mode = blend_mode; cmd.pipeline = renderer.GetBlendPipeline(options); for (auto texture_i = inputs.begin() + 1; texture_i < inputs.end(); @@ -570,7 +577,7 @@ static std::optional PipelineBlend( contents->SetColor(foreground_color.value()); Entity foreground_entity; - foreground_entity.SetBlendMode(pipeline_blend); + foreground_entity.SetBlendMode(blend_mode); foreground_entity.SetContents(contents); if (!foreground_entity.Render(renderer, pass)) { return false; @@ -598,19 +605,18 @@ static std::optional PipelineBlend( entity.GetBlendMode(), entity.GetStencilDepth()); } -#define BLEND_CASE(mode) \ - case BlendMode::k##mode: \ - advanced_blend_proc_ = [](const FilterInput::Vector& inputs, \ - const ContentContext& renderer, \ - const Entity& entity, const Rect& coverage, \ - std::optional fg_color, \ - bool absorb_opacity, \ - std::optional alpha) { \ - PipelineProc p = &ContentContext::GetBlend##mode##Pipeline; \ - return AdvancedBlend(inputs, renderer, entity, \ - coverage, fg_color, \ - absorb_opacity, p, alpha); \ - }; \ +#define BLEND_CASE(mode) \ + case BlendMode::k##mode: \ + advanced_blend_proc_ = \ + [](const FilterInput::Vector& inputs, const ContentContext& renderer, \ + const Entity& entity, const Rect& coverage, BlendMode blend_mode, \ + std::optional fg_color, bool absorb_opacity, \ + std::optional alpha) { \ + PipelineProc p = &ContentContext::GetBlend##mode##Pipeline; \ + return AdvancedBlend( \ + inputs, renderer, entity, coverage, blend_mode, fg_color, \ + absorb_opacity, p, alpha); \ + }; \ break; void BlendFilterContents::SetBlendMode(BlendMode blend_mode) { @@ -683,7 +689,7 @@ std::optional BlendFilterContents::RenderFilter( inputs[0], renderer, entity, coverage, foreground_color_.value(), blend_mode_, GetAlpha(), GetAbsorbOpacity()); } - return advanced_blend_proc_(inputs, renderer, entity, coverage, + return advanced_blend_proc_(inputs, renderer, entity, coverage, blend_mode_, foreground_color_, GetAbsorbOpacity(), GetAlpha()); } diff --git a/impeller/entity/contents/filters/blend_filter_contents.h b/impeller/entity/contents/filters/blend_filter_contents.h index 01078e9aba143..fc602fb85da1a 100644 --- a/impeller/entity/contents/filters/blend_filter_contents.h +++ b/impeller/entity/contents/filters/blend_filter_contents.h @@ -16,6 +16,7 @@ class BlendFilterContents : public ColorFilterContents { const ContentContext& renderer, const Entity& entity, const Rect& coverage, + BlendMode blend_mode, std::optional foreground_color, bool absorb_opacity, std::optional alpha)>; diff --git a/impeller/geometry/color.cc b/impeller/geometry/color.cc index 17dd4f34ae138..d51ee111f5b4d 100644 --- a/impeller/geometry/color.cc +++ b/impeller/geometry/color.cc @@ -7,6 +7,7 @@ #include #include #include +#include #include "impeller/base/strings.h" #include "impeller/geometry/constants.h" @@ -37,6 +38,16 @@ static constexpr inline bool ValidateBlendModes() { static_assert(ValidateBlendModes(), "IMPELLER_FOR_EACH_BLEND_MODE must match impeller::BlendMode."); +#define _IMPELLER_BLEND_MODE_NAME_LIST(blend_mode) #blend_mode, + +static constexpr const char* kBlendModeNames[] = { + IMPELLER_FOR_EACH_BLEND_MODE(_IMPELLER_BLEND_MODE_NAME_LIST)}; + +const char* BlendModeToString(BlendMode blend_mode) { + return kBlendModeNames[static_cast>( + blend_mode)]; +} + ColorHSB ColorHSB::FromRGB(Color rgb) { Scalar R = rgb.red; Scalar G = rgb.green; diff --git a/impeller/geometry/color.h b/impeller/geometry/color.h index 99d491e8f4305..89fe96ef809f7 100644 --- a/impeller/geometry/color.h +++ b/impeller/geometry/color.h @@ -54,7 +54,7 @@ enum class YUVColorSpace { kBT601LimitedRange, kBT601FullRange }; enum class BlendMode { // The following blend modes are able to be used as pipeline blend modes or // via `BlendFilterContents`. - kClear, + kClear = 0, kSource, kDestination, kSourceOver, @@ -91,6 +91,8 @@ enum class BlendMode { kLast = kLuminosity, }; +const char* BlendModeToString(BlendMode blend_mode); + /** * Represents a RGBA color */ diff --git a/impeller/geometry/geometry_unittests.cc b/impeller/geometry/geometry_unittests.cc index 654cf8e6601da..951a405002373 100644 --- a/impeller/geometry/geometry_unittests.cc +++ b/impeller/geometry/geometry_unittests.cc @@ -6,9 +6,11 @@ #include #include +#include #include "flutter/fml/build_config.h" #include "flutter/testing/testing.h" +#include "impeller/geometry/color.h" #include "impeller/geometry/constants.h" #include "impeller/geometry/gradient.h" #include "impeller/geometry/half.h" @@ -1446,6 +1448,20 @@ TEST(GeometryTest, ColorMakeRGBA8) { } } +#define _BLEND_MODE_NAME_CHECK(blend_mode) \ + case BlendMode::k##blend_mode: \ + ASSERT_STREQ(result, #blend_mode); \ + break; + +TEST(GeometryTest, BlendModeToString) { + using BlendT = std::underlying_type_t; + for (BlendT i = 0; i <= static_cast(BlendMode::kLast); i++) { + auto mode = static_cast(i); + auto result = BlendModeToString(mode); + switch (mode) { IMPELLER_FOR_EACH_BLEND_MODE(_BLEND_MODE_NAME_CHECK) } + } +} + TEST(GeometryTest, CanConvertBetweenDegressAndRadians) { { auto deg = Degrees{90.0};