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, uint32_t flags = 0, 97 const GrUserStencilSettings* = &GrUserStencilSettings::kUnused); 98 99 GrPipeline(const InitArgs&, GrProcessorSet&&, GrAppliedClip&&); 100 101 GrPipeline(const GrPipeline&) = delete; 102 GrPipeline& operator=(const GrPipeline&) = delete; 103 104 /// @} 105 106 /////////////////////////////////////////////////////////////////////////// 107 /// @name GrFragmentProcessors 108 109 // Make the renderTargetContext's GrOpList be dependent on any GrOpLists in this pipeline 110 void addDependenciesTo(GrOpList* recipient, const GrCaps&) const; 111 numColorFragmentProcessors()112 int numColorFragmentProcessors() const { return fNumColorProcessors; } numCoverageFragmentProcessors()113 int numCoverageFragmentProcessors() const { 114 return fFragmentProcessors.count() - fNumColorProcessors; 115 } numFragmentProcessors()116 int numFragmentProcessors() const { return fFragmentProcessors.count(); } 117 getXferProcessor()118 const GrXferProcessor& getXferProcessor() const { 119 if (fXferProcessor) { 120 return *fXferProcessor.get(); 121 } else { 122 // A null xp member means the common src-over case. GrXferProcessor's ref'ing 123 // mechanism is not thread safe so we do not hold a ref on this global. 124 return GrPorterDuffXPFactory::SimpleSrcOverXP(); 125 } 126 } 127 128 /** 129 * If the GrXferProcessor uses a texture to access the dst color, then this returns that 130 * texture and the offset to the dst contents within that texture. 131 */ 132 GrTextureProxy* dstTextureProxy(SkIPoint* offset = nullptr) const { 133 if (offset) { 134 *offset = fDstTextureOffset; 135 } 136 return fDstTextureProxy.get(); 137 } 138 139 GrTexture* peekDstTexture(SkIPoint* offset = nullptr) const { 140 if (GrTextureProxy* dstProxy = this->dstTextureProxy(offset)) { 141 return dstProxy->peekTexture(); 142 } 143 144 return nullptr; 145 } 146 getColorFragmentProcessor(int idx)147 const GrFragmentProcessor& getColorFragmentProcessor(int idx) const { 148 SkASSERT(idx < this->numColorFragmentProcessors()); 149 return *fFragmentProcessors[idx].get(); 150 } 151 getCoverageFragmentProcessor(int idx)152 const GrFragmentProcessor& getCoverageFragmentProcessor(int idx) const { 153 SkASSERT(idx < this->numCoverageFragmentProcessors()); 154 return *fFragmentProcessors[fNumColorProcessors + idx].get(); 155 } 156 getFragmentProcessor(int idx)157 const GrFragmentProcessor& getFragmentProcessor(int idx) const { 158 return *fFragmentProcessors[idx].get(); 159 } 160 161 /// @} 162 getUserStencil()163 const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; } 164 isScissorEnabled()165 bool isScissorEnabled() const { 166 return SkToBool(fFlags & kScissorEnabled_Flag); 167 } 168 getWindowRectsState()169 const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; } 170 isHWAntialiasState()171 bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAntialias_Flag); } snapVerticesToPixelCenters()172 bool snapVerticesToPixelCenters() const { 173 return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag); 174 } hasStencilClip()175 bool hasStencilClip() const { 176 return SkToBool(fFlags & kHasStencilClip_Flag); 177 } isStencilEnabled()178 bool isStencilEnabled() const { 179 return SkToBool(fFlags & kStencilEnabled_Flag); 180 } isBad()181 bool isBad() const { return SkToBool(fFlags & kIsBad_Flag); } 182 183 GrXferBarrierType xferBarrierType(GrTexture*, const GrCaps&) const; 184 DumpFlags(uint32_t flags)185 static SkString DumpFlags(uint32_t flags) { 186 if (flags) { 187 SkString result; 188 if (flags & GrPipeline::kSnapVerticesToPixelCenters_Flag) { 189 result.append("Snap vertices to pixel center.\n"); 190 } 191 if (flags & GrPipeline::kHWAntialias_Flag) { 192 result.append("HW Antialiasing enabled.\n"); 193 } 194 return result; 195 } 196 return SkString("No pipeline flags\n"); 197 } 198 199 // Used by Vulkan and Metal to cache their respective pipeline objects 200 uint32_t getBlendInfoKey() const; 201 202 private: markAsBad()203 void markAsBad() { fFlags |= kIsBad_Flag; } 204 205 /** This is a continuation of the public "Flags" enum. */ 206 enum PrivateFlags { 207 kHasStencilClip_Flag = 0x10, 208 kStencilEnabled_Flag = 0x20, 209 kScissorEnabled_Flag = 0x40, 210 kIsBad_Flag = 0x80, 211 }; 212 213 using DstTextureProxy = GrPendingIOResource<GrTextureProxy, kRead_GrIOType>; 214 using FragmentProcessorArray = SkAutoSTArray<8, std::unique_ptr<const GrFragmentProcessor>>; 215 216 DstTextureProxy fDstTextureProxy; 217 SkIPoint fDstTextureOffset; 218 GrWindowRectsState fWindowRectsState; 219 const GrUserStencilSettings* fUserStencilSettings; 220 uint16_t fFlags; 221 sk_sp<const GrXferProcessor> fXferProcessor; 222 FragmentProcessorArray fFragmentProcessors; 223 224 // This value is also the index in fFragmentProcessors where coverage processors begin. 225 int fNumColorProcessors; 226 }; 227 228 #endif 229