Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / include / gpu / GrPaint.h
1
2 /*
3  * Copyright 2011 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8
9
10 #ifndef GrPaint_DEFINED
11 #define GrPaint_DEFINED
12
13 #include "GrColor.h"
14 #include "GrProcessorStage.h"
15
16 #include "SkXfermode.h"
17
18 /**
19  * The paint describes how color and coverage are computed at each pixel by GrContext draw
20  * functions and the how color is blended with the destination pixel.
21  *
22  * The paint allows installation of custom color and coverage stages. New types of stages are
23  * created by subclassing GrProcessor.
24  *
25  * The primitive color computation starts with the color specified by setColor(). This color is the
26  * input to the first color stage. Each color stage feeds its output to the next color stage. The
27  * final color stage's output color is input to the color filter specified by
28  * setXfermodeColorFilter which produces the final source color, S.
29  *
30  * Fractional pixel coverage follows a similar flow. The coverage is initially the value specified
31  * by setCoverage(). This is input to the first coverage stage. Coverage stages are chained
32  * together in the same manner as color stages. The output of the last stage is modulated by any
33  * fractional coverage produced by anti-aliasing. This last step produces the final coverage, C.
34  *
35  * setBlendFunc() specifies blending coefficients for S (described above) and D, the initial value
36  * of the destination pixel, labeled Bs and Bd respectively. The final value of the destination
37  * pixel is then D' = (1-C)*D + C*(Bd*D + Bs*S).
38  *
39  * Note that the coverage is applied after the blend. This is why they are computed as distinct
40  * values.
41  *
42  * TODO: Encapsulate setXfermodeColorFilter in a GrProcessor and remove from GrPaint.
43  */
44 class GrPaint {
45 public:
46     GrPaint() { this->reset(); }
47
48     GrPaint(const GrPaint& paint) { *this = paint; }
49
50     ~GrPaint() {}
51
52     /**
53      * Sets the blending coefficients to use to blend the final primitive color with the
54      * destination color. Defaults to kOne for src and kZero for dst (i.e. src mode).
55      */
56     void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
57         fSrcBlendCoeff = srcCoeff;
58         fDstBlendCoeff = dstCoeff;
59     }
60     GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlendCoeff; }
61     GrBlendCoeff getDstBlendCoeff() const { return fDstBlendCoeff; }
62
63     /**
64      * The initial color of the drawn primitive. Defaults to solid white.
65      */
66     void setColor(GrColor color) { fColor = color; }
67     GrColor getColor() const { return fColor; }
68
69     /**
70      * Applies fractional coverage to the entire drawn primitive. Defaults to 0xff.
71      */
72     void setCoverage(uint8_t coverage) { fCoverage = coverage; }
73     uint8_t getCoverage() const { return fCoverage; }
74
75     /**
76      * Should primitives be anti-aliased or not. Defaults to false.
77      */
78     void setAntiAlias(bool aa) { fAntiAlias = aa; }
79     bool isAntiAlias() const { return fAntiAlias; }
80
81     /**
82      * Should dithering be applied. Defaults to false.
83      */
84     void setDither(bool dither) { fDither = dither; }
85     bool isDither() const { return fDither; }
86
87     /**
88      * Appends an additional color processor to the color computation.
89      */
90     const GrFragmentProcessor* addColorProcessor(const GrFragmentProcessor* fp) {
91         SkASSERT(fp);
92         if (!fp->willUseInputColor()) {
93             fColorStages.reset();
94         }
95         SkNEW_APPEND_TO_TARRAY(&fColorStages, GrProcessorStage, (fp));
96         return fp;
97     }
98
99     /**
100      * Appends an additional coverage processor to the coverage computation.
101      */
102     const GrFragmentProcessor* addCoverageProcessor(const GrFragmentProcessor* fp) {
103         SkASSERT(fp);
104         if (!fp->willUseInputColor()) {
105             fCoverageStages.reset();
106         }
107         SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrProcessorStage, (fp));
108         return fp;
109     }
110
111     /**
112      * Helpers for adding color or coverage effects that sample a texture. The matrix is applied
113      * to the src space position to compute texture coordinates.
114      */
115     void addColorTextureProcessor(GrTexture*, const SkMatrix&);
116     void addCoverageTextureProcessor(GrTexture*, const SkMatrix&);
117     void addColorTextureProcessor(GrTexture*, const SkMatrix&, const GrTextureParams&);
118     void addCoverageTextureProcessor(GrTexture*, const SkMatrix&, const GrTextureParams&);
119
120     int numColorStages() const { return fColorStages.count(); }
121     int numCoverageStages() const { return fCoverageStages.count(); }
122     int numTotalStages() const { return this->numColorStages() + this->numCoverageStages(); }
123
124     const GrFragmentStage& getColorStage(int s) const { return fColorStages[s]; }
125     const GrFragmentStage& getCoverageStage(int s) const { return fCoverageStages[s]; }
126
127     GrPaint& operator=(const GrPaint& paint) {
128         fSrcBlendCoeff = paint.fSrcBlendCoeff;
129         fDstBlendCoeff = paint.fDstBlendCoeff;
130         fAntiAlias = paint.fAntiAlias;
131         fDither = paint.fDither;
132
133         fColor = paint.fColor;
134         fCoverage = paint.fCoverage;
135
136         fColorStages = paint.fColorStages;
137         fCoverageStages = paint.fCoverageStages;
138
139         return *this;
140     }
141
142     /**
143      * Resets the paint to the defaults.
144      */
145     void reset() {
146         this->resetBlend();
147         this->resetOptions();
148         this->resetColor();
149         this->resetCoverage();
150         this->resetStages();
151     }
152
153     /**
154      * Determines whether the drawing with this paint is opaque with respect to both color blending
155      * and fractional coverage. It does not consider whether AA has been enabled on the paint or
156      * not. Depending upon whether multisampling or coverage-based AA is in use, AA may make the
157      * result only apply to the interior of primitives.
158      *
159      */
160     bool isOpaque() const;
161
162     /**
163      * Returns true if isOpaque would return true and the paint represents a solid constant color
164      * draw. If the result is true, constantColor will be updated to contain the constant color.
165      */
166     bool isOpaqueAndConstantColor(GrColor* constantColor) const;
167
168 private:
169
170     /**
171      * Helper for isOpaque and isOpaqueAndConstantColor.
172      */
173     bool getOpaqueAndKnownColor(GrColor* solidColor, uint32_t* solidColorKnownComponents) const;
174
175     /**
176      * Called when the source coord system from which geometry is rendered changes. It ensures that
177      * the local coordinates seen by effects remains unchanged. oldToNew gives the transformation
178      * from the previous coord system to the new coord system.
179      */
180     void localCoordChange(const SkMatrix& oldToNew) {
181         for (int i = 0; i < fColorStages.count(); ++i) {
182             fColorStages[i].localCoordChange(oldToNew);
183         }
184         for (int i = 0; i < fCoverageStages.count(); ++i) {
185             fCoverageStages[i].localCoordChange(oldToNew);
186         }
187     }
188
189     bool localCoordChangeInverse(const SkMatrix& newToOld) {
190         SkMatrix oldToNew;
191         bool computed = false;
192         for (int i = 0; i < fColorStages.count(); ++i) {
193             if (!computed && !newToOld.invert(&oldToNew)) {
194                 return false;
195             } else {
196                 computed = true;
197             }
198             fColorStages[i].localCoordChange(oldToNew);
199         }
200         for (int i = 0; i < fCoverageStages.count(); ++i) {
201             if (!computed && !newToOld.invert(&oldToNew)) {
202                 return false;
203             } else {
204                 computed = true;
205             }
206             fCoverageStages[i].localCoordChange(oldToNew);
207         }
208         return true;
209     }
210
211     friend class GrContext; // To access above two functions
212     friend class GrStencilAndCoverTextContext;  // To access above two functions
213
214     SkSTArray<4, GrFragmentStage> fColorStages;
215     SkSTArray<2, GrFragmentStage> fCoverageStages;
216
217     GrBlendCoeff                fSrcBlendCoeff;
218     GrBlendCoeff                fDstBlendCoeff;
219     bool                        fAntiAlias;
220     bool                        fDither;
221
222     GrColor                     fColor;
223     uint8_t                     fCoverage;
224
225     void resetBlend() {
226         fSrcBlendCoeff = kOne_GrBlendCoeff;
227         fDstBlendCoeff = kZero_GrBlendCoeff;
228     }
229
230     void resetOptions() {
231         fAntiAlias = false;
232         fDither = false;
233     }
234
235     void resetColor() {
236         fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
237     }
238
239     void resetCoverage() {
240         fCoverage = 0xff;
241     }
242
243     void resetStages() {
244         fColorStages.reset();
245         fCoverageStages.reset();
246     }
247 };
248
249 #endif