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 {
GrBatchToXPOverridesGrBatchToXPOverrides28     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 
numColorFragmentProcessors()103     int numColorFragmentProcessors() const { return fNumColorProcessors; }
numCoverageFragmentProcessors()104     int numCoverageFragmentProcessors() const {
105         return fFragmentProcessors.count() - fNumColorProcessors;
106     }
numFragmentProcessors()107     int numFragmentProcessors() const { return fFragmentProcessors.count(); }
108 
getXferProcessor()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 
getColorFragmentProcessor(int idx)119     const GrFragmentProcessor& getColorFragmentProcessor(int idx) const {
120         SkASSERT(idx < this->numColorFragmentProcessors());
121         return *fFragmentProcessors[idx].get();
122     }
123 
getCoverageFragmentProcessor(int idx)124     const GrFragmentProcessor& getCoverageFragmentProcessor(int idx) const {
125         SkASSERT(idx < this->numCoverageFragmentProcessors());
126         return *fFragmentProcessors[fNumColorProcessors + idx].get();
127     }
128 
getFragmentProcessor(int idx)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      */
getRenderTarget()140     GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
141 
getStencil()142     const GrStencilSettings& getStencil() const { return fStencilSettings; }
143 
getScissorState()144     const GrScissorState& getScissorState() const { return fScissorState; }
145 
isHWAntialiasState()146     bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAA_Flag); }
snapVerticesToPixelCenters()147     bool snapVerticesToPixelCenters() const { return SkToBool(fFlags & kSnapVertices_Flag); }
148 
xferBarrierType(const GrCaps & caps)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      */
getDrawFace()158     GrPipelineBuilder::DrawFace getDrawFace() const { return fDrawFace; }
159 
160 
161     ///////////////////////////////////////////////////////////////////////////
162 
readsFragPosition()163     bool readsFragPosition() const { return fReadsFragPosition; }
ignoresCoverage()164     bool ignoresCoverage() const { return fIgnoresCoverage; }
165 
166 private:
GrPipeline()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