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