Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Blend.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "src/gpu/Blend.h"
9
11
12#ifdef SK_DEBUG
14#endif
15
16namespace skgpu {
17
18const char* BlendFuncName(SkBlendMode mode) {
19 switch (mode) {
20 case SkBlendMode::kClear: return "blend_clear";
21 case SkBlendMode::kSrc: return "blend_src";
22 case SkBlendMode::kDst: return "blend_dst";
23 case SkBlendMode::kSrcOver: return "blend_src_over";
24 case SkBlendMode::kDstOver: return "blend_dst_over";
25 case SkBlendMode::kSrcIn: return "blend_src_in";
26 case SkBlendMode::kDstIn: return "blend_dst_in";
27 case SkBlendMode::kSrcOut: return "blend_src_out";
28 case SkBlendMode::kDstOut: return "blend_dst_out";
29 case SkBlendMode::kSrcATop: return "blend_src_atop";
30 case SkBlendMode::kDstATop: return "blend_dst_atop";
31 case SkBlendMode::kXor: return "blend_xor";
32 case SkBlendMode::kPlus: return "blend_plus";
33 case SkBlendMode::kModulate: return "blend_modulate";
34 case SkBlendMode::kScreen: return "blend_screen";
35 case SkBlendMode::kOverlay: return "blend_overlay";
36 case SkBlendMode::kDarken: return "blend_darken";
37 case SkBlendMode::kLighten: return "blend_lighten";
38 case SkBlendMode::kColorDodge: return "blend_color_dodge";
39 case SkBlendMode::kColorBurn: return "blend_color_burn";
40 case SkBlendMode::kHardLight: return "blend_hard_light";
41 case SkBlendMode::kSoftLight: return "blend_soft_light";
42 case SkBlendMode::kDifference: return "blend_difference";
43 case SkBlendMode::kExclusion: return "blend_exclusion";
44 case SkBlendMode::kMultiply: return "blend_multiply";
45 case SkBlendMode::kHue: return "blend_hue";
46 case SkBlendMode::kSaturation: return "blend_saturation";
47 case SkBlendMode::kColor: return "blend_color";
48 case SkBlendMode::kLuminosity: return "blend_luminosity";
49 }
51}
52
54 static constexpr float kClear[] = {0, 0, 0, 0};
55 static constexpr float kSrc[] = {1, 0, 0, 0};
56 static constexpr float kDst[] = {0, 1, 0, 0};
57 static constexpr float kSrcOver[] = {1, 0, 0, -1};
58 static constexpr float kDstOver[] = {0, 1, -1, 0};
59 static constexpr float kSrcIn[] = {0, 0, 1, 0};
60 static constexpr float kDstIn[] = {0, 0, 0, 1};
61 static constexpr float kSrcOut[] = {0, 0, -1, 0};
62 static constexpr float kDstOut[] = {0, 0, 0, -1};
63 static constexpr float kSrcATop[] = {0, 0, 1, -1};
64 static constexpr float kDstATop[] = {0, 0, -1, 1};
65 static constexpr float kXor[] = {0, 0, -1, -1};
66 static constexpr float kPlus[] = {1, 1, 0, 0};
67
68 switch (mode) {
69 case SkBlendMode::kClear: return SkSpan(kClear);
70 case SkBlendMode::kSrc: return SkSpan(kSrc);
71 case SkBlendMode::kDst: return SkSpan(kDst);
74 case SkBlendMode::kSrcIn: return SkSpan(kSrcIn);
75 case SkBlendMode::kDstIn: return SkSpan(kDstIn);
80 case SkBlendMode::kXor: return SkSpan(kXor);
81 case SkBlendMode::kPlus: return SkSpan(kPlus);
82 default: return {};
83 }
84}
85
87 static constexpr float kHue[] = {0, 1};
88 static constexpr float kSaturation[] = {1, 1};
89 static constexpr float kColor[] = {0, 0};
90 static constexpr float kLuminosity[] = {1, 0};
91
92 static constexpr float kOverlay[] = {0};
93 static constexpr float kHardLight[] = {1};
94
95 static constexpr float kDarken[] = {1};
96 static constexpr float kLighten[] = {-1};
97
98 switch (mode) {
99 // Clear/src/dst are intentionally omitted; using the built-in blend_xxxxx functions is
100 // preferable, since that gives us an opportunity to eliminate the src/dst entirely.
101
111 case SkBlendMode::kPlus: return {"blend_porter_duff", GetPorterDuffBlendConstants(mode)};
112
113 case SkBlendMode::kHue: return {"blend_hslc", SkSpan(kHue)};
114 case SkBlendMode::kSaturation: return {"blend_hslc", SkSpan(kSaturation)};
115 case SkBlendMode::kColor: return {"blend_hslc", SkSpan(kColor)};
116 case SkBlendMode::kLuminosity: return {"blend_hslc", SkSpan(kLuminosity)};
117
118 case SkBlendMode::kOverlay: return {"blend_overlay", SkSpan(kOverlay)};
119 case SkBlendMode::kHardLight: return {"blend_overlay", SkSpan(kHardLight)};
120
121 case SkBlendMode::kDarken: return {"blend_darken", SkSpan(kDarken)};
122 case SkBlendMode::kLighten: return {"blend_darken", SkSpan(kLighten)};
123
124 default: return {BlendFuncName(mode), {}};
125 }
126}
127
128#ifdef SK_DEBUG
129
130namespace {
131
132const char *equation_string(skgpu::BlendEquation eq) {
133 switch (eq) {
134 case skgpu::BlendEquation::kAdd: return "add";
135 case skgpu::BlendEquation::kSubtract: return "subtract";
136 case skgpu::BlendEquation::kReverseSubtract: return "reverse_subtract";
137 case skgpu::BlendEquation::kScreen: return "screen";
138 case skgpu::BlendEquation::kOverlay: return "overlay";
139 case skgpu::BlendEquation::kDarken: return "darken";
140 case skgpu::BlendEquation::kLighten: return "lighten";
141 case skgpu::BlendEquation::kColorDodge: return "color_dodge";
142 case skgpu::BlendEquation::kColorBurn: return "color_burn";
143 case skgpu::BlendEquation::kHardLight: return "hard_light";
144 case skgpu::BlendEquation::kSoftLight: return "soft_light";
145 case skgpu::BlendEquation::kDifference: return "difference";
146 case skgpu::BlendEquation::kExclusion: return "exclusion";
147 case skgpu::BlendEquation::kMultiply: return "multiply";
148 case skgpu::BlendEquation::kHSLHue: return "hsl_hue";
149 case skgpu::BlendEquation::kHSLSaturation: return "hsl_saturation";
150 case skgpu::BlendEquation::kHSLColor: return "hsl_color";
151 case skgpu::BlendEquation::kHSLLuminosity: return "hsl_luminosity";
153 SkASSERT(false);
154 return "<illegal>";
155 }
156
158}
159
160const char *coeff_string(skgpu::BlendCoeff coeff) {
161 switch (coeff) {
162 case skgpu::BlendCoeff::kZero: return "zero";
163 case skgpu::BlendCoeff::kOne: return "one";
164 case skgpu::BlendCoeff::kSC: return "src_color";
165 case skgpu::BlendCoeff::kISC: return "inv_src_color";
166 case skgpu::BlendCoeff::kDC: return "dst_color";
167 case skgpu::BlendCoeff::kIDC: return "inv_dst_color";
168 case skgpu::BlendCoeff::kSA: return "src_alpha";
169 case skgpu::BlendCoeff::kISA: return "inv_src_alpha";
170 case skgpu::BlendCoeff::kDA: return "dst_alpha";
171 case skgpu::BlendCoeff::kIDA: return "inv_dst_alpha";
172 case skgpu::BlendCoeff::kConstC: return "const_color";
173 case skgpu::BlendCoeff::kIConstC: return "inv_const_color";
174 case skgpu::BlendCoeff::kS2C: return "src2_color";
175 case skgpu::BlendCoeff::kIS2C: return "inv_src2_color";
176 case skgpu::BlendCoeff::kS2A: return "src2_alpha";
177 case skgpu::BlendCoeff::kIS2A: return "inv_src2_alpha";
179 SkASSERT(false);
180 return "<illegal>";
181 }
182
184}
185
186} // anonymous namespace
187
188SkString BlendInfo::dump() const {
190 out.printf("writes_color(%d) equation(%s) src_coeff(%s) dst_coeff:(%s) const(0x%08x)",
191 fWritesColor, equation_string(fEquation), coeff_string(fSrcBlend),
192 coeff_string(fDstBlend), fBlendConstant.toBytes_RGBA());
193 return out;
194}
195
196#endif // SK_DEBUG
197
198} // namespace skgpu
static constexpr SkColor kColor
static bool eq(const SkM44 &a, const SkM44 &b, float tol)
Definition M44Test.cpp:18
#define SkUNREACHABLE
Definition SkAssert.h:135
#define SkASSERT(cond)
Definition SkAssert.h:116
SkBlendMode
Definition SkBlendMode.h:38
@ kSrcOut
r = s * (1-da)
@ kExclusion
rc = s + d - two(s*d), ra = kSrcOver
@ kSaturation
saturation of source with hue and luminosity of destination
@ kColorBurn
darken destination to reflect source
@ kPlus
r = min(s + d, 1)
@ kLighten
rc = s + d - min(s*da, d*sa), ra = kSrcOver
@ kHue
hue of source with saturation and luminosity of destination
@ kDstIn
r = d * sa
@ kModulate
r = s*d
@ kMultiply
r = s*(1-da) + d*(1-sa) + s*d
@ kColorDodge
brighten destination to reflect source
@ kScreen
r = s + d - s*d
@ kSrcOver
r = s + (1-sa)*d
@ kXor
r = s*(1-da) + d*(1-sa)
@ kLuminosity
luminosity of source with hue and saturation of destination
@ kSoftLight
lighten or darken, depending on source
@ kDifference
rc = s + d - 2*(min(s*da, d*sa)), ra = kSrcOver
@ kOverlay
multiply or screen, depending on destination
@ kSrcATop
r = s*da + d*(1-sa)
@ kDstATop
r = d*sa + s*(1-da)
@ kDstOver
r = d + (1-da)*s
@ kColor
hue and saturation of source with luminosity of destination
@ kHardLight
multiply or screen, depending on source
@ kDstOut
r = d * (1-sa)
@ kDarken
rc = s + d - max(s*da, d*sa), ra = kSrcOver
@ kSrcIn
r = s * da
@ kClear
r = 0
const char * BlendFuncName(SkBlendMode mode)
Definition Blend.cpp:18
BlendEquation
Definition Blend.h:26
BlendCoeff
Definition Blend.h:60
ReducedBlendModeInfo GetReducedBlendModeInfo(SkBlendMode mode)
Definition Blend.cpp:86
SkSpan< const float > GetPorterDuffBlendConstants(SkBlendMode mode)
Definition Blend.cpp:53
uint32_t toBytes_RGBA() const
skgpu::BlendCoeff fDstBlend
Definition Blend.h:96
SkPMColor4f fBlendConstant
Definition Blend.h:97
bool fWritesColor
Definition Blend.h:98
skgpu::BlendCoeff fSrcBlend
Definition Blend.h:95