Skip to content

Commit f433042

Browse files
bderohouhuayong
authored andcommitted
[Impeller] Will it blend? (flutter#33817)
1 parent 6d487d3 commit f433042

20 files changed

+332
-46
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,17 @@ FILE: ../../../flutter/impeller/entity/entity_unittests.cc
570570
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.glsl
571571
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.vert
572572
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_colorburn.frag
573+
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_colordodge.frag
574+
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_darken.frag
575+
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_difference.frag
576+
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_exclusion.frag
577+
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_hardlight.frag
578+
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_lighten.frag
579+
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_multiply.frag
580+
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_overlay.frag
573581
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_screen.frag
582+
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_softlight.frag
583+
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_utils.glsl
574584
FILE: ../../../flutter/impeller/entity/shaders/blending/blend.frag
575585
FILE: ../../../flutter/impeller/entity/shaders/blending/blend.vert
576586
FILE: ../../../flutter/impeller/entity/shaders/border_mask_blur.frag

impeller/aiks/aiks_unittests.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,16 @@ TEST_P(AiksTest, ColorWheel) {
534534
{"Modulate", Entity::BlendMode::kModulate},
535535
// Advanced blends (color component blends)
536536
{"Screen", Entity::BlendMode::kScreen},
537+
{"Overlay", Entity::BlendMode::kOverlay},
538+
{"Darken", Entity::BlendMode::kDarken},
539+
{"Lighten", Entity::BlendMode::kLighten},
540+
{"ColorDodge", Entity::BlendMode::kColorDodge},
537541
{"ColorBurn", Entity::BlendMode::kColorBurn},
542+
{"HardLight", Entity::BlendMode::kHardLight},
543+
{"SoftLight", Entity::BlendMode::kSoftLight},
544+
{"Difference", Entity::BlendMode::kDifference},
545+
{"Exclusion", Entity::BlendMode::kExclusion},
546+
{"Multiply", Entity::BlendMode::kMultiply},
538547
};
539548
assert(blends.size() ==
540549
static_cast<size_t>(Entity::BlendMode::kLastAdvancedBlendMode) + 1);

impeller/display_list/display_list_dispatcher.cc

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,17 +66,26 @@ static std::optional<Entity::BlendMode> ToBlendMode(flutter::DlBlendMode mode) {
6666
return Entity::BlendMode::kModulate;
6767
case flutter::DlBlendMode::kScreen:
6868
return Entity::BlendMode::kScreen;
69-
case flutter::DlBlendMode::kColorBurn:
70-
return Entity::BlendMode::kColorBurn;
7169
case flutter::DlBlendMode::kOverlay:
70+
return Entity::BlendMode::kOverlay;
7271
case flutter::DlBlendMode::kDarken:
72+
return Entity::BlendMode::kDarken;
7373
case flutter::DlBlendMode::kLighten:
74+
return Entity::BlendMode::kLighten;
7475
case flutter::DlBlendMode::kColorDodge:
76+
return Entity::BlendMode::kColorDodge;
77+
case flutter::DlBlendMode::kColorBurn:
78+
return Entity::BlendMode::kColorBurn;
7579
case flutter::DlBlendMode::kHardLight:
80+
return Entity::BlendMode::kHardLight;
7681
case flutter::DlBlendMode::kSoftLight:
82+
return Entity::BlendMode::kSoftLight;
7783
case flutter::DlBlendMode::kDifference:
84+
return Entity::BlendMode::kDifference;
7885
case flutter::DlBlendMode::kExclusion:
86+
return Entity::BlendMode::kExclusion;
7987
case flutter::DlBlendMode::kMultiply:
88+
return Entity::BlendMode::kMultiply;
8089
case flutter::DlBlendMode::kHue:
8190
case flutter::DlBlendMode::kSaturation:
8291
case flutter::DlBlendMode::kColor:

impeller/entity/BUILD.gn

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,16 @@ impeller_shaders("entity_shaders") {
1010
shaders = [
1111
"shaders/blending/advanced_blend.vert",
1212
"shaders/blending/advanced_blend_colorburn.frag",
13+
"shaders/blending/advanced_blend_colordodge.frag",
14+
"shaders/blending/advanced_blend_darken.frag",
15+
"shaders/blending/advanced_blend_difference.frag",
16+
"shaders/blending/advanced_blend_exclusion.frag",
17+
"shaders/blending/advanced_blend_hardlight.frag",
18+
"shaders/blending/advanced_blend_lighten.frag",
19+
"shaders/blending/advanced_blend_multiply.frag",
20+
"shaders/blending/advanced_blend_overlay.frag",
1321
"shaders/blending/advanced_blend_screen.frag",
22+
"shaders/blending/advanced_blend_softlight.frag",
1423
"shaders/blending/blend.frag",
1524
"shaders/blending/blend.vert",
1625
"shaders/border_mask_blur.frag",

impeller/entity/contents/content_context.cc

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,28 @@ ContentContext::ContentContext(std::shared_ptr<Context> context)
155155
CreateDefaultPipeline<SolidFillPipeline>(*context_);
156156
texture_blend_pipelines_[{}] =
157157
CreateDefaultPipeline<BlendPipeline>(*context_);
158+
blend_colorburn_pipelines_[{}] =
159+
CreateDefaultPipeline<BlendColorBurnPipeline>(*context_);
160+
blend_colordodge_pipelines_[{}] =
161+
CreateDefaultPipeline<BlendColorDodgePipeline>(*context_);
162+
blend_darken_pipelines_[{}] =
163+
CreateDefaultPipeline<BlendDarkenPipeline>(*context_);
164+
blend_difference_pipelines_[{}] =
165+
CreateDefaultPipeline<BlendDifferencePipeline>(*context_);
166+
blend_exclusion_pipelines_[{}] =
167+
CreateDefaultPipeline<BlendExclusionPipeline>(*context_);
168+
blend_hardlight_pipelines_[{}] =
169+
CreateDefaultPipeline<BlendHardLightPipeline>(*context_);
170+
blend_lighten_pipelines_[{}] =
171+
CreateDefaultPipeline<BlendLightenPipeline>(*context_);
172+
blend_multiply_pipelines_[{}] =
173+
CreateDefaultPipeline<BlendMultiplyPipeline>(*context_);
174+
blend_overlay_pipelines_[{}] =
175+
CreateDefaultPipeline<BlendOverlayPipeline>(*context_);
158176
blend_screen_pipelines_[{}] =
159177
CreateDefaultPipeline<BlendScreenPipeline>(*context_);
160-
blend_colorburn_pipelines_[{}] =
161-
CreateDefaultPipeline<BlendColorburnPipeline>(*context_);
178+
blend_softlight_pipelines_[{}] =
179+
CreateDefaultPipeline<BlendSoftLightPipeline>(*context_);
162180
texture_pipelines_[{}] = CreateDefaultPipeline<TexturePipeline>(*context_);
163181
gaussian_blur_pipelines_[{}] =
164182
CreateDefaultPipeline<GaussianBlurPipeline>(*context_);

impeller/entity/contents/content_context.h

Lines changed: 98 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,16 @@
1313
#include "impeller/base/validation.h"
1414
#include "impeller/entity/advanced_blend.vert.h"
1515
#include "impeller/entity/advanced_blend_colorburn.frag.h"
16+
#include "impeller/entity/advanced_blend_colordodge.frag.h"
17+
#include "impeller/entity/advanced_blend_darken.frag.h"
18+
#include "impeller/entity/advanced_blend_difference.frag.h"
19+
#include "impeller/entity/advanced_blend_exclusion.frag.h"
20+
#include "impeller/entity/advanced_blend_hardlight.frag.h"
21+
#include "impeller/entity/advanced_blend_lighten.frag.h"
22+
#include "impeller/entity/advanced_blend_multiply.frag.h"
23+
#include "impeller/entity/advanced_blend_overlay.frag.h"
1624
#include "impeller/entity/advanced_blend_screen.frag.h"
25+
#include "impeller/entity/advanced_blend_softlight.frag.h"
1726
#include "impeller/entity/blend.frag.h"
1827
#include "impeller/entity/blend.vert.h"
1928
#include "impeller/entity/border_mask_blur.frag.h"
@@ -42,10 +51,28 @@ using GradientFillPipeline =
4251
using SolidFillPipeline =
4352
PipelineT<SolidFillVertexShader, SolidFillFragmentShader>;
4453
using BlendPipeline = PipelineT<BlendVertexShader, BlendFragmentShader>;
54+
using BlendColorBurnPipeline =
55+
PipelineT<AdvancedBlendVertexShader, AdvancedBlendColorburnFragmentShader>;
56+
using BlendColorDodgePipeline =
57+
PipelineT<AdvancedBlendVertexShader, AdvancedBlendColordodgeFragmentShader>;
58+
using BlendDarkenPipeline =
59+
PipelineT<AdvancedBlendVertexShader, AdvancedBlendDarkenFragmentShader>;
60+
using BlendDifferencePipeline =
61+
PipelineT<AdvancedBlendVertexShader, AdvancedBlendDifferenceFragmentShader>;
62+
using BlendExclusionPipeline =
63+
PipelineT<AdvancedBlendVertexShader, AdvancedBlendExclusionFragmentShader>;
64+
using BlendHardLightPipeline =
65+
PipelineT<AdvancedBlendVertexShader, AdvancedBlendHardlightFragmentShader>;
66+
using BlendLightenPipeline =
67+
PipelineT<AdvancedBlendVertexShader, AdvancedBlendLightenFragmentShader>;
68+
using BlendMultiplyPipeline =
69+
PipelineT<AdvancedBlendVertexShader, AdvancedBlendMultiplyFragmentShader>;
70+
using BlendOverlayPipeline =
71+
PipelineT<AdvancedBlendVertexShader, AdvancedBlendOverlayFragmentShader>;
4572
using BlendScreenPipeline =
4673
PipelineT<AdvancedBlendVertexShader, AdvancedBlendScreenFragmentShader>;
47-
using BlendColorburnPipeline =
48-
PipelineT<AdvancedBlendVertexShader, AdvancedBlendColorburnFragmentShader>;
74+
using BlendSoftLightPipeline =
75+
PipelineT<AdvancedBlendVertexShader, AdvancedBlendSoftlightFragmentShader>;
4976
using TexturePipeline =
5077
PipelineT<TextureFillVertexShader, TextureFillFragmentShader>;
5178
using GaussianBlurPipeline =
@@ -110,16 +137,6 @@ class ContentContext {
110137
return GetPipeline(texture_blend_pipelines_, opts);
111138
}
112139

113-
std::shared_ptr<Pipeline> GetBlendScreenPipeline(
114-
ContentContextOptions opts) const {
115-
return GetPipeline(blend_screen_pipelines_, opts);
116-
}
117-
118-
std::shared_ptr<Pipeline> GetBlendColorburnPipeline(
119-
ContentContextOptions opts) const {
120-
return GetPipeline(blend_colorburn_pipelines_, opts);
121-
}
122-
123140
std::shared_ptr<Pipeline> GetTexturePipeline(
124141
ContentContextOptions opts) const {
125142
return GetPipeline(texture_pipelines_, opts);
@@ -154,6 +171,63 @@ class ContentContext {
154171
return GetPipeline(vertices_pipelines_, opts);
155172
}
156173

174+
// Advanced blends.
175+
176+
std::shared_ptr<Pipeline> GetBlendColorBurnPipeline(
177+
ContentContextOptions opts) const {
178+
return GetPipeline(blend_colorburn_pipelines_, opts);
179+
}
180+
181+
std::shared_ptr<Pipeline> GetBlendColorDodgePipeline(
182+
ContentContextOptions opts) const {
183+
return GetPipeline(blend_colordodge_pipelines_, opts);
184+
}
185+
186+
std::shared_ptr<Pipeline> GetBlendDarkenPipeline(
187+
ContentContextOptions opts) const {
188+
return GetPipeline(blend_darken_pipelines_, opts);
189+
}
190+
191+
std::shared_ptr<Pipeline> GetBlendDifferencePipeline(
192+
ContentContextOptions opts) const {
193+
return GetPipeline(blend_difference_pipelines_, opts);
194+
}
195+
196+
std::shared_ptr<Pipeline> GetBlendExclusionPipeline(
197+
ContentContextOptions opts) const {
198+
return GetPipeline(blend_exclusion_pipelines_, opts);
199+
}
200+
201+
std::shared_ptr<Pipeline> GetBlendHardLightPipeline(
202+
ContentContextOptions opts) const {
203+
return GetPipeline(blend_hardlight_pipelines_, opts);
204+
}
205+
206+
std::shared_ptr<Pipeline> GetBlendLightenPipeline(
207+
ContentContextOptions opts) const {
208+
return GetPipeline(blend_lighten_pipelines_, opts);
209+
}
210+
211+
std::shared_ptr<Pipeline> GetBlendMultiplyPipeline(
212+
ContentContextOptions opts) const {
213+
return GetPipeline(blend_multiply_pipelines_, opts);
214+
}
215+
216+
std::shared_ptr<Pipeline> GetBlendOverlayPipeline(
217+
ContentContextOptions opts) const {
218+
return GetPipeline(blend_overlay_pipelines_, opts);
219+
}
220+
221+
std::shared_ptr<Pipeline> GetBlendScreenPipeline(
222+
ContentContextOptions opts) const {
223+
return GetPipeline(blend_screen_pipelines_, opts);
224+
}
225+
226+
std::shared_ptr<Pipeline> GetBlendSoftLightPipeline(
227+
ContentContextOptions opts) const {
228+
return GetPipeline(blend_softlight_pipelines_, opts);
229+
}
230+
157231
std::shared_ptr<Context> GetContext() const;
158232

159233
using SubpassCallback =
@@ -179,15 +253,25 @@ class ContentContext {
179253
mutable Variants<GradientFillPipeline> gradient_fill_pipelines_;
180254
mutable Variants<SolidFillPipeline> solid_fill_pipelines_;
181255
mutable Variants<BlendPipeline> texture_blend_pipelines_;
182-
mutable Variants<BlendScreenPipeline> blend_screen_pipelines_;
183-
mutable Variants<BlendColorburnPipeline> blend_colorburn_pipelines_;
184256
mutable Variants<TexturePipeline> texture_pipelines_;
185257
mutable Variants<GaussianBlurPipeline> gaussian_blur_pipelines_;
186258
mutable Variants<BorderMaskBlurPipeline> border_mask_blur_pipelines_;
187259
mutable Variants<SolidStrokePipeline> solid_stroke_pipelines_;
188260
mutable Variants<ClipPipeline> clip_pipelines_;
189261
mutable Variants<GlyphAtlasPipeline> glyph_atlas_pipelines_;
190262
mutable Variants<VerticesPipeline> vertices_pipelines_;
263+
// Advanced blends.
264+
mutable Variants<BlendColorBurnPipeline> blend_colorburn_pipelines_;
265+
mutable Variants<BlendColorDodgePipeline> blend_colordodge_pipelines_;
266+
mutable Variants<BlendDarkenPipeline> blend_darken_pipelines_;
267+
mutable Variants<BlendDifferencePipeline> blend_difference_pipelines_;
268+
mutable Variants<BlendExclusionPipeline> blend_exclusion_pipelines_;
269+
mutable Variants<BlendHardLightPipeline> blend_hardlight_pipelines_;
270+
mutable Variants<BlendLightenPipeline> blend_lighten_pipelines_;
271+
mutable Variants<BlendMultiplyPipeline> blend_multiply_pipelines_;
272+
mutable Variants<BlendOverlayPipeline> blend_overlay_pipelines_;
273+
mutable Variants<BlendScreenPipeline> blend_screen_pipelines_;
274+
mutable Variants<BlendSoftLightPipeline> blend_softlight_pipelines_;
191275

192276
template <class TypedPipeline>
193277
std::shared_ptr<Pipeline> GetPipeline(Variants<TypedPipeline>& container,

impeller/entity/contents/filters/blend_filter_contents.cc

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,18 @@ static bool PipelineBlend(const FilterInput::Vector& inputs,
216216
return true;
217217
}
218218

219+
#define BLEND_CASE(mode) \
220+
case Entity::BlendMode::k##mode: \
221+
advanced_blend_proc_ = \
222+
[](const FilterInput::Vector& inputs, const ContentContext& renderer, \
223+
const Entity& entity, RenderPass& pass, const Rect& coverage, \
224+
std::optional<Color> fg_color) { \
225+
PipelineProc p = &ContentContext::GetBlend##mode##Pipeline; \
226+
return AdvancedBlend<BlendScreenPipeline>( \
227+
inputs, renderer, entity, pass, coverage, fg_color, p); \
228+
}; \
229+
break;
230+
219231
void BlendFilterContents::SetBlendMode(Entity::BlendMode blend_mode) {
220232
if (blend_mode > Entity::BlendMode::kLastAdvancedBlendMode) {
221233
VALIDATION_LOG << "Invalid blend mode " << static_cast<int>(blend_mode)
@@ -226,31 +238,20 @@ void BlendFilterContents::SetBlendMode(Entity::BlendMode blend_mode) {
226238

227239
if (blend_mode > Entity::BlendMode::kLastPipelineBlendMode) {
228240
static_assert(Entity::BlendMode::kLastAdvancedBlendMode ==
229-
Entity::BlendMode::kColorBurn);
241+
Entity::BlendMode::kMultiply);
230242

231243
switch (blend_mode) {
232-
case Entity::BlendMode::kScreen:
233-
advanced_blend_proc_ = [](const FilterInput::Vector& inputs,
234-
const ContentContext& renderer,
235-
const Entity& entity, RenderPass& pass,
236-
const Rect& coverage,
237-
std::optional<Color> fg_color) {
238-
PipelineProc p = &ContentContext::GetBlendScreenPipeline;
239-
return AdvancedBlend<BlendScreenPipeline>(
240-
inputs, renderer, entity, pass, coverage, fg_color, p);
241-
};
242-
break;
243-
case Entity::BlendMode::kColorBurn:
244-
advanced_blend_proc_ = [](const FilterInput::Vector& inputs,
245-
const ContentContext& renderer,
246-
const Entity& entity, RenderPass& pass,
247-
const Rect& coverage,
248-
std::optional<Color> fg_color) {
249-
PipelineProc p = &ContentContext::GetBlendColorburnPipeline;
250-
return AdvancedBlend<BlendColorburnPipeline>(
251-
inputs, renderer, entity, pass, coverage, fg_color, p);
252-
};
253-
break;
244+
BLEND_CASE(Screen)
245+
BLEND_CASE(Overlay)
246+
BLEND_CASE(Darken)
247+
BLEND_CASE(Lighten)
248+
BLEND_CASE(ColorDodge)
249+
BLEND_CASE(ColorBurn)
250+
BLEND_CASE(HardLight)
251+
BLEND_CASE(SoftLight)
252+
BLEND_CASE(Difference)
253+
BLEND_CASE(Exclusion)
254+
BLEND_CASE(Multiply)
254255
default:
255256
FML_UNREACHABLE();
256257
}

impeller/entity/entity.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,19 @@ 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+
kOverlay,
47+
kDarken,
48+
kLighten,
49+
kColorDodge,
4650
kColorBurn,
51+
kHardLight,
52+
kSoftLight,
53+
kDifference,
54+
kExclusion,
55+
kMultiply,
4756

4857
kLastPipelineBlendMode = kModulate,
49-
kLastAdvancedBlendMode = kColorBurn,
58+
kLastAdvancedBlendMode = kMultiply,
5059
};
5160

5261
enum class ClipOperation {

impeller/entity/shaders/blending/advanced_blend_colorburn.frag

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
vec3 ComponentIsValue(vec3 n, float value) {
6-
return vec3(n.r == value, n.g == value, n.b == value);
7-
}
5+
#include "advanced_blend_utils.glsl"
86

97
vec3 Blend(vec3 dst, vec3 src) {
8+
// https://www.w3.org/TR/compositing-1/#blendingcolorburn
109
vec3 color = 1 - min(vec3(1), (1 - dst) / src);
1110
color = mix(color, vec3(1), ComponentIsValue(dst, 1.0));
1211
color = mix(color, vec3(0), ComponentIsValue(src, 0.0));
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
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 "advanced_blend_utils.glsl"
6+
7+
vec3 Blend(vec3 dst, vec3 src) {
8+
// https://www.w3.org/TR/compositing-1/#blendingcolordodge
9+
vec3 color = min(vec3(1), dst / (1 - src));
10+
color = mix(color, vec3(0), ComponentIsValue(dst, 0.0));
11+
color = mix(color, vec3(1), ComponentIsValue(src, 1.0));
12+
return color;
13+
}
14+
15+
#include "advanced_blend.glsl"

0 commit comments

Comments
 (0)