Skip to content

Commit 98c3632

Browse files
authored
[Impeller] Specify blend mode on blend filter commands (flutter#42676)
Side quest of flutter#127232. This is particularly useful for debugging pipeline blend variations of the blend filter, since we otherwise have to look at the raw pipeline blend ops and figure out and piece together what the blend mode must've been.
1 parent 95d5f91 commit 98c3632

File tree

5 files changed

+58
-22
lines changed

5 files changed

+58
-22
lines changed

impeller/entity/contents/filters/blend_filter_contents.cc

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
#include <memory>
99
#include <optional>
1010

11+
#include "impeller/base/strings.h"
1112
#include "impeller/core/formats.h"
1213
#include "impeller/entity/contents/anonymous_contents.h"
1314
#include "impeller/entity/contents/content_context.h"
1415
#include "impeller/entity/contents/contents.h"
1516
#include "impeller/entity/contents/filters/inputs/filter_input.h"
1617
#include "impeller/entity/contents/solid_color_contents.h"
1718
#include "impeller/entity/entity.h"
19+
#include "impeller/geometry/color.h"
1820
#include "impeller/geometry/path_builder.h"
1921
#include "impeller/renderer/render_pass.h"
2022
#include "impeller/renderer/sampler_library.h"
@@ -37,6 +39,7 @@ static std::optional<Entity> AdvancedBlend(
3739
const ContentContext& renderer,
3840
const Entity& entity,
3941
const Rect& coverage,
42+
BlendMode blend_mode,
4043
std::optional<Color> foreground_color,
4144
bool absorb_opacity,
4245
PipelineProc pipeline_proc,
@@ -114,7 +117,8 @@ static std::optional<Entity> AdvancedBlend(
114117
std::invoke(pipeline_proc, renderer, options);
115118

116119
Command cmd;
117-
cmd.label = "Advanced Blend Filter";
120+
cmd.label =
121+
SPrintF("Advanced Blend Filter (%s)", BlendModeToString(blend_mode));
118122
cmd.BindVertices(vtx_buffer);
119123
cmd.pipeline = std::move(pipeline);
120124

@@ -228,7 +232,8 @@ std::optional<Entity> BlendFilterContents::CreateForegroundAdvancedBlend(
228232
auto vtx_buffer = vtx_builder.CreateVertexBuffer(host_buffer);
229233

230234
Command cmd;
231-
cmd.label = "Foreground Advanced Blend Filter";
235+
cmd.label = SPrintF("Foreground Advanced Blend Filter (%s)",
236+
BlendModeToString(blend_mode));
232237
cmd.BindVertices(vtx_buffer);
233238
cmd.stencil_reference = entity.GetStencilDepth();
234239
auto options = OptionsFromPass(pass);
@@ -413,7 +418,8 @@ std::optional<Entity> BlendFilterContents::CreateForegroundPorterDuffBlend(
413418
auto vtx_buffer = vtx_builder.CreateVertexBuffer(host_buffer);
414419

415420
Command cmd;
416-
cmd.label = "Foreground PorterDuff Blend Filter";
421+
cmd.label = SPrintF("Foreground PorterDuff Blend Filter (%s)",
422+
BlendModeToString(blend_mode));
417423
cmd.BindVertices(vtx_buffer);
418424
cmd.stencil_reference = entity.GetStencilDepth();
419425
auto options = OptionsFromPass(pass);
@@ -475,7 +481,7 @@ static std::optional<Entity> PipelineBlend(
475481
const ContentContext& renderer,
476482
const Entity& entity,
477483
const Rect& coverage,
478-
BlendMode pipeline_blend,
484+
BlendMode blend_mode,
479485
std::optional<Color> foreground_color,
480486
bool absorb_opacity,
481487
std::optional<Scalar> alpha) {
@@ -493,7 +499,8 @@ static std::optional<Entity> PipelineBlend(
493499
auto& host_buffer = pass.GetTransientsBuffer();
494500

495501
Command cmd;
496-
cmd.label = "Pipeline Blend Filter";
502+
cmd.label =
503+
SPrintF("Pipeline Blend Filter (%s)", BlendModeToString(blend_mode));
497504
auto options = OptionsFromPass(pass);
498505

499506
auto add_blend_command = [&](std::optional<Snapshot> input) {
@@ -548,7 +555,7 @@ static std::optional<Entity> PipelineBlend(
548555
// Write subsequent textures using the selected blend mode.
549556

550557
if (inputs.size() >= 2) {
551-
options.blend_mode = pipeline_blend;
558+
options.blend_mode = blend_mode;
552559
cmd.pipeline = renderer.GetBlendPipeline(options);
553560

554561
for (auto texture_i = inputs.begin() + 1; texture_i < inputs.end();
@@ -570,7 +577,7 @@ static std::optional<Entity> PipelineBlend(
570577
contents->SetColor(foreground_color.value());
571578

572579
Entity foreground_entity;
573-
foreground_entity.SetBlendMode(pipeline_blend);
580+
foreground_entity.SetBlendMode(blend_mode);
574581
foreground_entity.SetContents(contents);
575582
if (!foreground_entity.Render(renderer, pass)) {
576583
return false;
@@ -598,19 +605,18 @@ static std::optional<Entity> PipelineBlend(
598605
entity.GetBlendMode(), entity.GetStencilDepth());
599606
}
600607

601-
#define BLEND_CASE(mode) \
602-
case BlendMode::k##mode: \
603-
advanced_blend_proc_ = [](const FilterInput::Vector& inputs, \
604-
const ContentContext& renderer, \
605-
const Entity& entity, const Rect& coverage, \
606-
std::optional<Color> fg_color, \
607-
bool absorb_opacity, \
608-
std::optional<Scalar> alpha) { \
609-
PipelineProc p = &ContentContext::GetBlend##mode##Pipeline; \
610-
return AdvancedBlend<Blend##mode##Pipeline>(inputs, renderer, entity, \
611-
coverage, fg_color, \
612-
absorb_opacity, p, alpha); \
613-
}; \
608+
#define BLEND_CASE(mode) \
609+
case BlendMode::k##mode: \
610+
advanced_blend_proc_ = \
611+
[](const FilterInput::Vector& inputs, const ContentContext& renderer, \
612+
const Entity& entity, const Rect& coverage, BlendMode blend_mode, \
613+
std::optional<Color> fg_color, bool absorb_opacity, \
614+
std::optional<Scalar> alpha) { \
615+
PipelineProc p = &ContentContext::GetBlend##mode##Pipeline; \
616+
return AdvancedBlend<Blend##mode##Pipeline>( \
617+
inputs, renderer, entity, coverage, blend_mode, fg_color, \
618+
absorb_opacity, p, alpha); \
619+
}; \
614620
break;
615621

616622
void BlendFilterContents::SetBlendMode(BlendMode blend_mode) {
@@ -683,7 +689,7 @@ std::optional<Entity> BlendFilterContents::RenderFilter(
683689
inputs[0], renderer, entity, coverage, foreground_color_.value(),
684690
blend_mode_, GetAlpha(), GetAbsorbOpacity());
685691
}
686-
return advanced_blend_proc_(inputs, renderer, entity, coverage,
692+
return advanced_blend_proc_(inputs, renderer, entity, coverage, blend_mode_,
687693
foreground_color_, GetAbsorbOpacity(),
688694
GetAlpha());
689695
}

impeller/entity/contents/filters/blend_filter_contents.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class BlendFilterContents : public ColorFilterContents {
1616
const ContentContext& renderer,
1717
const Entity& entity,
1818
const Rect& coverage,
19+
BlendMode blend_mode,
1920
std::optional<Color> foreground_color,
2021
bool absorb_opacity,
2122
std::optional<Scalar> alpha)>;

impeller/geometry/color.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <algorithm>
88
#include <cmath>
99
#include <sstream>
10+
#include <type_traits>
1011

1112
#include "impeller/base/strings.h"
1213
#include "impeller/geometry/constants.h"
@@ -37,6 +38,16 @@ static constexpr inline bool ValidateBlendModes() {
3738
static_assert(ValidateBlendModes(),
3839
"IMPELLER_FOR_EACH_BLEND_MODE must match impeller::BlendMode.");
3940

41+
#define _IMPELLER_BLEND_MODE_NAME_LIST(blend_mode) #blend_mode,
42+
43+
static constexpr const char* kBlendModeNames[] = {
44+
IMPELLER_FOR_EACH_BLEND_MODE(_IMPELLER_BLEND_MODE_NAME_LIST)};
45+
46+
const char* BlendModeToString(BlendMode blend_mode) {
47+
return kBlendModeNames[static_cast<std::underlying_type_t<BlendMode>>(
48+
blend_mode)];
49+
}
50+
4051
ColorHSB ColorHSB::FromRGB(Color rgb) {
4152
Scalar R = rgb.red;
4253
Scalar G = rgb.green;

impeller/geometry/color.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ enum class YUVColorSpace { kBT601LimitedRange, kBT601FullRange };
5454
enum class BlendMode {
5555
// The following blend modes are able to be used as pipeline blend modes or
5656
// via `BlendFilterContents`.
57-
kClear,
57+
kClear = 0,
5858
kSource,
5959
kDestination,
6060
kSourceOver,
@@ -91,6 +91,8 @@ enum class BlendMode {
9191
kLast = kLuminosity,
9292
};
9393

94+
const char* BlendModeToString(BlendMode blend_mode);
95+
9496
/**
9597
* Represents a RGBA color
9698
*/

impeller/geometry/geometry_unittests.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66

77
#include <limits>
88
#include <sstream>
9+
#include <type_traits>
910

1011
#include "flutter/fml/build_config.h"
1112
#include "flutter/testing/testing.h"
13+
#include "impeller/geometry/color.h"
1214
#include "impeller/geometry/constants.h"
1315
#include "impeller/geometry/gradient.h"
1416
#include "impeller/geometry/half.h"
@@ -1446,6 +1448,20 @@ TEST(GeometryTest, ColorMakeRGBA8) {
14461448
}
14471449
}
14481450

1451+
#define _BLEND_MODE_NAME_CHECK(blend_mode) \
1452+
case BlendMode::k##blend_mode: \
1453+
ASSERT_STREQ(result, #blend_mode); \
1454+
break;
1455+
1456+
TEST(GeometryTest, BlendModeToString) {
1457+
using BlendT = std::underlying_type_t<BlendMode>;
1458+
for (BlendT i = 0; i <= static_cast<BlendT>(BlendMode::kLast); i++) {
1459+
auto mode = static_cast<BlendMode>(i);
1460+
auto result = BlendModeToString(mode);
1461+
switch (mode) { IMPELLER_FOR_EACH_BLEND_MODE(_BLEND_MODE_NAME_CHECK) }
1462+
}
1463+
}
1464+
14491465
TEST(GeometryTest, CanConvertBetweenDegressAndRadians) {
14501466
{
14511467
auto deg = Degrees{90.0};

0 commit comments

Comments
 (0)