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 "include/core/SkMatrix.h" 12 #include "include/core/SkRefCnt.h" 13 #include "src/gpu/GrColor.h" 14 #include "src/gpu/GrFragmentProcessor.h" 15 #include "src/gpu/GrNonAtomicRef.h" 16 #include "src/gpu/GrPendingIOResource.h" 17 #include "src/gpu/GrProcessorSet.h" 18 #include "src/gpu/GrProgramDesc.h" 19 #include "src/gpu/GrScissorState.h" 20 #include "src/gpu/GrUserStencilSettings.h" 21 #include "src/gpu/GrWindowRectsState.h" 22 #include "src/gpu/effects/GrCoverageSetOpXP.h" 23 #include "src/gpu/effects/GrDisableColorXP.h" 24 #include "src/gpu/effects/GrPorterDuffXferProcessor.h" 25 #include "src/gpu/effects/generated/GrSimpleTextureEffect.h" 26 #include "src/gpu/geometry/GrRect.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 // Pipeline options that the caller may enable. 43 // NOTE: This enum is extended later by GrPipeline::Flags. 44 enum class InputFlags : uint8_t { 45 kNone = 0, 46 /** 47 * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target, 48 * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by 49 * the 3D API. 50 */ 51 kHWAntialias = (1 << 0), 52 /** 53 * Modifies the vertex shader so that vertices will be positioned at pixel centers. 54 */ 55 kSnapVerticesToPixelCenters = (1 << 1), // This value must be last. (See kLastInputFlag.) 56 }; 57 58 struct InitArgs { 59 InputFlags fInputFlags = InputFlags::kNone; 60 const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused; 61 const GrCaps* fCaps = nullptr; 62 GrXferProcessor::DstProxy fDstProxy; 63 GrSwizzle fOutputSwizzle; 64 }; 65 66 /** 67 * Some state can be changed between GrMeshes without changing GrPipelines. This is generally 68 * less expensive then using multiple pipelines. Such state is called "dynamic state". It can 69 * be specified in two ways: 70 * 1) FixedDynamicState - use this to specify state that does not vary between GrMeshes. 71 * 2) DynamicStateArrays - use this to specify per mesh values for dynamic state. 72 **/ 73 struct FixedDynamicState { FixedDynamicStateFixedDynamicState74 explicit FixedDynamicState(const SkIRect& scissorRect) : fScissorRect(scissorRect) {} 75 FixedDynamicState() = default; 76 SkIRect fScissorRect = SkIRect::EmptyIRect(); 77 // Must have GrPrimitiveProcessor::numTextureSamplers() entries. Can be null if no samplers 78 // or textures are passed using DynamicStateArrays. 79 GrTextureProxy** fPrimitiveProcessorTextures = nullptr; 80 }; 81 82 /** 83 * Any non-null array overrides the FixedDynamicState on a mesh-by-mesh basis. Arrays must 84 * have one entry for each GrMesh. 85 */ 86 struct DynamicStateArrays { 87 const SkIRect* fScissorRects = nullptr; 88 // Must have GrPrimitiveProcessor::numTextureSamplers() * num_meshes entries. 89 // Can be null if no samplers or to use the same textures for all meshes via' 90 // FixedDynamicState. 91 GrTextureProxy** fPrimitiveProcessorTextures = nullptr; 92 }; 93 94 /** 95 * Creates a simple pipeline with default settings and no processors. The provided blend mode 96 * must be "Porter Duff" (<= kLastCoeffMode). If using GrScissorTest::kEnabled, the caller must 97 * specify a scissor rectangle through the DynamicState struct. 98 **/ 99 GrPipeline(GrScissorTest scissor, SkBlendMode blend, const GrSwizzle& outputSwizzle, 100 InputFlags flags = InputFlags::kNone, 101 const GrUserStencilSettings* stencil = &GrUserStencilSettings::kUnused) GrPipeline(scissor,GrPorterDuffXPFactory::MakeNoCoverageXP (blend),outputSwizzle,flags,stencil)102 : GrPipeline(scissor, GrPorterDuffXPFactory::MakeNoCoverageXP(blend), outputSwizzle, 103 flags, stencil) { 104 } 105 106 GrPipeline(GrScissorTest, sk_sp<const GrXferProcessor>, const GrSwizzle& outputSwizzle, 107 InputFlags = InputFlags::kNone, 108 const GrUserStencilSettings* = &GrUserStencilSettings::kUnused); 109 110 GrPipeline(const InitArgs&, GrProcessorSet&&, GrAppliedClip&&); 111 112 GrPipeline(const GrPipeline&) = delete; 113 GrPipeline& operator=(const GrPipeline&) = delete; 114 115 /// @} 116 117 /////////////////////////////////////////////////////////////////////////// 118 /// @name GrFragmentProcessors 119 numColorFragmentProcessors()120 int numColorFragmentProcessors() const { return fNumColorProcessors; } numCoverageFragmentProcessors()121 int numCoverageFragmentProcessors() const { 122 return fFragmentProcessors.count() - fNumColorProcessors; 123 } numFragmentProcessors()124 int numFragmentProcessors() const { return fFragmentProcessors.count(); } 125 getXferProcessor()126 const GrXferProcessor& getXferProcessor() const { 127 if (fXferProcessor) { 128 return *fXferProcessor.get(); 129 } else { 130 // A null xp member means the common src-over case. GrXferProcessor's ref'ing 131 // mechanism is not thread safe so we do not hold a ref on this global. 132 return GrPorterDuffXPFactory::SimpleSrcOverXP(); 133 } 134 } 135 136 /** 137 * If the GrXferProcessor uses a texture to access the dst color, then this returns that 138 * texture and the offset to the dst contents within that texture. 139 */ 140 GrTextureProxy* dstTextureProxy(SkIPoint* offset = nullptr) const { 141 if (offset) { 142 *offset = fDstTextureOffset; 143 } 144 145 return fDstTextureProxy ? fDstTextureProxy->asTextureProxy() : nullptr; 146 } 147 148 GrTexture* peekDstTexture(SkIPoint* offset = nullptr) const { 149 if (GrTextureProxy* dstProxy = this->dstTextureProxy(offset)) { 150 return dstProxy->peekTexture(); 151 } 152 153 return nullptr; 154 } 155 getColorFragmentProcessor(int idx)156 const GrFragmentProcessor& getColorFragmentProcessor(int idx) const { 157 SkASSERT(idx < this->numColorFragmentProcessors()); 158 return *fFragmentProcessors[idx].get(); 159 } 160 getCoverageFragmentProcessor(int idx)161 const GrFragmentProcessor& getCoverageFragmentProcessor(int idx) const { 162 SkASSERT(idx < this->numCoverageFragmentProcessors()); 163 return *fFragmentProcessors[fNumColorProcessors + idx].get(); 164 } 165 getFragmentProcessor(int idx)166 const GrFragmentProcessor& getFragmentProcessor(int idx) const { 167 return *fFragmentProcessors[idx].get(); 168 } 169 170 /// @} 171 getUserStencil()172 const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; } 173 isScissorEnabled()174 bool isScissorEnabled() const { 175 return SkToBool(fFlags & Flags::kScissorEnabled); 176 } 177 getWindowRectsState()178 const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; } 179 isHWAntialiasState()180 bool isHWAntialiasState() const { return SkToBool(fFlags & InputFlags::kHWAntialias); } snapVerticesToPixelCenters()181 bool snapVerticesToPixelCenters() const { 182 return SkToBool(fFlags & InputFlags::kSnapVerticesToPixelCenters); 183 } hasStencilClip()184 bool hasStencilClip() const { 185 return SkToBool(fFlags & Flags::kHasStencilClip); 186 } isStencilEnabled()187 bool isStencilEnabled() const { 188 return SkToBool(fFlags & Flags::kStencilEnabled); 189 } 190 SkDEBUGCODE(bool isBad() const { return SkToBool(fFlags & Flags::kIsBad); }) 191 192 GrXferBarrierType xferBarrierType(GrTexture*, const GrCaps&) const; 193 194 // Used by Vulkan and Metal to cache their respective pipeline objects 195 uint32_t getBlendInfoKey() const; 196 outputSwizzle()197 const GrSwizzle& outputSwizzle() const { return fOutputSwizzle; } 198 199 private: 200 201 SkDEBUGCODE(void markAsBad() { fFlags |= Flags::kIsBad; }) 202 203 static constexpr uint8_t kLastInputFlag = (uint8_t)InputFlags::kSnapVerticesToPixelCenters; 204 205 /** This is a continuation of the public "InputFlags" enum. */ 206 enum class Flags : uint8_t { 207 kHasStencilClip = (kLastInputFlag << 1), 208 kStencilEnabled = (kLastInputFlag << 2), 209 kScissorEnabled = (kLastInputFlag << 3), 210 #ifdef SK_DEBUG 211 kIsBad = (kLastInputFlag << 4), 212 #endif 213 }; 214 215 GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags); 216 217 friend bool operator&(Flags, InputFlags); 218 219 using FragmentProcessorArray = SkAutoSTArray<8, std::unique_ptr<const GrFragmentProcessor>>; 220 221 GrProxyPendingIO fDstTextureProxy; 222 SkIPoint fDstTextureOffset; 223 GrWindowRectsState fWindowRectsState; 224 const GrUserStencilSettings* fUserStencilSettings; 225 Flags fFlags; 226 sk_sp<const GrXferProcessor> fXferProcessor; 227 FragmentProcessorArray fFragmentProcessors; 228 229 // This value is also the index in fFragmentProcessors where coverage processors begin. 230 int fNumColorProcessors; 231 232 GrSwizzle fOutputSwizzle; 233 }; 234 235 GR_MAKE_BITFIELD_CLASS_OPS(GrPipeline::InputFlags); 236 GR_MAKE_BITFIELD_CLASS_OPS(GrPipeline::Flags); 237 238 inline bool operator&(GrPipeline::Flags flags, GrPipeline::InputFlags inputFlag) { 239 return (flags & (GrPipeline::Flags)inputFlag); 240 } 241 242 #endif 243