aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects/SkArithmeticMode_gpu.h
blob: b282e224276e35a08c450088695f07520f6afc6d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkArithmeticMode_gpu_DEFINED
#define SkArithmeticMode_gpu_DEFINED

#include "SkTypes.h"

#if SK_SUPPORT_GPU

#include "GrCoordTransform.h"
#include "GrDrawTargetCaps.h"
#include "GrFragmentProcessor.h"
#include "GrTextureAccess.h"
#include "GrTypes.h"
#include "GrXferProcessor.h"

class GrInvariantOutput;
class GrProcOptInfo;
class GrTexture;

///////////////////////////////////////////////////////////////////////////////
// Fragment Processor
///////////////////////////////////////////////////////////////////////////////

class GrGLArtithmeticFP;

class GrArithmeticFP : public GrFragmentProcessor {
public:
    static GrFragmentProcessor* Create(float k1, float k2, float k3, float k4, bool enforcePMColor,
                               GrTexture* background) {
        return SkNEW_ARGS(GrArithmeticFP, (k1, k2, k3, k4, enforcePMColor, background));
    }

    ~GrArithmeticFP() SK_OVERRIDE {};

    const char* name() const SK_OVERRIDE { return "Arithmetic"; }

    void getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE;

    GrGLFragmentProcessor* createGLInstance() const SK_OVERRIDE;

    float k1() const { return fK1; }
    float k2() const { return fK2; }
    float k3() const { return fK3; }
    float k4() const { return fK4; }
    bool enforcePMColor() const { return fEnforcePMColor; }

private:
    bool onIsEqual(const GrFragmentProcessor&) const SK_OVERRIDE;

    void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;

    GrArithmeticFP(float k1, float k2, float k3, float k4, bool enforcePMColor,
                   GrTexture* background);

    float                       fK1, fK2, fK3, fK4;
    bool                        fEnforcePMColor;
    GrCoordTransform            fBackgroundTransform;
    GrTextureAccess             fBackgroundAccess;

    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
    typedef GrFragmentProcessor INHERITED;
};

///////////////////////////////////////////////////////////////////////////////
// Xfer Processor
///////////////////////////////////////////////////////////////////////////////

class GrArithmeticXP : public GrXferProcessor {
public:
    static GrXferProcessor* Create(float k1, float k2, float k3, float k4, bool enforcePMColor,
                                         const GrDeviceCoordTexture* dstCopy,
                                         bool willReadDstColor) {
        return SkNEW_ARGS(GrArithmeticXP, (k1, k2, k3, k4, enforcePMColor, dstCopy,
                                           willReadDstColor));
    }

    ~GrArithmeticXP() SK_OVERRIDE {};

    const char* name() const SK_OVERRIDE { return "Arithmetic"; }

    GrGLXferProcessor* createGLInstance() const SK_OVERRIDE;

    bool hasSecondaryOutput() const SK_OVERRIDE { return false; }

    GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
                                               const GrProcOptInfo& coveragePOI,
                                               bool doesStencilWrite,
                                               GrColor* overrideColor,
                                               const GrDrawTargetCaps& caps) SK_OVERRIDE;

    void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE {
        blendInfo->fSrcBlend = kOne_GrBlendCoeff;
        blendInfo->fDstBlend = kZero_GrBlendCoeff;
        blendInfo->fBlendConstant = 0;
    }

    float k1() const { return fK1; }
    float k2() const { return fK2; }
    float k3() const { return fK3; }
    float k4() const { return fK4; }
    bool enforcePMColor() const { return fEnforcePMColor; }

private:
    GrArithmeticXP(float k1, float k2, float k3, float k4, bool enforcePMColor,
                   const GrDeviceCoordTexture* dstCopy, bool willReadDstColor);

    void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE;

    bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE {
        const GrArithmeticXP& xp = xpBase.cast<GrArithmeticXP>();
        if (fK1 != xp.fK1 ||
            fK2 != xp.fK2 ||
            fK3 != xp.fK3 ||
            fK4 != xp.fK4 ||
            fEnforcePMColor != xp.fEnforcePMColor) {
            return false;
        }
        return true;
    }

    float                       fK1, fK2, fK3, fK4;
    bool                        fEnforcePMColor;

    typedef GrXferProcessor INHERITED;
};

///////////////////////////////////////////////////////////////////////////////

class GrArithmeticXPFactory : public GrXPFactory {
public:
    static GrXPFactory* Create(float k1, float k2, float k3, float k4, bool enforcePMColor) {
        return SkNEW_ARGS(GrArithmeticXPFactory, (k1, k2, k3, k4, enforcePMColor));
    }

    bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const SK_OVERRIDE {
        return true;
    }

    bool canApplyCoverage(const GrProcOptInfo& colorPOI,
                          const GrProcOptInfo& coveragePOI) const SK_OVERRIDE {
        return true;
    }

    bool canTweakAlphaForCoverage() const SK_OVERRIDE {
        return false;
    }

    void getInvariantOutput(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI,
                            GrXPFactory::InvariantOutput*) const SK_OVERRIDE;

private:
    GrArithmeticXPFactory(float k1, float k2, float k3, float k4, bool enforcePMColor); 

    GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI,
                                           const GrProcOptInfo& coveragePOI,
                                           const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE {
        return GrArithmeticXP::Create(fK1, fK2, fK3, fK4, fEnforcePMColor, dstCopy,
                                      this->willReadDstColor());
    }

    bool willReadDstColor() const SK_OVERRIDE { return true; }

    bool onIsEqual(const GrXPFactory& xpfBase) const SK_OVERRIDE {
        const GrArithmeticXPFactory& xpf = xpfBase.cast<GrArithmeticXPFactory>();
        if (fK1 != xpf.fK1 ||
            fK2 != xpf.fK2 ||
            fK3 != xpf.fK3 ||
            fK4 != xpf.fK4 ||
            fEnforcePMColor != xpf.fEnforcePMColor) {
            return false;
        }
        return true;
    }

    GR_DECLARE_XP_FACTORY_TEST;

    float                       fK1, fK2, fK3, fK4;
    bool                        fEnforcePMColor;

    typedef GrXPFactory INHERITED;
};

#endif
#endif