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