Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 27 additions & 21 deletions impeller/entity/contents/filters/blend_filter_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
#include <memory>
#include <optional>

#include "impeller/base/strings.h"
#include "impeller/core/formats.h"
#include "impeller/entity/contents/anonymous_contents.h"
#include "impeller/entity/contents/content_context.h"
#include "impeller/entity/contents/contents.h"
#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"
Expand All @@ -37,6 +39,7 @@ static std::optional<Entity> AdvancedBlend(
const ContentContext& renderer,
const Entity& entity,
const Rect& coverage,
BlendMode blend_mode,
std::optional<Color> foreground_color,
bool absorb_opacity,
PipelineProc pipeline_proc,
Expand Down Expand Up @@ -114,7 +117,8 @@ static std::optional<Entity> 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);

Expand Down Expand Up @@ -228,7 +232,8 @@ std::optional<Entity> 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);
Expand Down Expand Up @@ -413,7 +418,8 @@ std::optional<Entity> 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);
Expand Down Expand Up @@ -475,7 +481,7 @@ static std::optional<Entity> PipelineBlend(
const ContentContext& renderer,
const Entity& entity,
const Rect& coverage,
BlendMode pipeline_blend,
BlendMode blend_mode,
std::optional<Color> foreground_color,
bool absorb_opacity,
std::optional<Scalar> alpha) {
Expand All @@ -493,7 +499,8 @@ static std::optional<Entity> 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<Snapshot> input) {
Expand Down Expand Up @@ -548,7 +555,7 @@ static std::optional<Entity> 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();
Expand All @@ -570,7 +577,7 @@ static std::optional<Entity> 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;
Expand Down Expand Up @@ -598,19 +605,18 @@ static std::optional<Entity> 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<Color> fg_color, \
bool absorb_opacity, \
std::optional<Scalar> alpha) { \
PipelineProc p = &ContentContext::GetBlend##mode##Pipeline; \
return AdvancedBlend<Blend##mode##Pipeline>(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<Color> fg_color, bool absorb_opacity, \
std::optional<Scalar> alpha) { \
PipelineProc p = &ContentContext::GetBlend##mode##Pipeline; \
return AdvancedBlend<Blend##mode##Pipeline>( \
inputs, renderer, entity, coverage, blend_mode, fg_color, \
absorb_opacity, p, alpha); \
}; \
break;

void BlendFilterContents::SetBlendMode(BlendMode blend_mode) {
Expand Down Expand Up @@ -683,7 +689,7 @@ std::optional<Entity> 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());
}
Expand Down
1 change: 1 addition & 0 deletions impeller/entity/contents/filters/blend_filter_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class BlendFilterContents : public ColorFilterContents {
const ContentContext& renderer,
const Entity& entity,
const Rect& coverage,
BlendMode blend_mode,
std::optional<Color> foreground_color,
bool absorb_opacity,
std::optional<Scalar> alpha)>;
Expand Down
11 changes: 11 additions & 0 deletions impeller/geometry/color.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <algorithm>
#include <cmath>
#include <sstream>
#include <type_traits>

#include "impeller/base/strings.h"
#include "impeller/geometry/constants.h"
Expand Down Expand Up @@ -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<std::underlying_type_t<BlendMode>>(
blend_mode)];
}

ColorHSB ColorHSB::FromRGB(Color rgb) {
Scalar R = rgb.red;
Scalar G = rgb.green;
Expand Down
4 changes: 3 additions & 1 deletion impeller/geometry/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -91,6 +91,8 @@ enum class BlendMode {
kLast = kLuminosity,
};

const char* BlendModeToString(BlendMode blend_mode);

/**
* Represents a RGBA color
*/
Expand Down
16 changes: 16 additions & 0 deletions impeller/geometry/geometry_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@

#include <limits>
#include <sstream>
#include <type_traits>

#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"
Expand Down Expand Up @@ -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<BlendMode>;
for (BlendT i = 0; i <= static_cast<BlendT>(BlendMode::kLast); i++) {
auto mode = static_cast<BlendMode>(i);
auto result = BlendModeToString(mode);
switch (mode) { IMPELLER_FOR_EACH_BLEND_MODE(_BLEND_MODE_NAME_CHECK) }
}
}

TEST(GeometryTest, CanConvertBetweenDegressAndRadians) {
{
auto deg = Degrees{90.0};
Expand Down