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 "GrPendingIOResource.h" 15 #include "GrProcessorSet.h" 16 #include "GrProgramDesc.h" 17 #include "GrRect.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 GrOp; 30 class GrRenderTargetContext; 31 32 /** 33 * This immutable object contains information needed to set build a shader program and set API 34 * state for a draw. It is used along with a GrPrimitiveProcessor and a source of geometric 35 * data (GrMesh or GrPath) to draw. 36 */ 37 class GrPipeline { 38 public: 39 /////////////////////////////////////////////////////////////////////////// 40 /// @name Creation 41 42 enum Flags { 43 /** 44 * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target, 45 * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by 46 * the 3D API. 47 */ 48 kHWAntialias_Flag = 0x1, 49 /** 50 * Modifies the vertex shader so that vertices will be positioned at pixel centers. 51 */ 52 kSnapVerticesToPixelCenters_Flag = 0x2, 53 }; 54 55 struct InitArgs { 56 uint32_t fFlags = 0; 57 const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused; 58 const GrCaps* fCaps = nullptr; 59 GrResourceProvider* fResourceProvider = nullptr; 60 GrXferProcessor::DstProxy fDstProxy; 61 }; 62 63 /** 64 * Some state can be changed between GrMeshes without changing GrPipelines. This is generally 65 * less expensive then using multiple pipelines. Such state is called "dynamic state". It can 66 * be specified in two ways: 67 * 1) FixedDynamicState - use this to specify state that does not vary between GrMeshes. 68 * 2) DynamicStateArrays - use this to specify per mesh values for dynamic state. 69 **/ 70 struct FixedDynamicState { FixedDynamicStateFixedDynamicState71 explicit FixedDynamicState(const SkIRect& scissorRect) : fScissorRect(scissorRect) {} 72 FixedDynamicState() = default; 73 SkIRect fScissorRect = SkIRect::EmptyIRect(); 74 // Must have GrPrimitiveProcessor::numTextureSamplers() entries. Can be null if no samplers 75 // or textures are passed using DynamicStateArrays. 76 GrTextureProxy** fPrimitiveProcessorTextures = nullptr; 77 }; 78 79 /** 80 * Any non-null array overrides the FixedDynamicState on a mesh-by-mesh basis. Arrays must 81 * have one entry for each GrMesh. 82 */ 83 struct DynamicStateArrays { 84 const SkIRect* fScissorRects = nullptr; 85 // Must have GrPrimitiveProcessor::numTextureSamplers() * num_meshes entries. 86 // Can be null if no samplers or to use the same textures for all meshes via' 87 // FixedDynamicState. 88 GrTextureProxy** fPrimitiveProcessorTextures = nullptr; 89 }; 90 91 /** 92 * Creates a simple pipeline with default settings and no processors. The provided blend mode 93 * must be "Porter Duff" (<= kLastCoeffMode). If using GrScissorTest::kEnabled, the caller must 94 * specify a scissor rectangle through the DynamicState struct. 95 **/ 96 GrPipeline(GrScissorTest, SkBlendMode); 97 98 GrPipeline(const InitArgs&, GrProcessorSet&&, GrAppliedClip&&); 99 100 GrPipeline(const GrPipeline&) = delete; 101 GrPipeline& operator=(const GrPipeline&) = delete; 102 103 /// @} 104 105 /////////////////////////////////////////////////////////////////////////// 106 /// @name GrFragmentProcessors 107 108 // Make the renderTargetContext's GrOpList be dependent on any GrOpLists in this pipeline 109 void addDependenciesTo(GrOpList* recipient, const GrCaps&) const; 110 numColorFragmentProcessors()111 int numColorFragmentProcessors() const { return fNumColorProcessors; } numCoverageFragmentProcessors()112 int numCoverageFragmentProcessors() const { 113 return fFragmentProcessors.count() - fNumColorProcessors; 114 } numFragmentProcessors()115 int numFragmentProcessors() const { return fFragmentProcessors.count(); } 116 getXferProcessor()117 const GrXferProcessor& getXferProcessor() const { 118 if (fXferProcessor) { 119 return *fXferProcessor.get(); 120 } else { 121 // A null xp member means the common src-over case. GrXferProcessor's ref'ing 122 // mechanism is not thread safe so we do not hold a ref on this global. 123 return GrPorterDuffXPFactory::SimpleSrcOverXP(); 124 } 125 } 126 127 /** 128 * If the GrXferProcessor uses a texture to access the dst color, then this returns that 129 * texture and the offset to the dst contents within that texture. 130 */ 131 GrTextureProxy* dstTextureProxy(SkIPoint* offset = nullptr) const { 132 if (offset) { 133 *offset = fDstTextureOffset; 134 } 135 return fDstTextureProxy.get(); 136 } 137 138 GrTexture* peekDstTexture(SkIPoint* offset = nullptr) const { 139 if (GrTextureProxy* dstProxy = this->dstTextureProxy(offset)) { 140 return dstProxy->peekTexture(); 141 } 142 143 return nullptr; 144 } 145 getColorFragmentProcessor(int idx)146 const GrFragmentProcessor& getColorFragmentProcessor(int idx) const { 147 SkASSERT(idx < this->numColorFragmentProcessors()); 148 return *fFragmentProcessors[idx].get(); 149 } 150 getCoverageFragmentProcessor(int idx)151 const GrFragmentProcessor& getCoverageFragmentProcessor(int idx) const { 152 SkASSERT(idx < this->numCoverageFragmentProcessors()); 153 return *fFragmentProcessors[fNumColorProcessors + idx].get(); 154 } 155 getFragmentProcessor(int idx)156 const GrFragmentProcessor& getFragmentProcessor(int idx) const { 157 return *fFragmentProcessors[idx].get(); 158 } 159 160 /// @} 161 getUserStencil()162 const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; } 163 isScissorEnabled()164 bool isScissorEnabled() const { 165 return SkToBool(fFlags & kScissorEnabled_Flag); 166 } 167 getWindowRectsState()168 const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; } 169 isHWAntialiasState()170 bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAntialias_Flag); } snapVerticesToPixelCenters()171 bool snapVerticesToPixelCenters() const { 172 return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag); 173 } hasStencilClip()174 bool hasStencilClip() const { 175 return SkToBool(fFlags & kHasStencilClip_Flag); 176 } isStencilEnabled()177 bool isStencilEnabled() const { 178 return SkToBool(fFlags & kStencilEnabled_Flag); 179 } isBad()180 bool isBad() const { return SkToBool(fFlags & kIsBad_Flag); } 181 182 GrXferBarrierType xferBarrierType(GrTexture*, const GrCaps&) const; 183 DumpFlags(uint32_t flags)184 static SkString DumpFlags(uint32_t flags) { 185 if (flags) { 186 SkString result; 187 if (flags & GrPipeline::kSnapVerticesToPixelCenters_Flag) { 188 result.append("Snap vertices to pixel center.\n"); 189 } 190 if (flags & GrPipeline::kHWAntialias_Flag) { 191 result.append("HW Antialiasing enabled.\n"); 192 } 193 return result; 194 } 195 return SkString("No pipeline flags\n"); 196 } 197 198 private: markAsBad()199 void markAsBad() { fFlags |= kIsBad_Flag; } 200 201 /** This is a continuation of the public "Flags" enum. */ 202 enum PrivateFlags { 203 kHasStencilClip_Flag = 0x10, 204 kStencilEnabled_Flag = 0x20, 205 kScissorEnabled_Flag = 0x40, 206 kIsBad_Flag = 0x80, 207 }; 208 209 using DstTextureProxy = GrPendingIOResource<GrTextureProxy, kRead_GrIOType>; 210 using FragmentProcessorArray = SkAutoSTArray<8, std::unique_ptr<const GrFragmentProcessor>>; 211 212 DstTextureProxy fDstTextureProxy; 213 SkIPoint fDstTextureOffset; 214 GrWindowRectsState fWindowRectsState; 215 const GrUserStencilSettings* fUserStencilSettings; 216 uint16_t fFlags; 217 sk_sp<const GrXferProcessor> fXferProcessor; 218 FragmentProcessorArray fFragmentProcessors; 219 220 // This value is also the index in fFragmentProcessors where coverage processors begin. 221 int fNumColorProcessors; 222 }; 223 224 #endif 225