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 "GrClip.h"
13#include "GrDrawTargetCaps.h"
14#include "GrGpuResourceRef.h"
15#include "GrFragmentStage.h"
16#include "GrProcOptInfo.h"
17#include "GrRenderTarget.h"
18#include "GrStencil.h"
19#include "GrXferProcessor.h"
20#include "SkMatrix.h"
21#include "effects/GrCoverageSetOpXP.h"
22#include "effects/GrDisableColorXP.h"
23#include "effects/GrPorterDuffXferProcessor.h"
24#include "effects/GrSimpleTextureEffect.h"
25
26class GrBatch;
27class GrDrawTargetCaps;
28class GrPaint;
29class GrTexture;
30
31class GrPipelineBuilder {
32public:
33    GrPipelineBuilder();
34
35    GrPipelineBuilder(const GrPipelineBuilder& pipelineBuilder) {
36        SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
37        *this = pipelineBuilder;
38    }
39
40    virtual ~GrPipelineBuilder();
41
42    /**
43     * Initializes the GrPipelineBuilder based on a GrPaint, view matrix and render target. Note
44     * that GrPipelineBuilder encompasses more than GrPaint. Aspects of GrPipelineBuilder that have
45     * no GrPaint equivalents are set to default values with the exception of vertex attribute state
46     * which is unmodified by this function and clipping which will be enabled.
47     */
48    void setFromPaint(const GrPaint&, GrRenderTarget*, const GrClip&);
49
50    ///////////////////////////////////////////////////////////////////////////
51    /// @name Fragment Processors
52    ///
53    /// GrFragmentProcessors are used to compute per-pixel color and per-pixel fractional coverage.
54    /// There are two chains of FPs, one for color and one for coverage. The first FP in each
55    /// chain gets the initial color/coverage from the GrPrimitiveProcessor. It computes an output
56    /// color/coverage which is fed to the next FP in the chain. The last color and coverage FPs
57    /// feed their output to the GrXferProcessor which controls blending.
58    ////
59
60    int numColorFragmentStages() const { return fColorStages.count(); }
61    int numCoverageFragmentStages() const { return fCoverageStages.count(); }
62    int numFragmentStages() const { return this->numColorFragmentStages() +
63                                               this->numCoverageFragmentStages(); }
64
65    const GrFragmentStage& getColorFragmentStage(int idx) const { return fColorStages[idx]; }
66    const GrFragmentStage& getCoverageFragmentStage(int idx) const { return fCoverageStages[idx]; }
67
68    const GrFragmentProcessor* addColorProcessor(const GrFragmentProcessor* effect) {
69        SkASSERT(effect);
70        SkNEW_APPEND_TO_TARRAY(&fColorStages, GrFragmentStage, (effect));
71        fColorProcInfoValid = false;
72        return effect;
73    }
74
75    const GrFragmentProcessor* addCoverageProcessor(const GrFragmentProcessor* effect) {
76        SkASSERT(effect);
77        SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrFragmentStage, (effect));
78        fCoverageProcInfoValid = false;
79        return effect;
80    }
81
82    /**
83     * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
84     */
85    void addColorTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
86        this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref();
87    }
88
89    void addCoverageTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
90        this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref();
91    }
92
93    void addColorTextureProcessor(GrTexture* texture,
94                                  const SkMatrix& matrix,
95                                  const GrTextureParams& params) {
96        this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
97    }
98
99    void addCoverageTextureProcessor(GrTexture* texture,
100                                     const SkMatrix& matrix,
101                                     const GrTextureParams& params) {
102        this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
103    }
104
105    /**
106     * When this object is destroyed it will remove any color/coverage FPs from the pipeline builder
107     * that were added after its constructor.
108     */
109    class AutoRestoreFragmentProcessors : public ::SkNoncopyable {
110    public:
111        AutoRestoreFragmentProcessors()
112            : fPipelineBuilder(NULL)
113            , fColorEffectCnt(0)
114            , fCoverageEffectCnt(0) {}
115
116        AutoRestoreFragmentProcessors(GrPipelineBuilder* ds)
117            : fPipelineBuilder(NULL)
118            , fColorEffectCnt(0)
119            , fCoverageEffectCnt(0) {
120            this->set(ds);
121        }
122
123        ~AutoRestoreFragmentProcessors() { this->set(NULL); }
124
125        void set(GrPipelineBuilder* ds);
126
127        bool isSet() const { return SkToBool(fPipelineBuilder); }
128
129    private:
130        GrPipelineBuilder*    fPipelineBuilder;
131        int             fColorEffectCnt;
132        int             fCoverageEffectCnt;
133    };
134
135    /// @}
136
137    ///////////////////////////////////////////////////////////////////////////
138    /// @name Blending
139    ////
140
141    /**
142     * This function returns true if the render target destination pixel values will be read for
143     * blending during draw.
144     */
145    bool willBlendWithDst(const GrPrimitiveProcessor*) const;
146
147    /**
148     * Installs a GrXPFactory. This object controls how src color, fractional pixel coverage,
149     * and the dst color are blended.
150     */
151    const GrXPFactory* setXPFactory(const GrXPFactory* xpFactory) {
152        fXPFactory.reset(SkRef(xpFactory));
153        return xpFactory;
154    }
155
156    /**
157     * Sets a GrXPFactory that will ignore src color and perform a set operation between the draws
158     * output coverage and the destination. This is useful to render coverage masks as CSG.
159     */
160    void setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage = false) {
161        fXPFactory.reset(GrCoverageSetOpXPFactory::Create(regionOp, invertCoverage));
162    }
163
164    /**
165     * Sets a GrXPFactory that disables color writes to the destination. This is useful when
166     * rendering to the stencil buffer.
167     */
168    void setDisableColorXPFactory() {
169        fXPFactory.reset(GrDisableColorXPFactory::Create());
170    }
171
172    const GrXPFactory* getXPFactory() const {
173        if (!fXPFactory) {
174            fXPFactory.reset(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode));
175        }
176        return fXPFactory.get();
177    }
178
179    /**
180     * Checks whether the xp will need a copy of the destination to correctly blend.
181     */
182    bool willXPNeedDstCopy(const GrDrawTargetCaps& caps, const GrProcOptInfo& colorPOI,
183                           const GrProcOptInfo& coveragePOI) const;
184
185    /// @}
186
187
188    ///////////////////////////////////////////////////////////////////////////
189    /// @name Render Target
190    ////
191
192    /**
193     * Retrieves the currently set render-target.
194     *
195     * @return    The currently set render target.
196     */
197    GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
198
199    /**
200     * Sets the render-target used at the next drawing call
201     *
202     * @param target  The render target to set.
203     */
204    void setRenderTarget(GrRenderTarget* target) { fRenderTarget.reset(SkSafeRef(target)); }
205
206    /// @}
207
208    ///////////////////////////////////////////////////////////////////////////
209    /// @name Stencil
210    ////
211
212    const GrStencilSettings& getStencil() const { return fStencilSettings; }
213
214    /**
215     * Sets the stencil settings to use for the next draw.
216     * Changing the clip has the side-effect of possibly zeroing
217     * out the client settable stencil bits. So multipass algorithms
218     * using stencil should not change the clip between passes.
219     * @param settings  the stencil settings to use.
220     */
221    void setStencil(const GrStencilSettings& settings) { fStencilSettings = settings; }
222
223    /**
224     * Shortcut to disable stencil testing and ops.
225     */
226    void disableStencil() { fStencilSettings.setDisabled(); }
227
228    GrStencilSettings* stencil() { return &fStencilSettings; }
229
230    /**
231     * AutoRestoreStencil
232     *
233     * This simple struct saves and restores the stencil settings
234     */
235    class AutoRestoreStencil : public ::SkNoncopyable {
236    public:
237        AutoRestoreStencil() : fPipelineBuilder(NULL) {}
238
239        AutoRestoreStencil(GrPipelineBuilder* ds) : fPipelineBuilder(NULL) { this->set(ds); }
240
241        ~AutoRestoreStencil() { this->set(NULL); }
242
243        void set(GrPipelineBuilder* ds) {
244            if (fPipelineBuilder) {
245                fPipelineBuilder->setStencil(fStencilSettings);
246            }
247            fPipelineBuilder = ds;
248            if (ds) {
249                fStencilSettings = ds->getStencil();
250            }
251        }
252
253        bool isSet() const { return SkToBool(fPipelineBuilder); }
254
255    private:
256        GrPipelineBuilder*  fPipelineBuilder;
257        GrStencilSettings   fStencilSettings;
258    };
259
260
261    /// @}
262
263    ///////////////////////////////////////////////////////////////////////////
264    /// @name State Flags
265    ////
266
267    /**
268     *  Flags that affect rendering. Controlled using enable/disableState(). All
269     *  default to disabled.
270     */
271    enum Flags {
272        /**
273         * Perform dithering. TODO: Re-evaluate whether we need this bit
274         */
275        kDither_Flag        = 0x01,
276        /**
277         * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
278         * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
279         * the 3D API.
280         */
281        kHWAntialias_Flag   = 0x02,
282
283        /**
284         * Modifies the vertex shader so that vertices will be positioned at pixel centers.
285         */
286        kSnapVerticesToPixelCenters_Flag = 0x04,
287
288        kLast_Flag = kSnapVerticesToPixelCenters_Flag,
289    };
290
291    bool isDither() const { return SkToBool(fFlags & kDither_Flag); }
292    bool isHWAntialias() const { return SkToBool(fFlags & kHWAntialias_Flag); }
293    bool snapVerticesToPixelCenters() const {
294        return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag); }
295
296    /**
297     * Enable render state settings.
298     *
299     * @param flags bitfield of Flags specifying the states to enable
300     */
301    void enableState(uint32_t flags) { fFlags |= flags; }
302
303    /**
304     * Disable render state settings.
305     *
306     * @param flags bitfield of Flags specifying the states to disable
307     */
308    void disableState(uint32_t flags) { fFlags &= ~(flags); }
309
310    /**
311     * Enable or disable flags based on a boolean.
312     *
313     * @param flags bitfield of Flags to enable or disable
314     * @param enable    if true enable stateBits, otherwise disable
315     */
316    void setState(uint32_t flags, bool enable) {
317        if (enable) {
318            this->enableState(flags);
319        } else {
320            this->disableState(flags);
321        }
322    }
323
324    /// @}
325
326    ///////////////////////////////////////////////////////////////////////////
327    /// @name Face Culling
328    ////
329
330    enum DrawFace {
331        kInvalid_DrawFace = -1,
332
333        kBoth_DrawFace,
334        kCCW_DrawFace,
335        kCW_DrawFace,
336    };
337
338    /**
339     * Gets whether the target is drawing clockwise, counterclockwise,
340     * or both faces.
341     * @return the current draw face(s).
342     */
343    DrawFace getDrawFace() const { return fDrawFace; }
344
345    /**
346     * Controls whether clockwise, counterclockwise, or both faces are drawn.
347     * @param face  the face(s) to draw.
348     */
349    void setDrawFace(DrawFace face) {
350        SkASSERT(kInvalid_DrawFace != face);
351        fDrawFace = face;
352    }
353
354    /// @}
355
356    ///////////////////////////////////////////////////////////////////////////
357
358    GrPipelineBuilder& operator=(const GrPipelineBuilder& that);
359
360    // TODO delete when we have Batch
361    const GrProcOptInfo& colorProcInfo(const GrPrimitiveProcessor* pp) const {
362        this->calcColorInvariantOutput(pp);
363        return fColorProcInfo;
364    }
365
366    const GrProcOptInfo& coverageProcInfo(const GrPrimitiveProcessor* pp) const {
367        this->calcCoverageInvariantOutput(pp);
368        return fCoverageProcInfo;
369    }
370
371    const GrProcOptInfo& colorProcInfo(const GrBatch* batch) const {
372        this->calcColorInvariantOutput(batch);
373        return fColorProcInfo;
374    }
375
376    const GrProcOptInfo& coverageProcInfo(const GrBatch* batch) const {
377        this->calcCoverageInvariantOutput(batch);
378        return fCoverageProcInfo;
379    }
380
381    void setClip(const GrClip& clip) { fClip = clip; }
382    const GrClip& clip() const { return fClip; }
383
384private:
385    // Calculating invariant color / coverage information is expensive, so we partially cache the
386    // results.
387    //
388    // canUseFracCoveragePrimProc() - Called in regular skia draw, caches results but only for a
389    //                                specific color and coverage.  May be called multiple times
390    // willBlendWithDst() - only called by Nvpr, does not cache results
391    // GrOptDrawState constructor - never caches results
392
393    /**
394     * Primproc variants of the calc functions
395     * TODO remove these when batch is everywhere
396     */
397    void calcColorInvariantOutput(const GrPrimitiveProcessor*) const;
398    void calcCoverageInvariantOutput(const GrPrimitiveProcessor*) const;
399
400    /**
401     * GrBatch provides the initial seed for these loops based off of its initial geometry data
402     */
403    void calcColorInvariantOutput(const GrBatch*) const;
404    void calcCoverageInvariantOutput(const GrBatch*) const;
405
406    /**
407     * If fColorProcInfoValid is false, function calculates the invariant output for the color
408     * processors and results are stored in fColorProcInfo.
409     */
410    void calcColorInvariantOutput(GrColor) const;
411
412    /**
413     * If fCoverageProcInfoValid is false, function calculates the invariant output for the coverage
414     * processors and results are stored in fCoverageProcInfo.
415     */
416    void calcCoverageInvariantOutput(GrColor) const;
417
418    // Some of the auto restore objects assume that no effects are removed during their lifetime.
419    // This is used to assert that this condition holds.
420    SkDEBUGCODE(int fBlockEffectRemovalCnt;)
421
422    typedef SkSTArray<4, GrFragmentStage> FragmentStageArray;
423
424    SkAutoTUnref<GrRenderTarget>            fRenderTarget;
425    uint32_t                                fFlags;
426    GrStencilSettings                       fStencilSettings;
427    DrawFace                                fDrawFace;
428    mutable SkAutoTUnref<const GrXPFactory> fXPFactory;
429    FragmentStageArray                      fColorStages;
430    FragmentStageArray                      fCoverageStages;
431    GrClip                                  fClip;
432
433    mutable GrProcOptInfo fColorProcInfo;
434    mutable GrProcOptInfo fCoverageProcInfo;
435    mutable bool fColorProcInfoValid;
436    mutable bool fCoverageProcInfoValid;
437    mutable GrColor fColorCache;
438    mutable GrColor fCoverageCache;
439
440    friend class GrPipeline;
441};
442
443#endif
444