GrPorterDuffXferProcessor.h revision 50785a3d10b53bea5beb6e18431a2449860be237
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 GrPorterDuffXferProcessor_DEFINED
9#define GrPorterDuffXferProcessor_DEFINED
10
11#include "GrTypes.h"
12#include "GrXferProcessor.h"
13#include "SkXfermode.h"
14
15class GrDrawTargetCaps;
16class GrProcOptInfo;
17
18class GrPorterDuffXferProcessor : public GrXferProcessor {
19public:
20    static GrXferProcessor* Create(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend,
21                                   GrColor constant, const GrDeviceCoordTexture* dstCopy,
22                                   bool willReadDstColor) {
23        return SkNEW_ARGS(GrPorterDuffXferProcessor, (srcBlend, dstBlend, constant, dstCopy,
24                                                      willReadDstColor));
25    }
26
27    ~GrPorterDuffXferProcessor() SK_OVERRIDE;
28
29    const char* name() const SK_OVERRIDE { return "Porter Duff"; }
30
31    GrGLXferProcessor* createGLInstance() const SK_OVERRIDE;
32
33    bool hasSecondaryOutput() const SK_OVERRIDE;
34
35    ///////////////////////////////////////////////////////////////////////////
36    /// @name Stage Output Types
37    ////
38
39    enum PrimaryOutputType {
40        kNone_PrimaryOutputType,
41        kColor_PrimaryOutputType,
42        kCoverage_PrimaryOutputType,
43        // Modulate color and coverage, write result as the color output.
44        kModulate_PrimaryOutputType,
45    };
46
47    enum SecondaryOutputType {
48        // There is no secondary output
49        kNone_SecondaryOutputType,
50        // Writes coverage as the secondary output. Only set if dual source blending is supported
51        // and primary output is kModulate.
52        kCoverage_SecondaryOutputType,
53        // Writes coverage * (1 - colorA) as the secondary output. Only set if dual source blending
54        // is supported and primary output is kModulate.
55        kCoverageISA_SecondaryOutputType,
56        // Writes coverage * (1 - colorRGBA) as the secondary output. Only set if dual source
57        // blending is supported and primary output is kModulate.
58        kCoverageISC_SecondaryOutputType,
59
60        kSecondaryOutputTypeCnt,
61    };
62
63    PrimaryOutputType primaryOutputType() const { return fPrimaryOutputType; }
64    SecondaryOutputType secondaryOutputType() const { return fSecondaryOutputType; }
65
66    GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
67                                               const GrProcOptInfo& coveragePOI,
68                                               bool doesStencilWrite,
69                                               GrColor* overrideColor,
70                                               const GrDrawTargetCaps& caps) SK_OVERRIDE;
71
72    void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE {
73        blendInfo->fSrcBlend = fSrcBlend;
74        blendInfo->fDstBlend = fDstBlend;
75        blendInfo->fBlendConstant = fBlendConstant;
76    }
77
78private:
79    GrPorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, GrColor constant,
80                              const GrDeviceCoordTexture* dstCopy, bool willReadDstColor);
81
82    void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE;
83
84    bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE {
85        const GrPorterDuffXferProcessor& xp = xpBase.cast<GrPorterDuffXferProcessor>();
86        if (fSrcBlend != xp.fSrcBlend ||
87            fDstBlend != xp.fDstBlend ||
88            fBlendConstant != xp.fBlendConstant ||
89            fPrimaryOutputType != xp.fPrimaryOutputType ||
90            fSecondaryOutputType != xp.fSecondaryOutputType) {
91            return false;
92        }
93        return true;
94    }
95
96    GrXferProcessor::OptFlags internalGetOptimizations(const GrProcOptInfo& colorPOI,
97                                                       const GrProcOptInfo& coveragePOI,
98                                                       bool doesStencilWrite);
99
100    void calcOutputTypes(GrXferProcessor::OptFlags blendOpts, const GrDrawTargetCaps& caps,
101                         bool hasSolidCoverage);
102
103    GrBlendCoeff fSrcBlend;
104    GrBlendCoeff fDstBlend;
105    GrColor      fBlendConstant;
106    PrimaryOutputType fPrimaryOutputType;
107    SecondaryOutputType fSecondaryOutputType;
108
109    typedef GrXferProcessor INHERITED;
110};
111
112///////////////////////////////////////////////////////////////////////////////
113
114class GrPorterDuffXPFactory : public GrXPFactory {
115public:
116    static GrXPFactory* Create(SkXfermode::Mode mode);
117
118    static GrXPFactory* Create(SkXfermode::Coeff src, SkXfermode::Coeff dst) {
119        return SkNEW_ARGS(GrPorterDuffXPFactory, ((GrBlendCoeff)(src), (GrBlendCoeff)(dst)));
120    }
121
122    static GrXPFactory* Create(GrBlendCoeff src, GrBlendCoeff dst) {
123        return SkNEW_ARGS(GrPorterDuffXPFactory, (src, dst));
124    }
125
126    bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const SK_OVERRIDE;
127
128    bool canApplyCoverage(const GrProcOptInfo& colorPOI,
129                          const GrProcOptInfo& coveragePOI) const SK_OVERRIDE;
130
131    bool canTweakAlphaForCoverage() const SK_OVERRIDE;
132
133    void getInvariantOutput(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI,
134                            GrXPFactory::InvariantOutput*) const SK_OVERRIDE;
135
136private:
137    GrPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst);
138
139    GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI,
140                                           const GrProcOptInfo& coveragePOI,
141                                           const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE;
142
143    bool willReadDstColor() const SK_OVERRIDE;
144
145    bool onIsEqual(const GrXPFactory& xpfBase) const SK_OVERRIDE {
146        const GrPorterDuffXPFactory& xpf = xpfBase.cast<GrPorterDuffXPFactory>();
147        return (fSrcCoeff == xpf.fSrcCoeff && fDstCoeff == xpf.fDstCoeff);
148    }
149
150    GR_DECLARE_XP_FACTORY_TEST;
151
152    GrBlendCoeff fSrcCoeff;
153    GrBlendCoeff fDstCoeff;
154
155    typedef GrXPFactory INHERITED;
156};
157
158#endif
159