Home | History | Annotate | Download | only in gpu
      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 
     26 class GrBatch;
     27 class GrDrawTargetCaps;
     28 class GrPaint;
     29 class GrTexture;
     30 
     31 class GrPipelineBuilder {
     32 public:
     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 
    384 private:
    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