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 "GrGpu.h"
     14 #include "GrNonAtomicRef.h"
     15 #include "GrPendingProgramElement.h"
     16 #include "GrPrimitiveProcessor.h"
     17 #include "GrProgramDesc.h"
     18 #include "GrStencil.h"
     19 #include "GrTypesPriv.h"
     20 #include "SkMatrix.h"
     21 #include "SkRefCnt.h"
     22 
     23 class GrBatch;
     24 class GrDeviceCoordTexture;
     25 class GrPipelineBuilder;
     26 
     27 struct GrBatchToXPOverrides {
     28     GrBatchToXPOverrides()
     29     : fUsePLSDstRead(false) {}
     30 
     31     bool fUsePLSDstRead;
     32 };
     33 
     34 struct GrPipelineOptimizations {
     35     GrProcOptInfo fColorPOI;
     36     GrProcOptInfo fCoveragePOI;
     37     GrBatchToXPOverrides fOverrides;
     38 };
     39 
     40 /**
     41  * Class that holds an optimized version of a GrPipelineBuilder. It is meant to be an immutable
     42  * class, and contains all data needed to set the state for a gpu draw.
     43  */
     44 class GrPipeline : public GrNonAtomicRef<GrPipeline> {
     45 public:
     46     ///////////////////////////////////////////////////////////////////////////
     47     /// @name Creation
     48 
     49     struct CreateArgs {
     50         const GrPipelineBuilder*    fPipelineBuilder;
     51         const GrCaps*               fCaps;
     52         GrPipelineOptimizations     fOpts;
     53         const GrScissorState*       fScissor;
     54         GrXferProcessor::DstTexture fDstTexture;
     55     };
     56 
     57     /** Creates a pipeline into a pre-allocated buffer */
     58     static GrPipeline* CreateAt(void* memory, const CreateArgs&, GrXPOverridesForBatch*);
     59 
     60     /// @}
     61 
     62     ///////////////////////////////////////////////////////////////////////////
     63     /// @name Comparisons
     64 
     65     /**
     66      * Returns true if these pipelines are equivalent.  Coord transforms may be applied either on
     67      * the GPU or the CPU. When we apply them on the CPU then the matrices need not agree in order
     68      * to combine draws. Therefore we take a param that indicates whether coord transforms should be
     69      * compared."
     70      */
     71     static bool AreEqual(const GrPipeline& a, const GrPipeline& b, bool ignoreCoordTransforms);
     72 
     73     /**
     74      * Allows a GrBatch subclass to determine whether two GrBatches can combine. This is a stricter
     75      * test than isEqual because it also considers blend barriers when the two batches' bounds
     76      * overlap
     77      */
     78     static bool CanCombine(const GrPipeline& a, const SkRect& aBounds,
     79                            const GrPipeline& b, const SkRect& bBounds,
     80                            const GrCaps& caps,
     81                            bool ignoreCoordTransforms = false)  {
     82         if (!AreEqual(a, b, ignoreCoordTransforms)) {
     83             return false;
     84         }
     85         if (a.xferBarrierType(caps)) {
     86             return aBounds.fRight <= bBounds.fLeft ||
     87                    aBounds.fBottom <= bBounds.fTop ||
     88                    bBounds.fRight <= aBounds.fLeft ||
     89                    bBounds.fBottom <= aBounds.fTop;
     90         }
     91         return true;
     92     }
     93 
     94     /// @}
     95 
     96     ///////////////////////////////////////////////////////////////////////////
     97     /// @name GrFragmentProcessors
     98 
     99     // Make the renderTarget's drawTarget (if it exists) be dependent on any
    100     // drawTargets in this pipeline
    101     void addDependenciesTo(GrRenderTarget* rt) const;
    102 
    103     int numColorFragmentProcessors() const { return fNumColorProcessors; }
    104     int numCoverageFragmentProcessors() const {
    105         return fFragmentProcessors.count() - fNumColorProcessors;
    106     }
    107     int numFragmentProcessors() const { return fFragmentProcessors.count(); }
    108 
    109     const GrXferProcessor& getXferProcessor() const {
    110         if (fXferProcessor.get()) {
    111             return *fXferProcessor.get();
    112         } else {
    113             // A null xp member means the common src-over case. GrXferProcessor's ref'ing
    114             // mechanism is not thread safe so we do not hold a ref on this global.
    115             return GrPorterDuffXPFactory::SimpleSrcOverXP();
    116         }
    117     }
    118 
    119     const GrFragmentProcessor& getColorFragmentProcessor(int idx) const {
    120         SkASSERT(idx < this->numColorFragmentProcessors());
    121         return *fFragmentProcessors[idx].get();
    122     }
    123 
    124     const GrFragmentProcessor& getCoverageFragmentProcessor(int idx) const {
    125         SkASSERT(idx < this->numCoverageFragmentProcessors());
    126         return *fFragmentProcessors[fNumColorProcessors + idx].get();
    127     }
    128 
    129     const GrFragmentProcessor& getFragmentProcessor(int idx) const {
    130         return *fFragmentProcessors[idx].get();
    131     }
    132 
    133     /// @}
    134 
    135     /**
    136      * Retrieves the currently set render-target.
    137      *
    138      * @return    The currently set render target.
    139      */
    140     GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
    141 
    142     const GrStencilSettings& getStencil() const { return fStencilSettings; }
    143 
    144     const GrScissorState& getScissorState() const { return fScissorState; }
    145 
    146     bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAA_Flag); }
    147     bool snapVerticesToPixelCenters() const { return SkToBool(fFlags & kSnapVertices_Flag); }
    148 
    149     GrXferBarrierType xferBarrierType(const GrCaps& caps) const {
    150         return this->getXferProcessor().xferBarrierType(fRenderTarget.get(), caps);
    151     }
    152 
    153     /**
    154      * Gets whether the target is drawing clockwise, counterclockwise,
    155      * or both faces.
    156      * @return the current draw face(s).
    157      */
    158     GrPipelineBuilder::DrawFace getDrawFace() const { return fDrawFace; }
    159 
    160 
    161     ///////////////////////////////////////////////////////////////////////////
    162 
    163     bool readsFragPosition() const { return fReadsFragPosition; }
    164     bool ignoresCoverage() const { return fIgnoresCoverage; }
    165 
    166 private:
    167     GrPipeline() { /** Initialized in factory function*/ }
    168 
    169     /**
    170      * Alter the program desc and inputs (attribs and processors) based on the blend optimization.
    171      */
    172     void adjustProgramFromOptimizations(const GrPipelineBuilder& ds,
    173                                         GrXferProcessor::OptFlags,
    174                                         const GrProcOptInfo& colorPOI,
    175                                         const GrProcOptInfo& coveragePOI,
    176                                         int* firstColorProcessorIdx,
    177                                         int* firstCoverageProcessorIdx);
    178 
    179     /**
    180      * Calculates the primary and secondary output types of the shader. For certain output types
    181      * the function may adjust the blend coefficients. After this function is called the src and dst
    182      * blend coeffs will represent those used by backend API.
    183      */
    184     void setOutputStateInfo(const GrPipelineBuilder& ds, GrXferProcessor::OptFlags,
    185                             const GrCaps&);
    186 
    187     enum Flags {
    188         kHWAA_Flag              = 0x1,
    189         kSnapVertices_Flag      = 0x2,
    190     };
    191 
    192     typedef GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> RenderTarget;
    193     typedef GrPendingProgramElement<const GrFragmentProcessor> PendingFragmentProcessor;
    194     typedef SkAutoSTArray<8, PendingFragmentProcessor> FragmentProcessorArray;
    195     typedef GrPendingProgramElement<const GrXferProcessor> ProgramXferProcessor;
    196     RenderTarget                        fRenderTarget;
    197     GrScissorState                      fScissorState;
    198     GrStencilSettings                   fStencilSettings;
    199     GrPipelineBuilder::DrawFace         fDrawFace;
    200     uint32_t                            fFlags;
    201     ProgramXferProcessor                fXferProcessor;
    202     FragmentProcessorArray              fFragmentProcessors;
    203     bool                                fReadsFragPosition;
    204     bool                                fIgnoresCoverage;
    205 
    206     // This value is also the index in fFragmentProcessors where coverage processors begin.
    207     int                                 fNumColorProcessors;
    208 
    209     typedef SkRefCnt INHERITED;
    210 };
    211 
    212 #endif
    213