Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 44f856a

Browse files
committed
Add colorburn blend mode
1 parent 4596e39 commit 44f856a

14 files changed

+111
-51
lines changed

impeller/aiks/aiks_unittests.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ TEST_P(AiksTest, CanDrawWithAdvancedBlend) {
493493
{"Modulate", Entity::BlendMode::kModulate},
494494
// Advanced blends (non Porter-Duff/color blends)
495495
{"Screen", Entity::BlendMode::kScreen},
496+
{"ColorBurn", Entity::BlendMode::kColorBurn},
496497
};
497498
assert(blends.size() ==
498499
static_cast<size_t>(Entity::BlendMode::kLastAdvancedBlendMode) + 1);

impeller/blobcat/blob.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ struct Blob {
2626
kFragment,
2727
};
2828

29-
static constexpr size_t kMaxNameLength = 24u;
29+
static constexpr size_t kMaxNameLength = 32u;
3030

3131
ShaderType type = ShaderType::kVertex;
3232
uint64_t offset = 0;

impeller/display_list/display_list_dispatcher.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,13 @@ static std::optional<Entity::BlendMode> ToBlendMode(flutter::DlBlendMode mode) {
213213
case flutter::DlBlendMode::kModulate:
214214
return Entity::BlendMode::kModulate;
215215
case flutter::DlBlendMode::kScreen:
216+
return Entity::BlendMode::kScreen;
217+
case flutter::DlBlendMode::kColorBurn:
218+
return Entity::BlendMode::kColorBurn;
216219
case flutter::DlBlendMode::kOverlay:
217220
case flutter::DlBlendMode::kDarken:
218221
case flutter::DlBlendMode::kLighten:
219222
case flutter::DlBlendMode::kColorDodge:
220-
case flutter::DlBlendMode::kColorBurn:
221223
case flutter::DlBlendMode::kHardLight:
222224
case flutter::DlBlendMode::kSoftLight:
223225
case flutter::DlBlendMode::kDifference:
@@ -239,6 +241,7 @@ void DisplayListDispatcher::setBlendMode(flutter::DlBlendMode dl_mode) {
239241
paint_.blend_mode = mode.value();
240242
} else {
241243
UNIMPLEMENTED;
244+
paint_.blend_mode = Entity::BlendMode::kSourceOver;
242245
}
243246
}
244247

