1/*
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"
12#include "GrProcessor.h"
13#include "GrTexture.h"
14#include "GrTypes.h"
15#include "SkXfermode.h"
16
17class GrShaderCaps;
18class GrGLSLCaps;
19class GrGLXferProcessor;
20class GrProcOptInfo;
21
22/**
23 * Equations for alpha-blending.
24 */
25enum GrBlendEquation {
26    // 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
48    kFirstAdvancedGrBlendEquation = kScreen_GrBlendEquation,
49    kLast_GrBlendEquation = kHSLLuminosity_GrBlendEquation
50};
51
52static const int kGrBlendEquationCnt = kLast_GrBlendEquation + 1;
53
54inline bool GrBlendEquationIsAdvanced(GrBlendEquation equation) {
55    return equation >= kFirstAdvancedGrBlendEquation;
56}
57
58/**
59 * Coeffecients for alpha-blending.
60 */
61enum GrBlendCoeff {
62    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
81    kLast_GrBlendCoeff = kIS2A_GrBlendCoeff
82};
83
84static const int kGrBlendCoeffCnt = kLast_GrBlendCoeff + 1;
85
86/**
87 * 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.
92    kBlend_GrXferBarrierType,   //<! Required by certain blend extensions.
93};
94
95/**
96 * 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 */
108class GrXferProcessor : public GrProcessor {
109public:
110    /**
111     * Sets a unique key on the GrProcessorKeyBuilder calls onGetGLProcessorKey(...) to get the
112     * specific subclass's key.
113     */
114    void getGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const;
115
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    /**
122     * 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        /**
134         * GrXferProcessor will ignore color, thus no need to provide
135         */
136        kIgnoreColor_OptFlag              = 0x2,
137        /**
138         * GrXferProcessor will ignore coverage, thus no need to provide
139         */
140        kIgnoreCoverage_OptFlag           = 0x4,
141        /**
142         * Clear color stages and override input color to that returned by getOptimizations
143         */
144        kOverrideColor_OptFlag            = 0x8,
145        /**
146         * Set CoverageDrawing_StateBit
147         */
148        kSetCoverageDrawing_OptFlag       = 0x10,
149        /**
150         * Can tweak alpha for coverage. Currently this flag should only be used by a batch
151         */
152        kCanTweakAlphaForCoverage_OptFlag = 0x20,
153    };
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
160     * 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.
163     * A caller who calls this function on a XP is required to honor the returned OptFlags
164     * and color values for its draw.
165     */
166    OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
167                              const GrProcOptInfo& coveragePOI,
168                              bool doesStencilWrite,
169                              GrColor* overrideColor,
170                              const GrDrawTargetCaps& caps);
171
172    /**
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
180    struct BlendInfo {
181        void reset() {
182            fEquation = kAdd_GrBlendEquation;
183            fSrcBlend = kOne_GrBlendCoeff;
184            fDstBlend = kZero_GrBlendCoeff;
185            fBlendConstant = 0;
186            fWriteColor = true;
187        }
188
189        SkDEBUGCODE(SkString dump() const;)
190
191        GrBlendEquation fEquation;
192        GrBlendCoeff    fSrcBlend;
193        GrBlendCoeff    fDstBlend;
194        GrColor         fBlendConstant;
195        bool            fWriteColor;
196    };
197
198    void getBlendInfo(BlendInfo* blendInfo) const {
199        blendInfo->reset();
200        this->onGetBlendInfo(blendInfo);
201    }
202
203    bool willReadDstColor() const { return fWillReadDstColor; }
204
205    /**
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
221    /**
222     * Returns whether or not the XP will look at coverage when doing its blending.
223     */
224    bool readsCoverage() const { return fReadsCoverage; }
225
226    /**
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        }
243        if (this->fWillReadDstColor != that.fWillReadDstColor) {
244            return false;
245        }
246        if (this->fReadsCoverage != that.fReadsCoverage) {
247            return false;
248        }
249        if (this->fDstCopy.getTexture() != that.fDstCopy.getTexture()) {
250            return false;
251        }
252        if (this->fDstCopyTextureOffset != that.fDstCopyTextureOffset) {
253            return false;
254        }
255        return this->onIsEqual(that);
256    }
257
258protected:
259    GrXferProcessor();
260    GrXferProcessor(const GrDeviceCoordTexture* dstCopy, bool willReadDstColor);
261
262private:
263    virtual OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
264                                        const GrProcOptInfo& coveragePOI,
265                                        bool doesStencilWrite,
266                                        GrColor* overrideColor,
267                                        const GrDrawTargetCaps& caps) = 0;
268
269    /**
270     * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this xfer
271     * processor's GL backend implementation.
272     */
273    virtual void onGetGLProcessorKey(const GrGLSLCaps& caps,
274                                     GrProcessorKeyBuilder* b) const = 0;
275
276    /**
277     * 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    /**
287     * 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
293    virtual bool onIsEqual(const GrXferProcessor&) const = 0;
294
295    bool                    fWillReadDstColor;
296    bool                    fReadsCoverage;
297    SkIPoint                fDstCopyTextureOffset;
298    GrTextureAccess         fDstCopy;
299
300    typedef GrFragmentProcessor INHERITED;
301};
302
303GR_MAKE_BITFIELD_OPS(GrXferProcessor::OptFlags);
304
305///////////////////////////////////////////////////////////////////////////////
306
307/**
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 */
318class GrXPFactory : public SkRefCnt {
319public:
320    GrXferProcessor* createXferProcessor(const GrProcOptInfo& colorPOI,
321                                         const GrProcOptInfo& coveragePOI,
322                                         const GrDeviceCoordTexture* dstCopy,
323                                         const GrDrawTargetCaps& caps) const;
324
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
332    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.
342     */
343    virtual void getInvariantOutput(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI,
344                                    InvariantOutput*) const = 0;
345
346    bool willNeedDstCopy(const GrDrawTargetCaps& caps, const GrProcOptInfo& colorPOI,
347                         const GrProcOptInfo& coveragePOI) const;
348
349    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
373private:
374    virtual GrXferProcessor* onCreateXferProcessor(const GrDrawTargetCaps& caps,
375                                                   const GrProcOptInfo& colorPOI,
376                                                   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     */
382    virtual bool willReadDstColor(const GrDrawTargetCaps& caps,
383                                  const GrProcOptInfo& colorPOI,
384                                  const GrProcOptInfo& coveragePOI) const = 0;
385
386    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
405    typedef GrProgramElement INHERITED;
406};
407
408#endif
409
410