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 GrPipeline_DEFINED
      9 #define GrPipeline_DEFINED
     10 
     11 #include "GrColor.h"
     12 #include "GrFragmentProcessor.h"
     13 #include "GrNonAtomicRef.h"
     14 #include "GrPendingProgramElement.h"
     15 #include "GrPrimitiveProcessor.h"
     16 #include "GrProcessorSet.h"
     17 #include "GrProgramDesc.h"
     18 #include "GrScissorState.h"
     19 #include "GrUserStencilSettings.h"
     20 #include "GrWindowRectsState.h"
     21 #include "SkMatrix.h"
     22 #include "SkRefCnt.h"
     23 #include "effects/GrCoverageSetOpXP.h"
     24 #include "effects/GrDisableColorXP.h"
     25 #include "effects/GrPorterDuffXferProcessor.h"
     26 #include "effects/GrSimpleTextureEffect.h"
     27 
     28 class GrAppliedClip;
     29 class GrDeviceCoordTexture;
     30 class GrOp;
     31 class GrPipelineBuilder;
     32 class GrRenderTargetContext;
     33 
     34 /**
     35  * Class that holds an optimized version of a GrPipelineBuilder. It is meant to be an immutable
     36  * class, and contains all data needed to set the state for a gpu draw.
     37  */
     38 class GrPipeline : public GrNonAtomicRef<GrPipeline> {
     39 public:
     40     ///////////////////////////////////////////////////////////////////////////
     41     /// @name Creation
     42 
     43     enum Flags {
     44         /**
     45          * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
     46          * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
     47          * the 3D API.
     48          */
     49         kHWAntialias_Flag = 0x1,
     50 
     51         /**
     52          * Modifies the vertex shader so that vertices will be positioned at pixel centers.
     53          */
     54         kSnapVerticesToPixelCenters_Flag = 0x2,
     55     };
     56 
     57     struct InitArgs {
     58         uint32_t fFlags = 0;
     59         GrDrawFace fDrawFace = GrDrawFace::kBoth;
     60         const GrProcessorSet* fProcessors = nullptr;
     61         const GrProcessorSet::FragmentProcessorAnalysis* fAnalysis;
     62         const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused;
     63         const GrAppliedClip* fAppliedClip = nullptr;
     64         GrRenderTarget* fRenderTarget = nullptr;
     65         const GrCaps* fCaps = nullptr;
     66         GrXferProcessor::DstTexture fDstTexture;
     67     };
     68 
     69     /**
     70      * A Default constructed pipeline is unusable until init() is called.
     71      **/
     72     GrPipeline() = default;
     73 
     74     /**
     75      * Creates a simple pipeline with default settings and no processors. The provided blend mode
     76      * must be "Porter Duff" (<= kLastCoeffMode). This pipeline is initialized without requiring
     77      * a call to init().
     78      **/
     79     GrPipeline(GrRenderTarget*, SkBlendMode);
     80 
     81     /** (Re)initializes a pipeline. After initialization the pipeline can be used. */
     82     GrPipelineOptimizations init(const InitArgs&);
     83 
     84     /** True if the pipeline has been initialized. */
     85     bool isInitialized() const { return SkToBool(fRenderTarget.get()); }
     86 
     87     /// @}
     88 
     89     ///////////////////////////////////////////////////////////////////////////
     90     /// @name Comparisons
     91 
     92     /**
     93      * Returns true if these pipelines are equivalent.  Coord transforms may be applied either on
     94      * the GPU or the CPU. When we apply them on the CPU then the matrices need not agree in order
     95      * to combine draws. Therefore we take a param that indicates whether coord transforms should be
     96      * compared."
     97      */
     98     static bool AreEqual(const GrPipeline& a, const GrPipeline& b);
     99 
    100     /**
    101      * Allows a GrOp subclass to determine whether two GrOp instances can combine. This is a
    102      * stricter test than isEqual because it also considers blend barriers when the two ops'
    103      * bounds overlap
    104      */
    105     static bool CanCombine(const GrPipeline& a, const SkRect& aBounds,
    106                            const GrPipeline& b, const SkRect& bBounds,
    107                            const GrCaps& caps)  {
    108         if (!AreEqual(a, b)) {
    109             return false;
    110         }
    111         if (a.xferBarrierType(caps)) {
    112             return aBounds.fRight <= bBounds.fLeft ||
    113                    aBounds.fBottom <= bBounds.fTop ||
    114                    bBounds.fRight <= aBounds.fLeft ||
    115                    bBounds.fBottom <= aBounds.fTop;
    116         }
    117         return true;
    118     }
    119 
    120     /// @}
    121 
    122     ///////////////////////////////////////////////////////////////////////////
    123     /// @name GrFragmentProcessors
    124 
    125     // Make the renderTarget's GrOpList (if it exists) be dependent on any
    126     // GrOpLists in this pipeline
    127     void addDependenciesTo(GrRenderTarget* rt) const;
    128 
    129     int numColorFragmentProcessors() const { return fNumColorProcessors; }
    130     int numCoverageFragmentProcessors() const {
    131         return fFragmentProcessors.count() - fNumColorProcessors;
    132     }
    133     int numFragmentProcessors() const { return fFragmentProcessors.count(); }
    134 
    135     const GrXferProcessor& getXferProcessor() const {
    136         if (fXferProcessor.get()) {
    137             return *fXferProcessor.get();
    138         } else {
    139             // A null xp member means the common src-over case. GrXferProcessor's ref'ing
    140             // mechanism is not thread safe so we do not hold a ref on this global.
    141             return GrPorterDuffXPFactory::SimpleSrcOverXP();
    142         }
    143     }
    144 
    145     const GrFragmentProcessor& getColorFragmentProcessor(int idx) const {
    146         SkASSERT(idx < this->numColorFragmentProcessors());
    147         return *fFragmentProcessors[idx].get();
    148     }
    149 
    150     const GrFragmentProcessor& getCoverageFragmentProcessor(int idx) const {
    151         SkASSERT(idx < this->numCoverageFragmentProcessors());
    152         return *fFragmentProcessors[fNumColorProcessors + idx].get();
    153     }
    154 
    155     const GrFragmentProcessor& getFragmentProcessor(int idx) const {
    156         return *fFragmentProcessors[idx].get();
    157     }
    158 
    159     /// @}
    160 
    161     /**
    162      * Retrieves the currently set render-target.
    163      *
    164      * @return    The currently set render target.
    165      */
    166     GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
    167 
    168     const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; }
    169 
    170     const GrScissorState& getScissorState() const { return fScissorState; }
    171 
    172     const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }
    173 
    174     bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAntialias_Flag); }
    175     bool snapVerticesToPixelCenters() const {
    176         return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag);
    177     }
    178     bool getDisableOutputConversionToSRGB() const {
    179         return SkToBool(fFlags & kDisableOutputConversionToSRGB_Flag);
    180     }
    181     bool getAllowSRGBInputs() const {
    182         return SkToBool(fFlags & kAllowSRGBInputs_Flag);
    183     }
    184     bool usesDistanceVectorField() const {
    185         return SkToBool(fFlags & kUsesDistanceVectorField_Flag);
    186     }
    187     bool hasStencilClip() const {
    188         return SkToBool(fFlags & kHasStencilClip_Flag);
    189     }
    190     bool isStencilEnabled() const {
    191         return SkToBool(fFlags & kStencilEnabled_Flag);
    192     }
    193 
    194     GrXferBarrierType xferBarrierType(const GrCaps& caps) const {
    195         return this->getXferProcessor().xferBarrierType(fRenderTarget.get(), caps);
    196     }
    197 
    198     /**
    199      * Gets whether the target is drawing clockwise, counterclockwise,
    200      * or both faces.
    201      * @return the current draw face(s).
    202      */
    203     GrDrawFace getDrawFace() const { return static_cast<GrDrawFace>(fDrawFace); }
    204 
    205 private:
    206     /** This is a continuation of the public "Flags" enum. */
    207     enum PrivateFlags {
    208         kDisableOutputConversionToSRGB_Flag = 0x4,
    209         kAllowSRGBInputs_Flag = 0x8,
    210         kUsesDistanceVectorField_Flag = 0x10,
    211         kHasStencilClip_Flag = 0x20,
    212         kStencilEnabled_Flag = 0x40,
    213     };
    214 
    215     typedef GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> RenderTarget;
    216     typedef GrPendingProgramElement<const GrFragmentProcessor> PendingFragmentProcessor;
    217     typedef SkAutoSTArray<8, PendingFragmentProcessor> FragmentProcessorArray;
    218     typedef GrPendingProgramElement<const GrXferProcessor> ProgramXferProcessor;
    219     RenderTarget                        fRenderTarget;
    220     GrScissorState                      fScissorState;
    221     GrWindowRectsState                  fWindowRectsState;
    222     const GrUserStencilSettings*        fUserStencilSettings;
    223     uint16_t                            fDrawFace;
    224     uint16_t                            fFlags;
    225     ProgramXferProcessor                fXferProcessor;
    226     FragmentProcessorArray              fFragmentProcessors;
    227 
    228     // This value is also the index in fFragmentProcessors where coverage processors begin.
    229     int                                 fNumColorProcessors;
    230 
    231     typedef SkRefCnt INHERITED;
    232 };
    233 
    234 #endif
    235