impeller/entity/BUILD.gn

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ impeller_shaders("entity_shaders") {
1414
"shaders/solid_fill.vert",
1515
"shaders/solid_stroke.frag",
1616
"shaders/solid_stroke.vert",
17-
"shaders/texture_blend.frag",
18-
"shaders/texture_blend.vert",
19-
"shaders/texture_blend_screen.frag",
20-
"shaders/texture_blend_screen.vert",
17+
"shaders/blend.frag",
18+
"shaders/blend.vert",
19+
"shaders/advanced_blend.vert",
20+
"shaders/advanced_blend_screen.frag",
21+
"shaders/advanced_blend_colorburn.frag",
2122
"shaders/gaussian_blur.frag",
2223
"shaders/gaussian_blur.vert",
2324
"shaders/border_mask_blur.frag",

impeller/entity/contents/content_context.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ ContentContext::ContentContext(std::shared_ptr<Context> context)
2323
gradient_fill_pipelines_[{}] =
2424
std::make_unique<GradientFillPipeline>(*context_);
2525
solid_fill_pipelines_[{}] = std::make_unique<SolidFillPipeline>(*context_);
26-
texture_blend_pipelines_[{}] =
27-
std::make_unique<TextureBlendPipeline>(*context_);
28-
texture_blend_screen_pipelines_[{}] =
29-
std::make_unique<TextureBlendScreenPipeline>(*context_);
26+
texture_blend_pipelines_[{}] = std::make_unique<BlendPipeline>(*context_);
27+
blend_screen_pipelines_[{}] =
28+
std::make_unique<BlendScreenPipeline>(*context_);
29+
blend_colorburn_pipelines_[{}] =
30+
std::make_unique<BlendColorburnPipeline>(*context_);
3031
texture_pipelines_[{}] = std::make_unique<TexturePipeline>(*context_);
3132
gaussian_blur_pipelines_[{}] =
3233
std::make_unique<GaussianBlurPipeline>(*context_);

impeller/entity/contents/content_context.h

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111
#include "flutter/fml/macros.h"
1212
#include "fml/logging.h"
1313
#include "impeller/base/validation.h"
14+
#include "impeller/entity/advanced_blend.vert.h"
15+
#include "impeller/entity/advanced_blend_colorburn.frag.h"
16+
#include "impeller/entity/advanced_blend_screen.frag.h"
17+
#include "impeller/entity/blend.frag.h"
18+
#include "impeller/entity/blend.vert.h"
1419
#include "impeller/entity/border_mask_blur.frag.h"
1520
#include "impeller/entity/border_mask_blur.vert.h"
1621
#include "impeller/entity/entity.h"
@@ -24,10 +29,6 @@
2429
#include "impeller/entity/solid_fill.vert.h"
2530
#include "impeller/entity/solid_stroke.frag.h"
2631
#include "impeller/entity/solid_stroke.vert.h"
27-
#include "impeller/entity/texture_blend.frag.h"
28-
#include "impeller/entity/texture_blend.vert.h"
29-
#include "impeller/entity/texture_blend_screen.frag.h"
30-
#include "impeller/entity/texture_blend_screen.vert.h"
3132
#include "impeller/entity/texture_fill.frag.h"
3233
#include "impeller/entity/texture_fill.vert.h"
3334
#include "impeller/renderer/formats.h"
@@ -38,10 +39,11 @@ using GradientFillPipeline =
3839
PipelineT<GradientFillVertexShader, GradientFillFragmentShader>;
3940
using SolidFillPipeline =
4041
PipelineT<SolidFillVertexShader, SolidFillFragmentShader>;
41-
using TextureBlendPipeline =
42-
PipelineT<TextureBlendVertexShader, TextureBlendFragmentShader>;
43-
using TextureBlendScreenPipeline =
44-
PipelineT<TextureBlendScreenVertexShader, TextureBlendScreenFragmentShader>;
42+
using BlendPipeline = PipelineT<BlendVertexShader, BlendFragmentShader>;
43+
using BlendScreenPipeline =
44+
PipelineT<AdvancedBlendVertexShader, AdvancedBlendScreenFragmentShader>;
45+
using BlendColorburnPipeline =
46+
PipelineT<AdvancedBlendVertexShader, AdvancedBlendColorburnFragmentShader>;
4547
using TexturePipeline =
4648
PipelineT<TextureFillVertexShader, TextureFillFragmentShader>;
4749
using GaussianBlurPipeline =
@@ -98,14 +100,18 @@ class ContentContext {
98100
return GetPipeline(solid_fill_pipelines_, opts);
99101
}
100102

101-
std::shared_ptr<Pipeline> GetTextureBlendPipeline(
102-
ContentContextOptions opts) const {
103+
std::shared_ptr<Pipeline> GetBlendPipeline(ContentContextOptions opts) const {
103104
return GetPipeline(texture_blend_pipelines_, opts);
104105
}
105106

106-
std::shared_ptr<Pipeline> GetTextureBlendScreenPipeline(
107+
std::shared_ptr<Pipeline> GetBlendScreenPipeline(
108+
ContentContextOptions opts) const {
109+
return GetPipeline(blend_screen_pipelines_, opts);
110+
}
111+
112+
std::shared_ptr<Pipeline> GetBlendColorburnPipeline(
107113
ContentContextOptions opts) const {
108-
return GetPipeline(texture_blend_screen_pipelines_, opts);
114+
return GetPipeline(blend_colorburn_pipelines_, opts);
109115
}
110116

111117
std::shared_ptr<Pipeline> GetTexturePipeline(
@@ -161,8 +167,9 @@ class ContentContext {
161167
// map.
162168
mutable Variants<GradientFillPipeline> gradient_fill_pipelines_;
163169
mutable Variants<SolidFillPipeline> solid_fill_pipelines_;
164-
mutable Variants<TextureBlendPipeline> texture_blend_pipelines_;
165-
mutable Variants<TextureBlendScreenPipeline> texture_blend_screen_pipelines_;
170+
mutable Variants<BlendPipeline> texture_blend_pipelines_;
171+
mutable Variants<BlendScreenPipeline> blend_screen_pipelines_;
172+
mutable Variants<BlendColorburnPipeline> blend_colorburn_pipelines_;
166173
mutable Variants<TexturePipeline> texture_pipelines_;
167174
mutable Variants<GaussianBlurPipeline> gaussian_blur_pipelines_;
168175
mutable Variants<BorderMaskBlurPipeline> border_mask_blur_pipelines_;

impeller/entity/contents/filters/blend_filter_contents.cc

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,28 @@ void BlendFilterContents::SetBlendMode(Entity::BlendMode blend_mode) {
9999

100100
if (blend_mode > Entity::BlendMode::kLastPipelineBlendMode) {
101101
static_assert(Entity::BlendMode::kLastAdvancedBlendMode ==
102-
Entity::BlendMode::kScreen);
102+
Entity::BlendMode::kColorBurn);
103103

104104
switch (blend_mode) {
105105
case Entity::BlendMode::kScreen:
106106
advanced_blend_proc_ = [](const FilterInput::Vector& inputs,
107107
const ContentContext& renderer,
108108
const Entity& entity, RenderPass& pass,
109109
const Rect& coverage) {
110-
PipelineProc p = &ContentContext::GetTextureBlendScreenPipeline;
111-
return AdvancedBlend<TextureBlendScreenPipeline::VertexShader,
112-
TextureBlendScreenPipeline::FragmentShader>(
110+
PipelineProc p = &ContentContext::GetBlendScreenPipeline;
111+
return AdvancedBlend<BlendScreenPipeline::VertexShader,
112+
BlendScreenPipeline::FragmentShader>(
113+
inputs, renderer, entity, pass, coverage, p);
114+
};
115+
break;
116+
case Entity::BlendMode::kColorBurn:
117+
advanced_blend_proc_ = [](const FilterInput::Vector& inputs,
118+
const ContentContext& renderer,
119+
const Entity& entity, RenderPass& pass,
120+
const Rect& coverage) {
121+
PipelineProc p = &ContentContext::GetBlendColorburnPipeline;
122+
return AdvancedBlend<BlendColorburnPipeline::VertexShader,
123+
BlendColorburnPipeline::FragmentShader>(
113124
inputs, renderer, entity, pass, coverage, p);
114125
};
115126
break;
@@ -125,8 +136,8 @@ static bool BasicBlend(const FilterInput::Vector& inputs,
125136
RenderPass& pass,
126137
const Rect& coverage,
127138
Entity::BlendMode basic_blend) {
128-
using VS = TextureBlendPipeline::VertexShader;
129-
using FS = TextureBlendPipeline::FragmentShader;
139+
using VS = BlendPipeline::VertexShader;
140+
using FS = BlendPipeline::FragmentShader;
130141

131142
auto& host_buffer = pass.GetTransientsBuffer();
132143

@@ -175,7 +186,7 @@ static bool BasicBlend(const FilterInput::Vector& inputs,
175186
// Draw the first texture using kSource.
176187

177188
options.blend_mode = Entity::BlendMode::kSource;
178-
cmd.pipeline = renderer.GetTextureBlendPipeline(options);
189+
cmd.pipeline = renderer.GetBlendPipeline(options);
179190
if (!add_blend_command(inputs[0]->GetSnapshot(renderer, entity))) {
180191
return true;
181192
}
@@ -187,7 +198,7 @@ static bool BasicBlend(const FilterInput::Vector& inputs,
187198
// Write subsequent textures using the selected blend mode.
188199

189200
options.blend_mode = basic_blend;
190-
cmd.pipeline = renderer.GetTextureBlendPipeline(options);
201+
cmd.pipeline = renderer.GetBlendPipeline(options);
191202

192203
for (auto texture_i = inputs.begin() + 1; texture_i < inputs.end();
193204
texture_i++) {

impeller/entity/entity.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@ class Entity {
4343
// pipelines on most graphics devices without extensions, and so they are
4444
// only able to be used via `BlendFilterContents`.
4545
kScreen,
46+
kColorBurn,
4647

4748
kLastPipelineBlendMode = kModulate,
48-
kLastAdvancedBlendMode = kScreen,
49+
kLastAdvancedBlendMode = kColorBurn,
4950
};
5051

5152
enum class ClipOperation {
File renamed without changes.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "blending.glsl"
6+
7+
uniform sampler2D texture_sampler_dst;
8+
uniform sampler2D texture_sampler_src;
9+
10+
in vec2 v_dst_texture_coords;
11+
in vec2 v_src_texture_coords;
12+
13+
out vec4 frag_color;
14+
15+
vec3 ComponentIsValue(vec3 n, float value) {
16+
return vec3(n.r == value, n.g == value, n.b == value);
17+
}
18+
19+
void main() {
20+
const vec4 dst =
21+
SampleWithBorder(texture_sampler_dst, v_dst_texture_coords);
22+
const vec4 src =
23+
SampleWithBorder(texture_sampler_src, v_src_texture_coords);
24+
25+
vec3 color = 1 - min(vec3(1), (1 - dst.rgb) / src.rgb);
26+
color = mix(color, vec3(1), ComponentIsValue(dst.rgb, 1.0));
27+
color = mix(color, vec3(0), ComponentIsValue(src.rgb, 0.0));
28+
29+
frag_color = vec4(color, dst.a - src.a + src.a);
30+
}

0 commit comments

Comments
 (0)