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. */ isInitialized()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 */ CanCombine(const GrPipeline & a,const SkRect & aBounds,const GrPipeline & b,const SkRect & bBounds,const GrCaps & caps)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 numColorFragmentProcessors()129 int numColorFragmentProcessors() const { return fNumColorProcessors; } numCoverageFragmentProcessors()130 int numCoverageFragmentProcessors() const { 131 return fFragmentProcessors.count() - fNumColorProcessors; 132 } numFragmentProcessors()133 int numFragmentProcessors() const { return fFragmentProcessors.count(); } 134 getXferProcessor()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 getColorFragmentProcessor(int idx)145 const GrFragmentProcessor& getColorFragmentProcessor(int idx) const { 146 SkASSERT(idx < this->numColorFragmentProcessors()); 147 return *fFragmentProcessors[idx].get(); 148 } 149 getCoverageFragmentProcessor(int idx)150 const GrFragmentProcessor& getCoverageFragmentProcessor(int idx) const { 151 SkASSERT(idx < this->numCoverageFragmentProcessors()); 152 return *fFragmentProcessors[fNumColorProcessors + idx].get(); 153 } 154 getFragmentProcessor(int idx)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 */ getRenderTarget()166 GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); } 167 getUserStencil()168 const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; } 169 getScissorState()170 const GrScissorState& getScissorState() const { return fScissorState; } 171 getWindowRectsState()172 const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; } 173 isHWAntialiasState()174 bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAntialias_Flag); } snapVerticesToPixelCenters()175 bool snapVerticesToPixelCenters() const { 176 return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag); 177 } getDisableOutputConversionToSRGB()178 bool getDisableOutputConversionToSRGB() const { 179 return SkToBool(fFlags & kDisableOutputConversionToSRGB_Flag); 180 } getAllowSRGBInputs()181 bool getAllowSRGBInputs() const { 182 return SkToBool(fFlags & kAllowSRGBInputs_Flag); 183 } usesDistanceVectorField()184 bool usesDistanceVectorField() const { 185 return SkToBool(fFlags & kUsesDistanceVectorField_Flag); 186 } hasStencilClip()187 bool hasStencilClip() const { 188 return SkToBool(fFlags & kHasStencilClip_Flag); 189 } isStencilEnabled()190 bool isStencilEnabled() const { 191 return SkToBool(fFlags & kStencilEnabled_Flag); 192 } 193 xferBarrierType(const GrCaps & caps)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 */ getDrawFace()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