Introduce GrColorSpaceXform, for gamut conversion on textures
[platform/upstream/libSkiaSharp.git] / src / gpu / GrPipelineBuilder.h
1 /*
2  * Copyright 2015 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 GrPipelineBuilder_DEFINED
9 #define GrPipelineBuilder_DEFINED
10
11 #include "GrBlend.h"
12 #include "GrCaps.h"
13 #include "GrGpuResourceRef.h"
14 #include "GrProcOptInfo.h"
15 #include "GrRenderTarget.h"
16 #include "GrUserStencilSettings.h"
17 #include "GrXferProcessor.h"
18 #include "SkMatrix.h"
19 #include "SkRefCnt.h"
20 #include "effects/GrCoverageSetOpXP.h"
21 #include "effects/GrDisableColorXP.h"
22 #include "effects/GrPorterDuffXferProcessor.h"
23 #include "effects/GrSimpleTextureEffect.h"
24
25 class GrDrawBatch;
26 class GrCaps;
27 class GrPaint;
28 class GrTexture;
29
30 class GrPipelineBuilder : public SkNoncopyable {
31 public:
32     GrPipelineBuilder();
33
34     /**
35      * Initializes the GrPipelineBuilder based on a GrPaint and MSAA availability. Note
36      * that GrPipelineBuilder encompasses more than GrPaint. Aspects of GrPipelineBuilder that have
37      * no GrPaint equivalents are set to default values with the exception of vertex attribute state
38      * which is unmodified by this function and clipping which will be enabled.
39      */
40     GrPipelineBuilder(const GrPaint&, bool useHWAA = false);
41
42     virtual ~GrPipelineBuilder();
43
44     ///////////////////////////////////////////////////////////////////////////
45     /// @name Fragment Processors
46     ///
47     /// GrFragmentProcessors are used to compute per-pixel color and per-pixel fractional coverage.
48     /// There are two chains of FPs, one for color and one for coverage. The first FP in each
49     /// chain gets the initial color/coverage from the GrPrimitiveProcessor. It computes an output
50     /// color/coverage which is fed to the next FP in the chain. The last color and coverage FPs
51     /// feed their output to the GrXferProcessor which controls blending.
52     ////
53
54     int numColorFragmentProcessors() const { return fColorFragmentProcessors.count(); }
55     int numCoverageFragmentProcessors() const { return fCoverageFragmentProcessors.count(); }
56     int numFragmentProcessors() const { return this->numColorFragmentProcessors() +
57                                                this->numCoverageFragmentProcessors(); }
58
59     const GrFragmentProcessor* getColorFragmentProcessor(int idx) const {
60         return fColorFragmentProcessors[idx].get();
61     }
62     const GrFragmentProcessor* getCoverageFragmentProcessor(int idx) const {
63         return fCoverageFragmentProcessors[idx].get();
64     }
65
66     void addColorFragmentProcessor(sk_sp<GrFragmentProcessor> processor) {
67         SkASSERT(processor);
68         fColorFragmentProcessors.push_back(std::move(processor));
69     }
70
71     void addCoverageFragmentProcessor(sk_sp<GrFragmentProcessor> processor) {
72         SkASSERT(processor);
73         fCoverageFragmentProcessors.push_back(std::move(processor));
74     }
75
76     /**
77      * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
78      */
79     void addColorTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
80         this->addColorFragmentProcessor(GrSimpleTextureEffect::Make(texture, nullptr, matrix));
81     }
82
83     void addCoverageTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
84         this->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(texture, nullptr, matrix));
85     }
86
87     void addColorTextureProcessor(GrTexture* texture,
88                                   const SkMatrix& matrix,
89                                   const GrTextureParams& params) {
90         this->addColorFragmentProcessor(GrSimpleTextureEffect::Make(texture, nullptr, matrix,
91                                                                     params));
92     }
93
94     void addCoverageTextureProcessor(GrTexture* texture,
95                                      const SkMatrix& matrix,
96                                      const GrTextureParams& params) {
97         this->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(texture, nullptr, matrix,
98                                                                        params));
99     }
100
101     /**
102      * When this object is destroyed it will remove any color/coverage FPs from the pipeline builder
103      * that were added after its constructor.
104      * This class can transiently modify its "const" GrPipelineBuilder object but will restore it
105      * when done - so it is notionally "const" correct.
106      */
107     class AutoRestoreFragmentProcessorState : public ::SkNoncopyable {
108     public:
109         AutoRestoreFragmentProcessorState()
110             : fPipelineBuilder(nullptr)
111             , fColorEffectCnt(0)
112             , fCoverageEffectCnt(0) {}
113
114         AutoRestoreFragmentProcessorState(const GrPipelineBuilder& ds)
115             : fPipelineBuilder(nullptr)
116             , fColorEffectCnt(0)
117             , fCoverageEffectCnt(0) {
118             this->set(&ds);
119         }
120
121         ~AutoRestoreFragmentProcessorState() { this->set(nullptr); }
122
123         void set(const GrPipelineBuilder* ds);
124
125         bool isSet() const { return SkToBool(fPipelineBuilder); }
126
127         void addCoverageFragmentProcessor(sk_sp<GrFragmentProcessor> processor) {
128             SkASSERT(this->isSet());
129             return fPipelineBuilder->addCoverageFragmentProcessor(std::move(processor));
130         }
131
132     private:
133         // notionally const (as marginalia)
134         GrPipelineBuilder*    fPipelineBuilder;
135         int                   fColorEffectCnt;
136         int                   fCoverageEffectCnt;
137     };
138
139     /// @}
140
141     ///////////////////////////////////////////////////////////////////////////
142     /// @name Blending
143     ////
144
145     /**
146      * Installs a GrXPFactory. This object controls how src color, fractional pixel coverage,
147      * and the dst color are blended.
148      */
149     void setXPFactory(sk_sp<GrXPFactory> xpFactory) {
150         fXPFactory = std::move(xpFactory);
151     }
152
153     /**
154      * Sets a GrXPFactory that disables color writes to the destination. This is useful when
155      * rendering to the stencil buffer.
156      */
157     void setDisableColorXPFactory() {
158         fXPFactory = GrDisableColorXPFactory::Make();
159     }
160
161     const GrXPFactory* getXPFactory() const {
162         return fXPFactory.get();
163     }
164
165     /**
166      * Checks whether the xp will need destination in a texture to correctly blend.
167      */
168     bool willXPNeedDstTexture(const GrCaps& caps,
169                               const GrPipelineOptimizations& optimizations) const;
170
171     /// @}
172
173
174     ///////////////////////////////////////////////////////////////////////////
175     /// @name Stencil
176     ////
177
178     bool hasUserStencilSettings() const { return !fUserStencilSettings->isUnused(); }
179     const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; }
180
181     /**
182      * Sets the user stencil settings for the next draw.
183      * This class only stores pointers to stencil settings objects.
184      * The caller guarantees the pointer will remain valid until it
185      * changes or goes out of scope.
186      * @param settings  the stencil settings to use.
187      */
188     void setUserStencil(const GrUserStencilSettings* settings) { fUserStencilSettings = settings; }
189     void disableUserStencil() { fUserStencilSettings = &GrUserStencilSettings::kUnused; }
190
191     /// @}
192
193     ///////////////////////////////////////////////////////////////////////////
194     /// @name State Flags
195     ////
196
197     /**
198      *  Flags that affect rendering. Controlled using enable/disableState(). All
199      *  default to disabled.
200      */
201     enum Flags {
202         /**
203          * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
204          * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
205          * the 3D API.
206          */
207         kHWAntialias_Flag   = 0x01,
208
209         /**
210          * Modifies the vertex shader so that vertices will be positioned at pixel centers.
211          */
212         kSnapVerticesToPixelCenters_Flag = 0x02,
213
214         /**
215          * Suppress linear -> sRGB conversion when rendering to sRGB render targets.
216          */
217         kDisableOutputConversionToSRGB_Flag = 0x04,
218
219         /**
220          * Allow sRGB -> linear conversion when reading from sRGB inputs.
221          */
222         kAllowSRGBInputs_Flag = 0x08,
223
224         kLast_Flag = kAllowSRGBInputs_Flag,
225     };
226
227     bool isHWAntialias() const { return SkToBool(fFlags & kHWAntialias_Flag); }
228     bool snapVerticesToPixelCenters() const {
229         return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag); }
230     bool getDisableOutputConversionToSRGB() const {
231         return SkToBool(fFlags & kDisableOutputConversionToSRGB_Flag); }
232     bool getAllowSRGBInputs() const {
233         return SkToBool(fFlags & kAllowSRGBInputs_Flag); }
234
235     /**
236      * Enable render state settings.
237      *
238      * @param flags bitfield of Flags specifying the states to enable
239      */
240     void enableState(uint32_t flags) { fFlags |= flags; }
241
242     /**
243      * Disable render state settings.
244      *
245      * @param flags bitfield of Flags specifying the states to disable
246      */
247     void disableState(uint32_t flags) { fFlags &= ~(flags); }
248
249     /**
250      * Enable or disable flags based on a boolean.
251      *
252      * @param flags bitfield of Flags to enable or disable
253      * @param enable    if true enable stateBits, otherwise disable
254      */
255     void setState(uint32_t flags, bool enable) {
256         if (enable) {
257             this->enableState(flags);
258         } else {
259             this->disableState(flags);
260         }
261     }
262
263     /// @}
264
265     ///////////////////////////////////////////////////////////////////////////
266     /// @name Face Culling
267     ////
268
269     enum DrawFace {
270         kInvalid_DrawFace = -1,
271
272         kBoth_DrawFace,
273         kCCW_DrawFace,
274         kCW_DrawFace,
275     };
276
277     /**
278      * Gets whether the target is drawing clockwise, counterclockwise,
279      * or both faces.
280      * @return the current draw face(s).
281      */
282     DrawFace getDrawFace() const { return fDrawFace; }
283
284     /**
285      * Controls whether clockwise, counterclockwise, or both faces are drawn.
286      * @param face  the face(s) to draw.
287      */
288     void setDrawFace(DrawFace face) {
289         SkASSERT(kInvalid_DrawFace != face);
290         fDrawFace = face;
291     }
292
293     /// @}
294
295     ///////////////////////////////////////////////////////////////////////////
296
297     bool usePLSDstRead(const GrDrawBatch* batch) const;
298
299 private:
300     // Some of the auto restore objects assume that no effects are removed during their lifetime.
301     // This is used to assert that this condition holds.
302     SkDEBUGCODE(mutable int fBlockEffectRemovalCnt;)
303
304     typedef SkSTArray<4, sk_sp<GrFragmentProcessor>> FragmentProcessorArray;
305
306     uint32_t                                fFlags;
307     const GrUserStencilSettings*            fUserStencilSettings;
308     DrawFace                                fDrawFace;
309     mutable sk_sp<GrXPFactory>              fXPFactory;
310     FragmentProcessorArray                  fColorFragmentProcessors;
311     FragmentProcessorArray                  fCoverageFragmentProcessors;
312
313     friend class GrPipeline;
314     friend class GrDrawTarget;
315 };
316
317 #endif