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 "GrProcessorSet.h" 16 #include "GrProgramDesc.h" 17 #include "GrRect.h" 18 #include "GrRenderTargetProxy.h" 19 #include "GrScissorState.h" 20 #include "GrUserStencilSettings.h" 21 #include "GrWindowRectsState.h" 22 #include "SkMatrix.h" 23 #include "SkRefCnt.h" 24 #include "effects/GrCoverageSetOpXP.h" 25 #include "effects/GrDisableColorXP.h" 26 #include "effects/GrPorterDuffXferProcessor.h" 27 #include "effects/GrSimpleTextureEffect.h" 28 29 class GrAppliedClip; 30 class GrDeviceCoordTexture; 31 class GrOp; 32 class GrRenderTargetContext; 33 34 /** 35 * This immutable object contains information needed to set build a shader program and set API 36 * state for a draw. It is used along with a GrPrimitiveProcessor and a source of geometric 37 * data (GrMesh or GrPath) to draw. 38 */ 39 class GrPipeline { 40 public: 41 /////////////////////////////////////////////////////////////////////////// 42 /// @name Creation 43 44 enum Flags { 45 /** 46 * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target, 47 * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by 48 * the 3D API. 49 */ 50 kHWAntialias_Flag = 0x1, 51 /** 52 * Modifies the vertex shader so that vertices will be positioned at pixel centers. 53 */ 54 kSnapVerticesToPixelCenters_Flag = 0x2, 55 /** Disables conversion to sRGB from linear when writing to a sRGB destination. */ 56 kDisableOutputConversionToSRGB_Flag = 0x4, 57 /** Allows conversion from sRGB to linear when reading from processor's sRGB texture. */ 58 kAllowSRGBInputs_Flag = 0x8, 59 }; 60 SRGBFlagsFromPaint(const GrPaint & paint)61 static uint32_t SRGBFlagsFromPaint(const GrPaint& paint) { 62 uint32_t flags = 0; 63 if (paint.getAllowSRGBInputs()) { 64 flags |= kAllowSRGBInputs_Flag; 65 } 66 if (paint.getDisableOutputConversionToSRGB()) { 67 flags |= kDisableOutputConversionToSRGB_Flag; 68 } 69 return flags; 70 } 71 72 enum ScissorState : bool { 73 kEnabled = true, 74 kDisabled = false 75 }; 76 77 struct InitArgs { 78 uint32_t fFlags = 0; 79 const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused; 80 GrRenderTargetProxy* fProxy = nullptr; 81 const GrCaps* fCaps = nullptr; 82 GrResourceProvider* fResourceProvider = nullptr; 83 GrXferProcessor::DstProxy fDstProxy; 84 }; 85 86 /** 87 * Graphics state that can change dynamically without creating a new pipeline. 88 **/ 89 struct DynamicState { 90 // Overrides the scissor rectangle (if scissor is enabled in the pipeline). 91 // TODO: eventually this should be the only way to specify a scissor rectangle, as is the 92 // case with the simple constructor. 93 SkIRect fScissorRect; 94 }; 95 96 /** 97 * Creates a simple pipeline with default settings and no processors. The provided blend mode 98 * must be "Porter Duff" (<= kLastCoeffMode). If using ScissorState::kEnabled, the caller must 99 * specify a scissor rectangle through the DynamicState struct. 100 **/ 101 GrPipeline(GrRenderTargetProxy*, ScissorState, SkBlendMode); 102 103 GrPipeline(const InitArgs&, GrProcessorSet&&, GrAppliedClip&&); 104 105 GrPipeline(const GrPipeline&) = delete; 106 GrPipeline& operator=(const GrPipeline&) = delete; 107 108 /// @} 109 110 /////////////////////////////////////////////////////////////////////////// 111 /// @name GrFragmentProcessors 112 113 // Make the renderTargetContext's GrOpList be dependent on any GrOpLists in this pipeline 114 void addDependenciesTo(GrOpList* recipient, const GrCaps&) const; 115 numColorFragmentProcessors()116 int numColorFragmentProcessors() const { return fNumColorProcessors; } numCoverageFragmentProcessors()117 int numCoverageFragmentProcessors() const { 118 return fFragmentProcessors.count() - fNumColorProcessors; 119 } numFragmentProcessors()120 int numFragmentProcessors() const { return fFragmentProcessors.count(); } 121 getXferProcessor()122 const GrXferProcessor& getXferProcessor() const { 123 if (fXferProcessor) { 124 return *fXferProcessor.get(); 125 } else { 126 // A null xp member means the common src-over case. GrXferProcessor's ref'ing 127 // mechanism is not thread safe so we do not hold a ref on this global. 128 return GrPorterDuffXPFactory::SimpleSrcOverXP(); 129 } 130 } 131 132 /** 133 * If the GrXferProcessor uses a texture to access the dst color, then this returns that 134 * texture and the offset to the dst contents within that texture. 135 */ 136 GrTextureProxy* dstTextureProxy(SkIPoint* offset = nullptr) const { 137 if (offset) { 138 *offset = fDstTextureOffset; 139 } 140 return fDstTextureProxy.get(); 141 } 142 143 GrTexture* peekDstTexture(SkIPoint* offset = nullptr) const { 144 if (GrTextureProxy* dstProxy = this->dstTextureProxy(offset)) { 145 return dstProxy->priv().peekTexture(); 146 } 147 148 return nullptr; 149 } 150 getColorFragmentProcessor(int idx)151 const GrFragmentProcessor& getColorFragmentProcessor(int idx) const { 152 SkASSERT(idx < this->numColorFragmentProcessors()); 153 return *fFragmentProcessors[idx].get(); 154 } 155 getCoverageFragmentProcessor(int idx)156 const GrFragmentProcessor& getCoverageFragmentProcessor(int idx) const { 157 SkASSERT(idx < this->numCoverageFragmentProcessors()); 158 return *fFragmentProcessors[fNumColorProcessors + idx].get(); 159 } 160 getFragmentProcessor(int idx)161 const GrFragmentProcessor& getFragmentProcessor(int idx) const { 162 return *fFragmentProcessors[idx].get(); 163 } 164 165 /// @} 166 167 /** 168 * Retrieves the currently set render-target. 169 * 170 * @return The currently set render target. 171 */ proxy()172 GrRenderTargetProxy* proxy() const { return fProxy.get(); } renderTarget()173 GrRenderTarget* renderTarget() const { return fProxy.get()->priv().peekRenderTarget(); } 174 getUserStencil()175 const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; } 176 getScissorState()177 const GrScissorState& getScissorState() const { return fScissorState; } 178 getWindowRectsState()179 const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; } 180 isHWAntialiasState()181 bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAntialias_Flag); } snapVerticesToPixelCenters()182 bool snapVerticesToPixelCenters() const { 183 return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag); 184 } getDisableOutputConversionToSRGB()185 bool getDisableOutputConversionToSRGB() const { 186 return SkToBool(fFlags & kDisableOutputConversionToSRGB_Flag); 187 } getAllowSRGBInputs()188 bool getAllowSRGBInputs() const { 189 return SkToBool(fFlags & kAllowSRGBInputs_Flag); 190 } hasStencilClip()191 bool hasStencilClip() const { 192 return SkToBool(fFlags & kHasStencilClip_Flag); 193 } isStencilEnabled()194 bool isStencilEnabled() const { 195 return SkToBool(fFlags & kStencilEnabled_Flag); 196 } isBad()197 bool isBad() const { return SkToBool(fFlags & kIsBad_Flag); } 198 199 GrXferBarrierType xferBarrierType(const GrCaps& caps) const; 200 DumpFlags(uint32_t flags)201 static SkString DumpFlags(uint32_t flags) { 202 if (flags) { 203 SkString result; 204 if (flags & GrPipeline::kSnapVerticesToPixelCenters_Flag) { 205 result.append("Snap vertices to pixel center.\n"); 206 } 207 if (flags & GrPipeline::kHWAntialias_Flag) { 208 result.append("HW Antialiasing enabled.\n"); 209 } 210 if (flags & GrPipeline::kDisableOutputConversionToSRGB_Flag) { 211 result.append("Disable output conversion to sRGB.\n"); 212 } 213 if (flags & GrPipeline::kAllowSRGBInputs_Flag) { 214 result.append("Allow sRGB Inputs.\n"); 215 } 216 return result; 217 } 218 return SkString("No pipeline flags\n"); 219 } 220 221 private: markAsBad()222 void markAsBad() { fFlags |= kIsBad_Flag; } 223 224 /** This is a continuation of the public "Flags" enum. */ 225 enum PrivateFlags { 226 kHasStencilClip_Flag = 0x10, 227 kStencilEnabled_Flag = 0x20, 228 kIsBad_Flag = 0x40, 229 }; 230 231 using RenderTargetProxy = GrPendingIOResource<GrRenderTargetProxy, kWrite_GrIOType>; 232 using DstTextureProxy = GrPendingIOResource<GrTextureProxy, kRead_GrIOType>; 233 using FragmentProcessorArray = SkAutoSTArray<8, std::unique_ptr<const GrFragmentProcessor>>; 234 235 DstTextureProxy fDstTextureProxy; 236 SkIPoint fDstTextureOffset; 237 // MDB TODO: do we still need the destination proxy here? 238 RenderTargetProxy fProxy; 239 GrScissorState fScissorState; 240 GrWindowRectsState fWindowRectsState; 241 const GrUserStencilSettings* fUserStencilSettings; 242 uint16_t fFlags; 243 sk_sp<const GrXferProcessor> fXferProcessor; 244 FragmentProcessorArray fFragmentProcessors; 245 246 // This value is also the index in fFragmentProcessors where coverage processors begin. 247 int fNumColorProcessors; 248 249 typedef SkRefCnt INHERITED; 250 }; 251 252 #endif 253