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 GrPipelineBuilder_DEFINED 9 #define GrPipelineBuilder_DEFINED 10 11 #include "GrBlend.h" 12 #include "GrCaps.h" 13 #include "GrClip.h" 14 #include "GrGpuResourceRef.h" 15 #include "GrProcOptInfo.h" 16 #include "GrRenderTarget.h" 17 #include "GrStencil.h" 18 #include "GrXferProcessor.h" 19 #include "SkMatrix.h" 20 #include "effects/GrCoverageSetOpXP.h" 21 #include "effects/GrDisableColorXP.h" 22 #include "effects/GrPorterDuffXferProcessor.h" 23 #include "effects/GrSimpleTextureEffect.h" 24 25 class GrDrawBatch; 26 class GrCaps; 27 class GrPaint; 28 class GrTexture; 29 30 class GrPipelineBuilder : public SkNoncopyable { 31 public: 32 GrPipelineBuilder(); 33 34 /** 35 * Initializes the GrPipelineBuilder based on a GrPaint, render target, and clip. Note 36 * that GrPipelineBuilder encompasses more than GrPaint. Aspects of GrPipelineBuilder that have 37 * no GrPaint equivalents are set to default values with the exception of vertex attribute state 38 * which is unmodified by this function and clipping which will be enabled. 39 */ 40 GrPipelineBuilder(const GrPaint&, GrRenderTarget*, const GrClip&); 41 42 virtual ~GrPipelineBuilder(); 43 44 /////////////////////////////////////////////////////////////////////////// 45 /// @name Fragment Processors 46 /// 47 /// GrFragmentProcessors are used to compute per-pixel color and per-pixel fractional coverage. 48 /// There are two chains of FPs, one for color and one for coverage. The first FP in each 49 /// chain gets the initial color/coverage from the GrPrimitiveProcessor. It computes an output 50 /// color/coverage which is fed to the next FP in the chain. The last color and coverage FPs 51 /// feed their output to the GrXferProcessor which controls blending. 52 //// 53 numColorFragmentProcessors()54 int numColorFragmentProcessors() const { return fColorFragmentProcessors.count(); } numCoverageFragmentProcessors()55 int numCoverageFragmentProcessors() const { return fCoverageFragmentProcessors.count(); } numFragmentProcessors()56 int numFragmentProcessors() const { return this->numColorFragmentProcessors() + 57 this->numCoverageFragmentProcessors(); } 58 getColorFragmentProcessor(int idx)59 const GrFragmentProcessor* getColorFragmentProcessor(int idx) const { 60 return fColorFragmentProcessors[idx]; 61 } getCoverageFragmentProcessor(int idx)62 const GrFragmentProcessor* getCoverageFragmentProcessor(int idx) const { 63 return fCoverageFragmentProcessors[idx]; 64 } 65 addColorFragmentProcessor(const GrFragmentProcessor * processor)66 const GrFragmentProcessor* addColorFragmentProcessor(const GrFragmentProcessor* processor) { 67 SkASSERT(processor); 68 fColorFragmentProcessors.push_back(SkRef(processor)); 69 return processor; 70 } 71 addCoverageFragmentProcessor(const GrFragmentProcessor * processor)72 const GrFragmentProcessor* addCoverageFragmentProcessor(const GrFragmentProcessor* processor) { 73 SkASSERT(processor); 74 fCoverageFragmentProcessors.push_back(SkRef(processor)); 75 return processor; 76 } 77 78 /** 79 * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates. 80 */ addColorTextureProcessor(GrTexture * texture,const SkMatrix & matrix)81 void addColorTextureProcessor(GrTexture* texture, const SkMatrix& matrix) { 82 this->addColorFragmentProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref(); 83 } 84 addCoverageTextureProcessor(GrTexture * texture,const SkMatrix & matrix)85 void addCoverageTextureProcessor(GrTexture* texture, const SkMatrix& matrix) { 86 this->addCoverageFragmentProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref(); 87 } 88 addColorTextureProcessor(GrTexture * texture,const SkMatrix & matrix,const GrTextureParams & params)89 void addColorTextureProcessor(GrTexture* texture, 90 const SkMatrix& matrix, 91 const GrTextureParams& params) { 92 this->addColorFragmentProcessor(GrSimpleTextureEffect::Create(texture, matrix, 93 params))->unref(); 94 } 95 addCoverageTextureProcessor(GrTexture * texture,const SkMatrix & matrix,const GrTextureParams & params)96 void addCoverageTextureProcessor(GrTexture* texture, 97 const SkMatrix& matrix, 98 const GrTextureParams& params) { 99 this->addCoverageFragmentProcessor(GrSimpleTextureEffect::Create(texture, matrix, 100 params))->unref(); 101 } 102 103 /** 104 * When this object is destroyed it will remove any color/coverage FPs from the pipeline builder 105 * that were added after its constructor. 106 * This class can transiently modify its "const" GrPipelineBuilder object but will restore it 107 * when done - so it is notionally "const" correct. 108 */ 109 class AutoRestoreFragmentProcessorState : public ::SkNoncopyable { 110 public: AutoRestoreFragmentProcessorState()111 AutoRestoreFragmentProcessorState() 112 : fPipelineBuilder(nullptr) 113 , fColorEffectCnt(0) 114 , fCoverageEffectCnt(0) {} 115 AutoRestoreFragmentProcessorState(const GrPipelineBuilder & ds)116 AutoRestoreFragmentProcessorState(const GrPipelineBuilder& ds) 117 : fPipelineBuilder(nullptr) 118 , fColorEffectCnt(0) 119 , fCoverageEffectCnt(0) { 120 this->set(&ds); 121 } 122 ~AutoRestoreFragmentProcessorState()123 ~AutoRestoreFragmentProcessorState() { this->set(nullptr); } 124 125 void set(const GrPipelineBuilder* ds); 126 isSet()127 bool isSet() const { return SkToBool(fPipelineBuilder); } 128 addCoverageFragmentProcessor(const GrFragmentProcessor * processor)129 const GrFragmentProcessor* addCoverageFragmentProcessor( 130 const GrFragmentProcessor* processor) { 131 SkASSERT(this->isSet()); 132 return fPipelineBuilder->addCoverageFragmentProcessor(processor); 133 } 134 135 private: 136 // notionally const (as marginalia) 137 GrPipelineBuilder* fPipelineBuilder; 138 int fColorEffectCnt; 139 int fCoverageEffectCnt; 140 }; 141 142 /// @} 143 144 /////////////////////////////////////////////////////////////////////////// 145 /// @name Blending 146 //// 147 148 /** 149 * Installs a GrXPFactory. This object controls how src color, fractional pixel coverage, 150 * and the dst color are blended. 151 */ setXPFactory(const GrXPFactory * xpFactory)152 const GrXPFactory* setXPFactory(const GrXPFactory* xpFactory) { 153 fXPFactory.reset(SkSafeRef(xpFactory)); 154 return xpFactory; 155 } 156 157 /** 158 * Sets a GrXPFactory that will ignore src color and perform a set operation between the draws 159 * output coverage and the destination. This is useful to render coverage masks as CSG. 160 */ 161 void setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage = false) { 162 fXPFactory.reset(GrCoverageSetOpXPFactory::Create(regionOp, invertCoverage)); 163 } 164 165 /** 166 * Sets a GrXPFactory that disables color writes to the destination. This is useful when 167 * rendering to the stencil buffer. 168 */ setDisableColorXPFactory()169 void setDisableColorXPFactory() { 170 fXPFactory.reset(GrDisableColorXPFactory::Create()); 171 } 172 getXPFactory()173 const GrXPFactory* getXPFactory() const { 174 return fXPFactory; 175 } 176 177 /** 178 * Checks whether the xp will need destination in a texture to correctly blend. 179 */ 180 bool willXPNeedDstTexture(const GrCaps& caps, 181 const GrPipelineOptimizations& optimizations) const; 182 183 /// @} 184 185 186 /////////////////////////////////////////////////////////////////////////// 187 /// @name Render Target 188 //// 189 190 /** 191 * Retrieves the currently set render-target. 192 * 193 * @return The currently set render target. 194 */ getRenderTarget()195 GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); } 196 197 /** 198 * Sets the render-target used at the next drawing call 199 * 200 * @param target The render target to set. 201 */ setRenderTarget(GrRenderTarget * target)202 void setRenderTarget(GrRenderTarget* target) { fRenderTarget.reset(SkSafeRef(target)); } 203 204 /** 205 * Returns whether the rasterizer and stencil test (if any) will run at a higher sample rate 206 * than the color buffer. In is scenario, the higher sample rate is resolved during blending. 207 */ hasMixedSamples()208 bool hasMixedSamples() const { 209 return fRenderTarget->hasMixedSamples() && 210 (this->isHWAntialias() || !fStencilSettings.isDisabled()); 211 } 212 213 /// @} 214 215 /////////////////////////////////////////////////////////////////////////// 216 /// @name Stencil 217 //// 218 getStencil()219 const GrStencilSettings& getStencil() const { return fStencilSettings; } 220 221 /** 222 * Sets the stencil settings to use for the next draw. 223 * Changing the clip has the side-effect of possibly zeroing 224 * out the client settable stencil bits. So multipass algorithms 225 * using stencil should not change the clip between passes. 226 * @param settings the stencil settings to use. 227 */ setStencil(const GrStencilSettings & settings)228 void setStencil(const GrStencilSettings& settings) { fStencilSettings = settings; } 229 stencil()230 GrStencilSettings* stencil() { return &fStencilSettings; } 231 232 /** 233 * AutoRestoreStencil 234 * 235 * This simple struct saves and restores the stencil settings 236 * This class can transiently modify its "const" GrPipelineBuilder object but will restore it 237 * when done - so it is notionally "const" correct. 238 */ 239 class AutoRestoreStencil : public ::SkNoncopyable { 240 public: AutoRestoreStencil()241 AutoRestoreStencil() : fPipelineBuilder(nullptr) {} 242 AutoRestoreStencil(const GrPipelineBuilder & ds)243 AutoRestoreStencil(const GrPipelineBuilder& ds) : fPipelineBuilder(nullptr) { this->set(&ds); } 244 ~AutoRestoreStencil()245 ~AutoRestoreStencil() { this->set(nullptr); } 246 set(const GrPipelineBuilder * ds)247 void set(const GrPipelineBuilder* ds) { 248 if (fPipelineBuilder) { 249 fPipelineBuilder->setStencil(fStencilSettings); 250 } 251 fPipelineBuilder = const_cast<GrPipelineBuilder*>(ds); 252 if (ds) { 253 fStencilSettings = ds->getStencil(); 254 } 255 } 256 isSet()257 bool isSet() const { return SkToBool(fPipelineBuilder); } 258 setStencil(const GrStencilSettings & settings)259 void setStencil(const GrStencilSettings& settings) { 260 SkASSERT(this->isSet()); 261 fPipelineBuilder->setStencil(settings); 262 } 263 264 private: 265 // notionally const (as marginalia) 266 GrPipelineBuilder* fPipelineBuilder; 267 GrStencilSettings fStencilSettings; 268 }; 269 270 271 /// @} 272 273 /////////////////////////////////////////////////////////////////////////// 274 /// @name State Flags 275 //// 276 277 /** 278 * Flags that affect rendering. Controlled using enable/disableState(). All 279 * default to disabled. 280 */ 281 enum Flags { 282 /** 283 * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target, 284 * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by 285 * the 3D API. 286 */ 287 kHWAntialias_Flag = 0x01, 288 289 /** 290 * Modifies the vertex shader so that vertices will be positioned at pixel centers. 291 */ 292 kSnapVerticesToPixelCenters_Flag = 0x02, 293 294 kLast_Flag = kSnapVerticesToPixelCenters_Flag, 295 }; 296 isHWAntialias()297 bool isHWAntialias() const { return SkToBool(fFlags & kHWAntialias_Flag); } snapVerticesToPixelCenters()298 bool snapVerticesToPixelCenters() const { 299 return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag); } 300 301 /** 302 * Enable render state settings. 303 * 304 * @param flags bitfield of Flags specifying the states to enable 305 */ enableState(uint32_t flags)306 void enableState(uint32_t flags) { fFlags |= flags; } 307 308 /** 309 * Disable render state settings. 310 * 311 * @param flags bitfield of Flags specifying the states to disable 312 */ disableState(uint32_t flags)313 void disableState(uint32_t flags) { fFlags &= ~(flags); } 314 315 /** 316 * Enable or disable flags based on a boolean. 317 * 318 * @param flags bitfield of Flags to enable or disable 319 * @param enable if true enable stateBits, otherwise disable 320 */ setState(uint32_t flags,bool enable)321 void setState(uint32_t flags, bool enable) { 322 if (enable) { 323 this->enableState(flags); 324 } else { 325 this->disableState(flags); 326 } 327 } 328 329 /// @} 330 331 /////////////////////////////////////////////////////////////////////////// 332 /// @name Face Culling 333 //// 334 335 enum DrawFace { 336 kInvalid_DrawFace = -1, 337 338 kBoth_DrawFace, 339 kCCW_DrawFace, 340 kCW_DrawFace, 341 }; 342 343 /** 344 * Gets whether the target is drawing clockwise, counterclockwise, 345 * or both faces. 346 * @return the current draw face(s). 347 */ getDrawFace()348 DrawFace getDrawFace() const { return fDrawFace; } 349 350 /** 351 * Controls whether clockwise, counterclockwise, or both faces are drawn. 352 * @param face the face(s) to draw. 353 */ setDrawFace(DrawFace face)354 void setDrawFace(DrawFace face) { 355 SkASSERT(kInvalid_DrawFace != face); 356 fDrawFace = face; 357 } 358 359 /// @} 360 361 /////////////////////////////////////////////////////////////////////////// 362 363 bool usePLSDstRead(const GrDrawBatch* batch) const; 364 setClip(const GrClip & clip)365 void setClip(const GrClip& clip) { fClip = clip; } clip()366 const GrClip& clip() const { return fClip; } 367 368 private: 369 // Some of the auto restore objects assume that no effects are removed during their lifetime. 370 // This is used to assert that this condition holds. 371 SkDEBUGCODE(mutable int fBlockEffectRemovalCnt;) 372 373 typedef SkSTArray<4, const GrFragmentProcessor*, true> FragmentProcessorArray; 374 375 SkAutoTUnref<GrRenderTarget> fRenderTarget; 376 uint32_t fFlags; 377 GrStencilSettings fStencilSettings; 378 DrawFace fDrawFace; 379 mutable SkAutoTUnref<const GrXPFactory> fXPFactory; 380 FragmentProcessorArray fColorFragmentProcessors; 381 FragmentProcessorArray fCoverageFragmentProcessors; 382 GrClip fClip; 383 384 friend class GrPipeline; 385 friend class GrDrawTarget; 386 }; 387 388 #endif 389