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 "GrXferProcessor.h"
15 #include "effects/GrPorterDuffXferProcessor.h"
16 #include "GrFragmentProcessor.h"
17 
18 #include "SkRegion.h"
19 #include "SkXfermode.h"
20 
21 /**
22  * The paint describes how color and coverage are computed at each pixel by GrContext draw
23  * functions and the how color is blended with the destination pixel.
24  *
25  * The paint allows installation of custom color and coverage stages. New types of stages are
26  * created by subclassing GrProcessor.
27  *
28  * The primitive color computation starts with the color specified by setColor(). This color is the
29  * input to the first color stage. Each color stage feeds its output to the next color stage.
30  *
31  * Fractional pixel coverage follows a similar flow. The coverage is initially the value specified
32  * by setCoverage(). This is input to the first coverage stage. Coverage stages are chained
33  * together in the same manner as color stages. The output of the last stage is modulated by any
34  * fractional coverage produced by anti-aliasing. This last step produces the final coverage, C.
35  *
36  * setXPFactory is used to control blending between the output color and dest. It also implements
37  * the application of fractional coverage from the coverage pipeline.
38  */
39 class GrPaint {
40 public:
41     GrPaint();
42 
GrPaint(const GrPaint & paint)43     GrPaint(const GrPaint& paint) { *this = paint; }
44 
~GrPaint()45     ~GrPaint() { this->resetFragmentProcessors();  }
46 
47     /**
48      * The initial color of the drawn primitive. Defaults to solid white.
49      */
setColor(GrColor color)50     void setColor(GrColor color) { fColor = color; }
getColor()51     GrColor getColor() const { return fColor; }
52 
53     /**
54      * Should primitives be anti-aliased or not. Defaults to false.
55      */
setAntiAlias(bool aa)56     void setAntiAlias(bool aa) { fAntiAlias = aa; }
isAntiAlias()57     bool isAntiAlias() const { return fAntiAlias; }
58 
setXPFactory(const GrXPFactory * xpFactory)59     const GrXPFactory* setXPFactory(const GrXPFactory* xpFactory) {
60         fXPFactory.reset(SkSafeRef(xpFactory));
61         return xpFactory;
62     }
63 
setPorterDuffXPFactory(SkXfermode::Mode mode)64     void setPorterDuffXPFactory(SkXfermode::Mode mode) {
65         fXPFactory.reset(GrPorterDuffXPFactory::Create(mode));
66     }
67 
68     void setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage = false);
69 
70     /**
71      * Appends an additional color processor to the color computation.
72      */
addColorFragmentProcessor(const GrFragmentProcessor * fp)73     const GrFragmentProcessor* addColorFragmentProcessor(const GrFragmentProcessor* fp) {
74         SkASSERT(fp);
75         fColorFragmentProcessors.push_back(SkRef(fp));
76         return fp;
77     }
78 
79     /**
80      * Appends an additional coverage processor to the coverage computation.
81      */
addCoverageFragmentProcessor(const GrFragmentProcessor * fp)82     const GrFragmentProcessor* addCoverageFragmentProcessor(const GrFragmentProcessor* fp) {
83         SkASSERT(fp);
84         fCoverageFragmentProcessors.push_back(SkRef(fp));
85         return fp;
86     }
87 
88     /**
89      * Helpers for adding color or coverage effects that sample a texture. The matrix is applied
90      * to the src space position to compute texture coordinates.
91      */
92     void addColorTextureProcessor(GrTexture*, const SkMatrix&);
93     void addCoverageTextureProcessor(GrTexture*, const SkMatrix&);
94     void addColorTextureProcessor(GrTexture*, const SkMatrix&, const GrTextureParams&);
95     void addCoverageTextureProcessor(GrTexture*, const SkMatrix&, const GrTextureParams&);
96 
numColorFragmentProcessors()97     int numColorFragmentProcessors() const { return fColorFragmentProcessors.count(); }
numCoverageFragmentProcessors()98     int numCoverageFragmentProcessors() const { return fCoverageFragmentProcessors.count(); }
numTotalFragmentProcessors()99     int numTotalFragmentProcessors() const { return this->numColorFragmentProcessors() +
100                                               this->numCoverageFragmentProcessors(); }
101 
getXPFactory()102     const GrXPFactory* getXPFactory() const {
103         return fXPFactory;
104     }
105 
getColorFragmentProcessor(int i)106     const GrFragmentProcessor* getColorFragmentProcessor(int i) const {
107         return fColorFragmentProcessors[i];
108     }
getCoverageFragmentProcessor(int i)109     const GrFragmentProcessor* getCoverageFragmentProcessor(int i) const {
110         return fCoverageFragmentProcessors[i];
111     }
112 
113     GrPaint& operator=(const GrPaint& paint) {
114         fAntiAlias = paint.fAntiAlias;
115 
116         fColor = paint.fColor;
117         this->resetFragmentProcessors();
118         fColorFragmentProcessors = paint.fColorFragmentProcessors;
119         fCoverageFragmentProcessors = paint.fCoverageFragmentProcessors;
120         for (int i = 0; i < fColorFragmentProcessors.count(); ++i) {
121             fColorFragmentProcessors[i]->ref();
122         }
123         for (int i = 0; i < fCoverageFragmentProcessors.count(); ++i) {
124             fCoverageFragmentProcessors[i]->ref();
125         }
126 
127         fXPFactory.reset(SkSafeRef(paint.getXPFactory()));
128 
129         return *this;
130     }
131 
132     /**
133      * Returns true if the paint's output color will be constant after blending. If the result is
134      * true, constantColor will be updated to contain the constant color. Note that we can conflate
135      * coverage and color, so the actual values written to pixels with partial coverage may still
136      * not seem constant, even if this function returns true.
137      */
138     bool isConstantBlendedColor(GrColor* constantColor) const;
139 
140 private:
resetFragmentProcessors()141     void resetFragmentProcessors() {
142         for (int i = 0; i < fColorFragmentProcessors.count(); ++i) {
143             fColorFragmentProcessors[i]->unref();
144         }
145         for (int i = 0; i < fCoverageFragmentProcessors.count(); ++i) {
146             fCoverageFragmentProcessors[i]->unref();
147         }
148         fColorFragmentProcessors.reset();
149         fCoverageFragmentProcessors.reset();
150     }
151 
152     mutable SkAutoTUnref<const GrXPFactory>         fXPFactory;
153     SkSTArray<4, const GrFragmentProcessor*, true>  fColorFragmentProcessors;
154     SkSTArray<2, const GrFragmentProcessor*, true>  fCoverageFragmentProcessors;
155 
156     bool                                            fAntiAlias;
157 
158     GrColor                                         fColor;
159 };
160 
161 #endif
162