blob: fa9dca211e8fcd24ea0fb81c4c8b743da09a33f8 [file] [log] [blame]
egdaniel378092f2014-12-03 10:40:13 -08001/*
2 * Copyright 2014 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 GrXferProcessor_DEFINED
9#define GrXferProcessor_DEFINED
10
11#include "GrColor.h"
egdanielc2304142014-12-11 13:15:13 -080012#include "GrProcessor.h"
bsalomon50785a32015-02-06 07:02:37 -080013#include "GrTexture.h"
egdaniel378092f2014-12-03 10:40:13 -080014#include "GrTypes.h"
15#include "SkXfermode.h"
16
jvanverthe9c0fc62015-04-29 11:18:05 -070017class GrShaderCaps;
18class GrGLSLCaps;
egdanielc2304142014-12-11 13:15:13 -080019class GrGLXferProcessor;
egdaniel95131432014-12-09 11:15:43 -080020class GrProcOptInfo;
21
egdaniel378092f2014-12-03 10:40:13 -080022/**
cdalton8917d622015-05-06 13:40:21 -070023 * Equations for alpha-blending.
24 */
25enum GrBlendEquation {
cdalton8917d622015-05-06 13:40:21 -070026 // Basic blend equations.
27 kAdd_GrBlendEquation, //<! Cs*S + Cd*D
28 kSubtract_GrBlendEquation, //<! Cs*S - Cd*D
29 kReverseSubtract_GrBlendEquation, //<! Cd*D - Cs*S
30
31 // Advanced blend equations. These are described in the SVG and PDF specs.
32 kScreen_GrBlendEquation,
33 kOverlay_GrBlendEquation,
34 kDarken_GrBlendEquation,
35 kLighten_GrBlendEquation,
36 kColorDodge_GrBlendEquation,
37 kColorBurn_GrBlendEquation,
38 kHardLight_GrBlendEquation,
39 kSoftLight_GrBlendEquation,
40 kDifference_GrBlendEquation,
41 kExclusion_GrBlendEquation,
42 kMultiply_GrBlendEquation,
43 kHSLHue_GrBlendEquation,
44 kHSLSaturation_GrBlendEquation,
45 kHSLColor_GrBlendEquation,
46 kHSLLuminosity_GrBlendEquation,
47
bsalomonf7cc8772015-05-11 11:21:14 -070048 kFirstAdvancedGrBlendEquation = kScreen_GrBlendEquation,
49 kLast_GrBlendEquation = kHSLLuminosity_GrBlendEquation
cdalton8917d622015-05-06 13:40:21 -070050};
51
bsalomonf7cc8772015-05-11 11:21:14 -070052static const int kGrBlendEquationCnt = kLast_GrBlendEquation + 1;
53
cdalton8917d622015-05-06 13:40:21 -070054inline bool GrBlendEquationIsAdvanced(GrBlendEquation equation) {
55 return equation >= kFirstAdvancedGrBlendEquation;
56}
57
58/**
egdanielb197b8f2015-02-17 07:34:43 -080059 * Coeffecients for alpha-blending.
60 */
61enum GrBlendCoeff {
egdanielb197b8f2015-02-17 07:34:43 -080062 kZero_GrBlendCoeff, //<! 0
63 kOne_GrBlendCoeff, //<! 1
64 kSC_GrBlendCoeff, //<! src color
65 kISC_GrBlendCoeff, //<! one minus src color
66 kDC_GrBlendCoeff, //<! dst color
67 kIDC_GrBlendCoeff, //<! one minus dst color
68 kSA_GrBlendCoeff, //<! src alpha
69 kISA_GrBlendCoeff, //<! one minus src alpha
70 kDA_GrBlendCoeff, //<! dst alpha
71 kIDA_GrBlendCoeff, //<! one minus dst alpha
72 kConstC_GrBlendCoeff, //<! constant color
73 kIConstC_GrBlendCoeff, //<! one minus constant color
74 kConstA_GrBlendCoeff, //<! constant color alpha
75 kIConstA_GrBlendCoeff, //<! one minus constant color alpha
76 kS2C_GrBlendCoeff,
77 kIS2C_GrBlendCoeff,
78 kS2A_GrBlendCoeff,
79 kIS2A_GrBlendCoeff,
80
bsalomonf7cc8772015-05-11 11:21:14 -070081 kLast_GrBlendCoeff = kIS2A_GrBlendCoeff
egdanielb197b8f2015-02-17 07:34:43 -080082};
83
bsalomonf7cc8772015-05-11 11:21:14 -070084static const int kGrBlendCoeffCnt = kLast_GrBlendCoeff + 1;
85
egdanielb197b8f2015-02-17 07:34:43 -080086/**
cdalton9954bc32015-04-29 14:17:00 -070087 * Barriers for blending. When a shader reads the dst directly, an Xfer barrier is sometimes
88 * required after a pixel has been written, before it can be safely read again.
89 */
90enum GrXferBarrierType {
91 kTexture_GrXferBarrierType, //<! Required when a shader reads and renders to the same texture.
cdalton8917d622015-05-06 13:40:21 -070092 kBlend_GrXferBarrierType, //<! Required by certain blend extensions.
cdalton9954bc32015-04-29 14:17:00 -070093};
94
95/**
egdaniel378092f2014-12-03 10:40:13 -080096 * GrXferProcessor is responsible for implementing the xfer mode that blends the src color and dst
97 * color. It does this by emitting fragment shader code and controlling the fixed-function blend
98 * state. The inputs to its shader code are the final computed src color and fractional pixel
99 * coverage. The GrXferProcessor's shader code writes the fragment shader output color that goes
100 * into the fixed-function blend. When dual-source blending is available, it may also write a
101 * seconday fragment shader output color. When allowed by the backend API, the GrXferProcessor may
102 * read the destination color. The GrXferProcessor is responsible for setting the blend coefficients
103 * and blend constant color.
104 *
105 * A GrXferProcessor is never installed directly into our draw state, but instead is created from a
106 * GrXPFactory once we have finalized the state of our draw.
107 */
egdanielc2304142014-12-11 13:15:13 -0800108class GrXferProcessor : public GrProcessor {
egdaniel95131432014-12-09 11:15:43 -0800109public:
110 /**
bsalomon50785a32015-02-06 07:02:37 -0800111 * Sets a unique key on the GrProcessorKeyBuilder calls onGetGLProcessorKey(...) to get the
112 * specific subclass's key.
113 */
jvanverthcfc18862015-04-28 08:48:20 -0700114 void getGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const;
egdanielc2304142014-12-11 13:15:13 -0800115
116 /** Returns a new instance of the appropriate *GL* implementation class
117 for the given GrXferProcessor; caller is responsible for deleting
118 the object. */
119 virtual GrGLXferProcessor* createGLInstance() const = 0;
120
121 /**
egdaniel95131432014-12-09 11:15:43 -0800122 * Optimizations for blending / coverage that an OptDrawState should apply to itself.
123 */
124 enum OptFlags {
125 /**
126 * No optimizations needed
127 */
128 kNone_Opt = 0,
129 /**
130 * The draw can be skipped completely.
131 */
132 kSkipDraw_OptFlag = 0x1,
133 /**
joshualitt9b989322014-12-15 14:16:27 -0800134 * GrXferProcessor will ignore color, thus no need to provide
egdaniel95131432014-12-09 11:15:43 -0800135 */
joshualitt9b989322014-12-15 14:16:27 -0800136 kIgnoreColor_OptFlag = 0x2,
egdaniel95131432014-12-09 11:15:43 -0800137 /**
joshualitt9b989322014-12-15 14:16:27 -0800138 * GrXferProcessor will ignore coverage, thus no need to provide
egdaniel95131432014-12-09 11:15:43 -0800139 */
joshualitt9b989322014-12-15 14:16:27 -0800140 kIgnoreCoverage_OptFlag = 0x4,
egdaniel95131432014-12-09 11:15:43 -0800141 /**
egdaniel54160f32014-12-15 12:38:53 -0800142 * Clear color stages and override input color to that returned by getOptimizations
143 */
144 kOverrideColor_OptFlag = 0x8,
145 /**
egdaniel95131432014-12-09 11:15:43 -0800146 * Set CoverageDrawing_StateBit
147 */
egdaniel54160f32014-12-15 12:38:53 -0800148 kSetCoverageDrawing_OptFlag = 0x10,
egdanielf7c2d552015-02-13 12:11:00 -0800149 /**
150 * Can tweak alpha for coverage. Currently this flag should only be used by a batch
151 */
152 kCanTweakAlphaForCoverage_OptFlag = 0x20,
egdaniel95131432014-12-09 11:15:43 -0800153 };
154
155 GR_DECL_BITFIELD_OPS_FRIENDS(OptFlags);
156
157 /**
158 * Determines which optimizations (as described by the ptFlags above) can be performed by
159 * the draw with this xfer processor. If this function is called, the xfer processor may change
egdaniel54160f32014-12-15 12:38:53 -0800160 * its state to reflected the given blend optimizations. If the XP needs to see a specific input
161 * color to blend correctly, it will set the OverrideColor flag and the output parameter
162 * overrideColor will be the required value that should be passed into the XP.
egdaniel95131432014-12-09 11:15:43 -0800163 * A caller who calls this function on a XP is required to honor the returned OptFlags
egdaniel54160f32014-12-15 12:38:53 -0800164 * and color values for its draw.
egdaniel95131432014-12-09 11:15:43 -0800165 */
egdanielc19cdc22015-05-10 08:45:18 -0700166 OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
167 const GrProcOptInfo& coveragePOI,
168 bool doesStencilWrite,
169 GrColor* overrideColor,
170 const GrDrawTargetCaps& caps);
egdaniel95131432014-12-09 11:15:43 -0800171
cdalton9954bc32015-04-29 14:17:00 -0700172 /**
173 * Returns whether this XP will require an Xfer barrier on the given rt. If true, outBarrierType
174 * is updated to contain the type of barrier needed.
175 */
176 bool willNeedXferBarrier(const GrRenderTarget* rt,
177 const GrDrawTargetCaps& caps,
178 GrXferBarrierType* outBarrierType) const;
179
egdaniel95131432014-12-09 11:15:43 -0800180 struct BlendInfo {
cdaltonf4f2b442015-04-23 09:40:23 -0700181 void reset() {
cdalton8917d622015-05-06 13:40:21 -0700182 fEquation = kAdd_GrBlendEquation;
cdaltonf4f2b442015-04-23 09:40:23 -0700183 fSrcBlend = kOne_GrBlendCoeff;
184 fDstBlend = kZero_GrBlendCoeff;
185 fBlendConstant = 0;
186 fWriteColor = true;
187 }
egdaniel080e6732014-12-22 07:35:52 -0800188
bsalomonf7cc8772015-05-11 11:21:14 -0700189 SkDEBUGCODE(SkString dump() const;)
190
cdalton8917d622015-05-06 13:40:21 -0700191 GrBlendEquation fEquation;
192 GrBlendCoeff fSrcBlend;
193 GrBlendCoeff fDstBlend;
194 GrColor fBlendConstant;
195 bool fWriteColor;
egdaniel95131432014-12-09 11:15:43 -0800196 };
197
cdaltonf4f2b442015-04-23 09:40:23 -0700198 void getBlendInfo(BlendInfo* blendInfo) const {
199 blendInfo->reset();
200 this->onGetBlendInfo(blendInfo);
201 }
egdaniel95131432014-12-09 11:15:43 -0800202
egdaniel95131432014-12-09 11:15:43 -0800203 bool willReadDstColor() const { return fWillReadDstColor; }
204
bsalomon50785a32015-02-06 07:02:37 -0800205 /**
206 * Returns the texture to be used as the destination when reading the dst in the fragment
207 * shader. If the returned texture is NULL then the XP is either not reading the dst or we have
208 * extentions that support framebuffer fetching and thus don't need a copy of the dst texture.
209 */
210 const GrTexture* getDstCopyTexture() const { return fDstCopy.getTexture(); }
211
212 /**
213 * Returns the offset into the DstCopyTexture to use when reading it in the shader. This value
214 * is only valid if getDstCopyTexture() != NULL.
215 */
216 const SkIPoint& dstCopyTextureOffset() const {
217 SkASSERT(this->getDstCopyTexture());
218 return fDstCopyTextureOffset;
219 }
220
egdanielc19cdc22015-05-10 08:45:18 -0700221 /**
222 * Returns whether or not the XP will look at coverage when doing its blending.
223 */
224 bool readsCoverage() const { return fReadsCoverage; }
225
egdanielc2304142014-12-11 13:15:13 -0800226 /**
227 * Returns whether or not this xferProcossor will set a secondary output to be used with dual
228 * source blending.
229 */
230 virtual bool hasSecondaryOutput() const { return false; }
231
232 /** Returns true if this and other processor conservatively draw identically. It can only return
233 true when the two processor are of the same subclass (i.e. they return the same object from
234 from getFactory()).
235
236 A return value of true from isEqual() should not be used to test whether the processor would
237 generate the same shader code. To test for identical code generation use getGLProcessorKey*/
238
239 bool isEqual(const GrXferProcessor& that) const {
240 if (this->classID() != that.classID()) {
241 return false;
242 }
bsalomon50785a32015-02-06 07:02:37 -0800243 if (this->fWillReadDstColor != that.fWillReadDstColor) {
244 return false;
245 }
egdanielc19cdc22015-05-10 08:45:18 -0700246 if (this->fReadsCoverage != that.fReadsCoverage) {
247 return false;
248 }
bsalomon50785a32015-02-06 07:02:37 -0800249 if (this->fDstCopy.getTexture() != that.fDstCopy.getTexture()) {
250 return false;
251 }
252 if (this->fDstCopyTextureOffset != that.fDstCopyTextureOffset) {
253 return false;
254 }
egdanielc2304142014-12-11 13:15:13 -0800255 return this->onIsEqual(that);
256 }
257
egdaniel95131432014-12-09 11:15:43 -0800258protected:
bsalomon50785a32015-02-06 07:02:37 -0800259 GrXferProcessor();
260 GrXferProcessor(const GrDeviceCoordTexture* dstCopy, bool willReadDstColor);
egdaniel95131432014-12-09 11:15:43 -0800261
egdaniel378092f2014-12-03 10:40:13 -0800262private:
egdanielc19cdc22015-05-10 08:45:18 -0700263 virtual OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
264 const GrProcOptInfo& coveragePOI,
265 bool doesStencilWrite,
266 GrColor* overrideColor,
267 const GrDrawTargetCaps& caps) = 0;
268
bsalomon50785a32015-02-06 07:02:37 -0800269 /**
270 * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this xfer
271 * processor's GL backend implementation.
272 */
jvanverthcfc18862015-04-28 08:48:20 -0700273 virtual void onGetGLProcessorKey(const GrGLSLCaps& caps,
bsalomon50785a32015-02-06 07:02:37 -0800274 GrProcessorKeyBuilder* b) const = 0;
275
cdaltonf4f2b442015-04-23 09:40:23 -0700276 /**
cdalton8917d622015-05-06 13:40:21 -0700277 * If not using a texture barrier, retrieves whether the subclass will require a different type
278 * of barrier.
279 */
280 virtual bool onWillNeedXferBarrier(const GrRenderTarget*,
281 const GrDrawTargetCaps&,
282 GrXferBarrierType* outBarrierType SK_UNUSED) const {
283 return false;
284 }
285
286 /**
cdaltonf4f2b442015-04-23 09:40:23 -0700287 * Retrieves the hardware blend state required by this Xfer processor. The BlendInfo struct
288 * comes initialized to default values, so the Xfer processor only needs to set the state it
289 * needs. It may not even need to override this method at all.
290 */
291 virtual void onGetBlendInfo(BlendInfo*) const {}
292
egdanielc2304142014-12-11 13:15:13 -0800293 virtual bool onIsEqual(const GrXferProcessor&) const = 0;
egdaniel378092f2014-12-03 10:40:13 -0800294
bsalomon50785a32015-02-06 07:02:37 -0800295 bool fWillReadDstColor;
egdanielc19cdc22015-05-10 08:45:18 -0700296 bool fReadsCoverage;
bsalomon50785a32015-02-06 07:02:37 -0800297 SkIPoint fDstCopyTextureOffset;
298 GrTextureAccess fDstCopy;
egdaniel95131432014-12-09 11:15:43 -0800299
egdaniel378092f2014-12-03 10:40:13 -0800300 typedef GrFragmentProcessor INHERITED;
301};
302
egdaniel95131432014-12-09 11:15:43 -0800303GR_MAKE_BITFIELD_OPS(GrXferProcessor::OptFlags);
304
bsalomon50785a32015-02-06 07:02:37 -0800305///////////////////////////////////////////////////////////////////////////////
306
egdaniel378092f2014-12-03 10:40:13 -0800307/**
308 * We install a GrXPFactory (XPF) early on in the pipeline before all the final draw information is
309 * known (e.g. whether there is fractional pixel coverage, will coverage be 1 or 4 channel, is the
310 * draw opaque, etc.). Once the state of the draw is finalized, we use the XPF along with all the
311 * draw information to create a GrXferProcessor (XP) which can implement the desired blending for
312 * the draw.
313 *
314 * Before the XP is created, the XPF is able to answer queries about what functionality the XPs it
315 * creates will have. For example, can it create an XP that supports RGB coverage or will the XP
316 * blend with the destination color.
317 */
egdanielc016fb82014-12-03 11:41:54 -0800318class GrXPFactory : public SkRefCnt {
egdaniel378092f2014-12-03 10:40:13 -0800319public:
bsalomon50785a32015-02-06 07:02:37 -0800320 GrXferProcessor* createXferProcessor(const GrProcOptInfo& colorPOI,
321 const GrProcOptInfo& coveragePOI,
322 const GrDeviceCoordTexture* dstCopy,
323 const GrDrawTargetCaps& caps) const;
egdaniel378092f2014-12-03 10:40:13 -0800324
325 /**
326 * This function returns true if the GrXferProcessor generated from this factory will be able to
327 * correctly blend when using RGB coverage. The knownColor and knownColorFlags represent the
328 * final computed color from the color stages.
329 */
330 virtual bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const = 0;
331
egdaniel9e4ecdc2014-12-18 12:44:55 -0800332 struct InvariantOutput {
333 bool fWillBlendWithDst;
334 GrColor fBlendedColor;
335 uint32_t fBlendedColorFlags;
336 };
337
338 /**
339 * This function returns known information about the output of the xfer processor produced by
340 * this xp factory. The invariant color information returned by this function refers to the
341 * final color produced after all blending.
egdaniel95131432014-12-09 11:15:43 -0800342 */
egdaniel9e4ecdc2014-12-18 12:44:55 -0800343 virtual void getInvariantOutput(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI,
egdaniel080e6732014-12-22 07:35:52 -0800344 InvariantOutput*) const = 0;
egdaniel95131432014-12-09 11:15:43 -0800345
egdaniele36914c2015-02-13 09:00:33 -0800346 bool willNeedDstCopy(const GrDrawTargetCaps& caps, const GrProcOptInfo& colorPOI,
347 const GrProcOptInfo& coveragePOI) const;
egdaniel080e6732014-12-22 07:35:52 -0800348
egdaniel915187b2014-12-05 12:58:28 -0800349 bool isEqual(const GrXPFactory& that) const {
350 if (this->classID() != that.classID()) {
351 return false;
352 }
353 return this->onIsEqual(that);
354 }
355
356 /**
357 * Helper for down-casting to a GrXPFactory subclass
358 */
359 template <typename T> const T& cast() const { return *static_cast<const T*>(this); }
360
361 uint32_t classID() const { SkASSERT(kIllegalXPFClassID != fClassID); return fClassID; }
362
363protected:
364 GrXPFactory() : fClassID(kIllegalXPFClassID) {}
365
366 template <typename XPF_SUBCLASS> void initClassID() {
367 static uint32_t kClassID = GenClassID();
368 fClassID = kClassID;
369 }
370
371 uint32_t fClassID;
372
egdaniel378092f2014-12-03 10:40:13 -0800373private:
egdaniel3ad65702015-02-17 11:15:47 -0800374 virtual GrXferProcessor* onCreateXferProcessor(const GrDrawTargetCaps& caps,
375 const GrProcOptInfo& colorPOI,
bsalomon50785a32015-02-06 07:02:37 -0800376 const GrProcOptInfo& coveragePOI,
377 const GrDeviceCoordTexture* dstCopy) const = 0;
378 /**
379 * Returns true if the XP generated by this factory will explicitly read dst in the fragment
380 * shader.
381 */
egdaniel3ad65702015-02-17 11:15:47 -0800382 virtual bool willReadDstColor(const GrDrawTargetCaps& caps,
383 const GrProcOptInfo& colorPOI,
egdaniele36914c2015-02-13 09:00:33 -0800384 const GrProcOptInfo& coveragePOI) const = 0;
bsalomon50785a32015-02-06 07:02:37 -0800385
egdaniel915187b2014-12-05 12:58:28 -0800386 virtual bool onIsEqual(const GrXPFactory&) const = 0;
387
388 static uint32_t GenClassID() {
389 // fCurrXPFactoryID has been initialized to kIllegalXPFactoryID. The
390 // atomic inc returns the old value not the incremented value. So we add
391 // 1 to the returned value.
392 uint32_t id = static_cast<uint32_t>(sk_atomic_inc(&gCurrXPFClassID)) + 1;
393 if (!id) {
394 SkFAIL("This should never wrap as it should only be called once for each GrXPFactory "
395 "subclass.");
396 }
397 return id;
398 }
399
400 enum {
401 kIllegalXPFClassID = 0,
402 };
403 static int32_t gCurrXPFClassID;
404
egdaniel378092f2014-12-03 10:40:13 -0800405 typedef GrProgramElement INHERITED;
406};
407
408#endif
409