• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "GrColorSpaceXform.h"
15 #include "GrFragmentProcessor.h"
16 #include "SkBlendMode.h"
17 #include "SkRefCnt.h"
18 #include "SkRegion.h"
19 #include "SkTLazy.h"
20 
21 class GrTextureProxy;
22 class GrXPFactory;
23 
24 /**
25  * The paint describes how color and coverage are computed at each pixel by GrContext draw
26  * functions and the how color is blended with the destination pixel.
27  *
28  * The paint allows installation of custom color and coverage stages. New types of stages are
29  * created by subclassing GrProcessor.
30  *
31  * The primitive color computation starts with the color specified by setColor(). This color is the
32  * input to the first color stage. Each color stage feeds its output to the next color stage.
33  *
34  * Fractional pixel coverage follows a similar flow. The GrGeometryProcessor (specified elsewhere)
35  * provides the initial coverage which is passed to the first coverage fragment processor, which
36  * feeds its output to next coverage fragment processor.
37  *
38  * setXPFactory is used to control blending between the output color and dest. It also implements
39  * the application of fractional coverage from the coverage pipeline.
40  */
41 class GrPaint {
42 public:
43     GrPaint() = default;
44     explicit GrPaint(const GrPaint&) = default;
45     ~GrPaint() = default;
46 
47     /**
48      * The initial color of the drawn primitive. Defaults to solid white.
49      */
setColor4f(const GrColor4f & color)50     void setColor4f(const GrColor4f& color) { fColor = color; }
getColor4f()51     const GrColor4f& getColor4f() const { return fColor; }
52 
53     /**
54      * Legacy getter, until all code handles 4f directly.
55      */
getColor()56     GrColor getColor() const { return fColor.toGrColor(); }
57 
58     /**
59      * Should shader output conversion from linear to sRGB be disabled.
60      * Only relevant if the destination is sRGB. Defaults to false.
61      */
setDisableOutputConversionToSRGB(bool srgb)62     void setDisableOutputConversionToSRGB(bool srgb) { fDisableOutputConversionToSRGB = srgb; }
getDisableOutputConversionToSRGB()63     bool getDisableOutputConversionToSRGB() const { return fDisableOutputConversionToSRGB; }
64 
65     /**
66      * Should sRGB inputs be allowed to perform sRGB to linear conversion. With this flag
67      * set to false, sRGB textures will be treated as linear (including filtering).
68      */
setAllowSRGBInputs(bool allowSRGBInputs)69     void setAllowSRGBInputs(bool allowSRGBInputs) { fAllowSRGBInputs = allowSRGBInputs; }
getAllowSRGBInputs()70     bool getAllowSRGBInputs() const { return fAllowSRGBInputs; }
71 
72     /**
73      * Should rendering be gamma-correct, end-to-end. Causes sRGB render targets to behave
74      * as such (with linear blending), and sRGB inputs to be filtered and decoded correctly.
75      */
setGammaCorrect(bool gammaCorrect)76     void setGammaCorrect(bool gammaCorrect) {
77         this->setDisableOutputConversionToSRGB(!gammaCorrect);
78         this->setAllowSRGBInputs(gammaCorrect);
79     }
80 
setXPFactory(const GrXPFactory * xpFactory)81     void setXPFactory(const GrXPFactory* xpFactory) {
82         fXPFactory = xpFactory;
83         fTrivial &= !SkToBool(xpFactory);
84     }
85 
86     void setPorterDuffXPFactory(SkBlendMode mode);
87 
88     void setCoverageSetOpXPFactory(SkRegion::Op, bool invertCoverage = false);
89 
90     /**
91      * Appends an additional color processor to the color computation.
92      */
addColorFragmentProcessor(sk_sp<GrFragmentProcessor> fp)93     void addColorFragmentProcessor(sk_sp<GrFragmentProcessor> fp) {
94         SkASSERT(fp);
95         fColorFragmentProcessors.push_back(std::move(fp));
96         fTrivial = false;
97     }
98 
99     /**
100      * Appends an additional coverage processor to the coverage computation.
101      */
addCoverageFragmentProcessor(sk_sp<GrFragmentProcessor> fp)102     void addCoverageFragmentProcessor(sk_sp<GrFragmentProcessor> fp) {
103         SkASSERT(fp);
104         fCoverageFragmentProcessors.push_back(std::move(fp));
105         fTrivial = false;
106     }
107 
108     /**
109      * Helpers for adding color or coverage effects that sample a texture. The matrix is applied
110      * to the src space position to compute texture coordinates.
111      */
112     void addColorTextureProcessor(sk_sp<GrTextureProxy>,
113                                   sk_sp<GrColorSpaceXform>, const SkMatrix&);
114     void addColorTextureProcessor(sk_sp<GrTextureProxy>,
115                                   sk_sp<GrColorSpaceXform>, const SkMatrix&,
116                                   const GrSamplerParams&);
117 
118     void addCoverageTextureProcessor(sk_sp<GrTextureProxy>, const SkMatrix&);
119     void addCoverageTextureProcessor(sk_sp<GrTextureProxy>,
120                                      const SkMatrix&, const GrSamplerParams&);
121 
numColorFragmentProcessors()122     int numColorFragmentProcessors() const { return fColorFragmentProcessors.count(); }
numCoverageFragmentProcessors()123     int numCoverageFragmentProcessors() const { return fCoverageFragmentProcessors.count(); }
numTotalFragmentProcessors()124     int numTotalFragmentProcessors() const { return this->numColorFragmentProcessors() +
125                                               this->numCoverageFragmentProcessors(); }
126 
getXPFactory()127     const GrXPFactory* getXPFactory() const { return fXPFactory; }
128 
getColorFragmentProcessor(int i)129     GrFragmentProcessor* getColorFragmentProcessor(int i) const {
130         return fColorFragmentProcessors[i].get();
131     }
getCoverageFragmentProcessor(int i)132     GrFragmentProcessor* getCoverageFragmentProcessor(int i) const {
133         return fCoverageFragmentProcessors[i].get();
134     }
135 
136     /**
137      * Returns true if the paint's output color will be constant after blending. If the result is
138      * true, constantColor will be updated to contain the constant color. Note that we can conflate
139      * coverage and color, so the actual values written to pixels with partial coverage may still
140      * not seem constant, even if this function returns true.
141      */
142     bool isConstantBlendedColor(GrColor* constantColor) const;
143 
144     /**
145      * A trivial paint is one that uses src-over and has no fragment processors.
146      * It may have variable sRGB settings.
147      **/
isTrivial()148     bool isTrivial() const { return fTrivial; }
149 
150 private:
151     template <bool> class MoveOrImpl;
152 
153 public:
154     /**
155      * A temporary instance of this class can be used to select between moving an existing paint or
156      * a temporary copy of an existing paint into a call site. MoveOrClone(paint, false) is a rvalue
157      * reference to paint while MoveOrClone(paint, true) is a rvalue reference to a copy of paint.
158      */
159     using MoveOrClone = MoveOrImpl<true>;
160 
161     /**
162      * A temporary instance of this class can be used to select between moving an existing or a
163      * newly default constructed paint into a call site. MoveOrNew(paint, false) is a rvalue
164      * reference to paint while MoveOrNew(paint, true) is a rvalue reference to a default paint.
165      */
166     using MoveOrNew = MoveOrImpl<false>;
167 
168 private:
169     GrPaint& operator=(const GrPaint&) = delete;
170 
171     friend class GrProcessorSet;
172 
173     const GrXPFactory* fXPFactory = nullptr;
174     SkSTArray<4, sk_sp<GrFragmentProcessor>>  fColorFragmentProcessors;
175     SkSTArray<2, sk_sp<GrFragmentProcessor>>  fCoverageFragmentProcessors;
176     bool fDisableOutputConversionToSRGB = false;
177     bool fAllowSRGBInputs = false;
178     bool fTrivial = true;
179     GrColor4f fColor = GrColor4f::OpaqueWhite();
180 };
181 
182 /** This is the implementation of MoveOrCopy and MoveOrNew. */
183 template <bool COPY_IF_NEW>
184 class GrPaint::MoveOrImpl {
185 public:
MoveOrImpl(GrPaint & paint,bool newPaint)186     MoveOrImpl(GrPaint& paint, bool newPaint) {
187         if (newPaint) {
188             if (COPY_IF_NEW) {
189                 fStorage.init(paint);
190             } else {
191                 fStorage.init();
192             };
193             fPaint = fStorage.get();
194         } else {
195             fPaint = &paint;
196         }
197     }
198 
199     operator GrPaint&&() && { return std::move(*fPaint); }
paint()200     GrPaint& paint() { return *fPaint; }
201 
202 private:
203     SkTLazy<GrPaint> fStorage;
204     GrPaint* fPaint;
205 };
206 
207 #endif
208