Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Blend.h
Go to the documentation of this file.
1/*
2 * Copyright 2013 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#ifndef skgpu_Blend_DEFINED
9#define skgpu_Blend_DEFINED
10
11#include "include/core/SkSpan.h"
15
16#include <cstdint>
17
18enum class SkBlendMode;
19class SkString;
20
21namespace skgpu {
22
23/**
24 * Equations for alpha-blending.
25 */
26enum class BlendEquation : uint8_t {
27 // Basic blend equations.
28 kAdd, //<! Cs*S + Cd*D
29 kSubtract, //<! Cs*S - Cd*D
30 kReverseSubtract, //<! Cd*D - Cs*S
31
32 // Advanced blend equations. These are described in the SVG and PDF specs.
33 kScreen,
35 kDarken,
44 kHSLHue,
48
50
53};
54
55static const int kBlendEquationCnt = static_cast<int>(BlendEquation::kLast) + 1;
56
57/**
58 * Coefficients for alpha-blending.
59 */
60enum class BlendCoeff : uint8_t {
61 kZero, //<! 0
62 kOne, //<! 1
63 kSC, //<! src color
64 kISC, //<! one minus src color
65 kDC, //<! dst color
66 kIDC, //<! one minus dst color
67 kSA, //<! src alpha
68 kISA, //<! one minus src alpha
69 kDA, //<! dst alpha
70 kIDA, //<! one minus dst alpha
71 kConstC, //<! constant color
72 kIConstC, //<! one minus constant color
73 kS2C,
74 kIS2C,
75 kS2A,
76 kIS2A,
77
79
81};
82
83struct BlendInfo {
85
86 bool operator==(const BlendInfo& other) const {
87 return fEquation == other.fEquation &&
88 fSrcBlend == other.fSrcBlend &&
89 fDstBlend == other.fDstBlend &&
92 }
93
98 bool fWritesColor = true;
99};
100
101static const int kBlendCoeffCnt = static_cast<int>(BlendCoeff::kLast) + 1;
102
103static constexpr bool BlendCoeffRefsSrc(const BlendCoeff coeff) {
104 return BlendCoeff::kSC == coeff || BlendCoeff::kISC == coeff || BlendCoeff::kSA == coeff ||
105 BlendCoeff::kISA == coeff;
106}
107
108static constexpr bool BlendCoeffRefsDst(const BlendCoeff coeff) {
109 return BlendCoeff::kDC == coeff || BlendCoeff::kIDC == coeff || BlendCoeff::kDA == coeff ||
110 BlendCoeff::kIDA == coeff;
111}
112
113static constexpr bool BlendCoeffRefsSrc2(const BlendCoeff coeff) {
114 return BlendCoeff::kS2C == coeff || BlendCoeff::kIS2C == coeff ||
115 BlendCoeff::kS2A == coeff || BlendCoeff::kIS2A == coeff;
116}
117
118static constexpr bool BlendCoeffsUseSrcColor(BlendCoeff srcCoeff, BlendCoeff dstCoeff) {
119 return BlendCoeff::kZero != srcCoeff || BlendCoeffRefsSrc(dstCoeff);
120}
121
122static constexpr bool BlendCoeffsUseDstColor(BlendCoeff srcCoeff,
123 BlendCoeff dstCoeff,
124 bool srcColorIsOpaque) {
125 return BlendCoeffRefsDst(srcCoeff) ||
126 (dstCoeff != BlendCoeff::kZero && !(dstCoeff == BlendCoeff::kISA && srcColorIsOpaque));
127}
128
129static constexpr bool BlendEquationIsAdvanced(BlendEquation equation) {
130 return equation >= BlendEquation::kFirstAdvanced &&
131 equation != BlendEquation::kIllegal;
132}
133
134static constexpr bool BlendModifiesDst(BlendEquation equation,
135 BlendCoeff srcCoeff,
136 BlendCoeff dstCoeff) {
137 return (BlendEquation::kAdd != equation && BlendEquation::kReverseSubtract != equation) ||
138 BlendCoeff::kZero != srcCoeff || BlendCoeff::kOne != dstCoeff;
139}
140
141static constexpr bool BlendCoeffRefsConstant(const BlendCoeff coeff) {
142 return coeff == BlendCoeff::kConstC || coeff == BlendCoeff::kIConstC;
143}
144
145static constexpr bool BlendShouldDisable(BlendEquation equation,
146 BlendCoeff srcCoeff,
147 BlendCoeff dstCoeff) {
148 return (BlendEquation::kAdd == equation || BlendEquation::kSubtract == equation) &&
149 BlendCoeff::kOne == srcCoeff && BlendCoeff::kZero == dstCoeff;
150}
151
152/**
153 * Advanced blend equations can always tweak alpha for coverage. (See GrCustomXfermode.cpp)
154 *
155 * For "add" and "reverse subtract" the blend equation with f=coverage is:
156 *
157 * D' = f * (S * srcCoeff + D * dstCoeff) + (1-f) * D
158 * = f * S * srcCoeff + D * (f * dstCoeff + (1 - f))
159 *
160 * (Let srcCoeff be negative for reverse subtract.) We can tweak alpha for coverage when the
161 * following relationship holds:
162 *
163 * (f*S) * srcCoeff' + D * dstCoeff' == f * S * srcCoeff + D * (f * dstCoeff + (1 - f))
164 *
165 * (Where srcCoeff' and dstCoeff' have any reference to S pre-multiplied by f.)
166 *
167 * It's easy to see this works for the src term as long as srcCoeff' == srcCoeff (meaning srcCoeff
168 * does not reference S). For the dst term, this will work as long as the following is true:
169 *|
170 * dstCoeff' == f * dstCoeff + (1 - f)
171 * dstCoeff' == 1 - f * (1 - dstCoeff)
172 *
173 * By inspection we can see this will work as long as dstCoeff has a 1, and any other term in
174 * dstCoeff references S.
175 *
176 * Moreover, if the blend doesn't modify the dst at all then it is ok to arbitrarily modify the src
177 * color so folding in coverage is allowed.
178 */
179static constexpr bool BlendAllowsCoverageAsAlpha(BlendEquation equation,
180 BlendCoeff srcCoeff,
181 BlendCoeff dstCoeff) {
182 return BlendEquationIsAdvanced(equation) ||
183 !BlendModifiesDst(equation, srcCoeff, dstCoeff) ||
184 ((BlendEquation::kAdd == equation || BlendEquation::kReverseSubtract == equation) &&
185 !BlendCoeffRefsSrc(srcCoeff) &&
186 (BlendCoeff::kOne == dstCoeff || BlendCoeff::kISC == dstCoeff ||
187 BlendCoeff::kISA == dstCoeff));
188}
189
190/**
191 * Returns the name of the SkSL built-in blend function for a SkBlendMode.
192 */
193const char* BlendFuncName(SkBlendMode mode);
194
195/**
196 * If a blend can be represented by `blend_porter_duff`, returns the associated blend constants as
197 * an array of four floats. If not, returns an empty span.
198 */
200
201/**
202 * Returns a pair of "blend function + uniform data" for a particular SkBlendMode.
203 * This allows us to use fewer unique functions when generating shaders, e.g. every Porter-Duff
204 * blend can use the same function.
205 */
211
212} // namespace skgpu
213
214#endif // skgpu_Blend_DEFINED
SkBlendMode
Definition SkBlendMode.h:38
constexpr SkPMColor4f SK_PMColor4fTRANSPARENT
static void dump(const float m[20], SkYUVColorSpace cs, bool rgb2yuv)
static constexpr bool BlendCoeffRefsConstant(const BlendCoeff coeff)
Definition Blend.h:141
static constexpr bool BlendEquationIsAdvanced(BlendEquation equation)
Definition Blend.h:129
const char * BlendFuncName(SkBlendMode mode)
Definition Blend.cpp:18
static constexpr bool BlendCoeffRefsDst(const BlendCoeff coeff)
Definition Blend.h:108
static constexpr bool BlendCoeffsUseSrcColor(BlendCoeff srcCoeff, BlendCoeff dstCoeff)
Definition Blend.h:118
static constexpr bool BlendShouldDisable(BlendEquation equation, BlendCoeff srcCoeff, BlendCoeff dstCoeff)
Definition Blend.h:145
static constexpr bool BlendAllowsCoverageAsAlpha(BlendEquation equation, BlendCoeff srcCoeff, BlendCoeff dstCoeff)
Definition Blend.h:179
static const int kBlendEquationCnt
Definition Blend.h:55
static constexpr bool BlendCoeffRefsSrc(const BlendCoeff coeff)
Definition Blend.h:103
BlendEquation
Definition Blend.h:26
static constexpr bool BlendCoeffsUseDstColor(BlendCoeff srcCoeff, BlendCoeff dstCoeff, bool srcColorIsOpaque)
Definition Blend.h:122
BlendCoeff
Definition Blend.h:60
ReducedBlendModeInfo GetReducedBlendModeInfo(SkBlendMode mode)
Definition Blend.cpp:86
static constexpr bool BlendModifiesDst(BlendEquation equation, BlendCoeff srcCoeff, BlendCoeff dstCoeff)
Definition Blend.h:134
static const int kBlendCoeffCnt
Definition Blend.h:101
SkSpan< const float > GetPorterDuffBlendConstants(SkBlendMode mode)
Definition Blend.cpp:53
static constexpr bool BlendCoeffRefsSrc2(const BlendCoeff coeff)
Definition Blend.h:113
skgpu::BlendCoeff fDstBlend
Definition Blend.h:96
SkPMColor4f fBlendConstant
Definition Blend.h:97
SkDEBUGCODE(SkString dump() const ;) bool operator
bool fWritesColor
Definition Blend.h:98
skgpu::BlendCoeff fSrcBlend
Definition Blend.h:95
const char * fFunction
Definition Blend.h:207
SkSpan< const float > fUniformData
Definition Blend.h:208