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 "GrClip.h" 13 #include "GrDrawTargetCaps.h" 14 #include "GrGpuResourceRef.h" 15 #include "GrFragmentStage.h" 16 #include "GrProcOptInfo.h" 17 #include "GrRenderTarget.h" 18 #include "GrStencil.h" 19 #include "GrXferProcessor.h" 20 #include "SkMatrix.h" 21 #include "effects/GrCoverageSetOpXP.h" 22 #include "effects/GrDisableColorXP.h" 23 #include "effects/GrPorterDuffXferProcessor.h" 24 #include "effects/GrSimpleTextureEffect.h" 25 26 class GrBatch; 27 class GrDrawTargetCaps; 28 class GrPaint; 29 class GrTexture; 30 31 class GrPipelineBuilder { 32 public: 33 GrPipelineBuilder(); 34 GrPipelineBuilder(const GrPipelineBuilder & pipelineBuilder)35 GrPipelineBuilder(const GrPipelineBuilder& pipelineBuilder) { 36 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;) 37 *this = pipelineBuilder; 38 } 39 40 virtual ~GrPipelineBuilder(); 41 42 /** 43 * Initializes the GrPipelineBuilder based on a GrPaint, view matrix and render target. Note 44 * that GrPipelineBuilder encompasses more than GrPaint. Aspects of GrPipelineBuilder that have 45 * no GrPaint equivalents are set to default values with the exception of vertex attribute state 46 * which is unmodified by this function and clipping which will be enabled. 47 */ 48 void setFromPaint(const GrPaint&, GrRenderTarget*, const GrClip&); 49 50 /////////////////////////////////////////////////////////////////////////// 51 /// @name Fragment Processors 52 /// 53 /// GrFragmentProcessors are used to compute per-pixel color and per-pixel fractional coverage. 54 /// There are two chains of FPs, one for color and one for coverage. The first FP in each 55 /// chain gets the initial color/coverage from the GrPrimitiveProcessor. It computes an output 56 /// color/coverage which is fed to the next FP in the chain. The last color and coverage FPs 57 /// feed their output to the GrXferProcessor which controls blending. 58 //// 59 numColorFragmentStages()60 int numColorFragmentStages() const { return fColorStages.count(); } numCoverageFragmentStages()61 int numCoverageFragmentStages() const { return fCoverageStages.count(); } numFragmentStages()62 int numFragmentStages() const { return this->numColorFragmentStages() + 63 this->numCoverageFragmentStages(); } 64 getColorFragmentStage(int idx)65 const GrFragmentStage& getColorFragmentStage(int idx) const { return fColorStages[idx]; } getCoverageFragmentStage(int idx)66 const GrFragmentStage& getCoverageFragmentStage(int idx) const { return fCoverageStages[idx]; } 67 addColorProcessor(const GrFragmentProcessor * effect)68 const GrFragmentProcessor* addColorProcessor(const GrFragmentProcessor* effect) { 69 SkASSERT(effect); 70 SkNEW_APPEND_TO_TARRAY(&fColorStages, GrFragmentStage, (effect)); 71 fColorProcInfoValid = false; 72 return effect; 73 } 74 addCoverageProcessor(const GrFragmentProcessor * effect)75 const GrFragmentProcessor* addCoverageProcessor(const GrFragmentProcessor* effect) { 76 SkASSERT(effect); 77 SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrFragmentStage, (effect)); 78 fCoverageProcInfoValid = false; 79 return effect; 80 } 81 82 /** 83 * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates. 84 */ addColorTextureProcessor(GrTexture * texture,const SkMatrix & matrix)85 void addColorTextureProcessor(GrTexture* texture, const SkMatrix& matrix) { 86 this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref(); 87 } 88 addCoverageTextureProcessor(GrTexture * texture,const SkMatrix & matrix)89 void addCoverageTextureProcessor(GrTexture* texture, const SkMatrix& matrix) { 90 this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref(); 91 } 92 addColorTextureProcessor(GrTexture * texture,const SkMatrix & matrix,const GrTextureParams & params)93 void addColorTextureProcessor(GrTexture* texture, 94 const SkMatrix& matrix, 95 const GrTextureParams& params) { 96 this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref(); 97 } 98 addCoverageTextureProcessor(GrTexture * texture,const SkMatrix & matrix,const GrTextureParams & params)99 void addCoverageTextureProcessor(GrTexture* texture, 100 const SkMatrix& matrix, 101 const GrTextureParams& params) { 102 this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref(); 103 } 104 105 /** 106 * When this object is destroyed it will remove any color/coverage FPs from the pipeline builder 107 * that were added after its constructor. 108 */ 109 class AutoRestoreFragmentProcessors : public ::SkNoncopyable { 110 public: AutoRestoreFragmentProcessors()111 AutoRestoreFragmentProcessors() 112 : fPipelineBuilder(NULL) 113 , fColorEffectCnt(0) 114 , fCoverageEffectCnt(0) {} 115 AutoRestoreFragmentProcessors(GrPipelineBuilder * ds)116 AutoRestoreFragmentProcessors(GrPipelineBuilder* ds) 117 : fPipelineBuilder(NULL) 118 , fColorEffectCnt(0) 119 , fCoverageEffectCnt(0) { 120 this->set(ds); 121 } 122 ~AutoRestoreFragmentProcessors()123 ~AutoRestoreFragmentProcessors() { this->set(NULL); } 124 125 void set(GrPipelineBuilder* ds); 126 isSet()127 bool isSet() const { return SkToBool(fPipelineBuilder); } 128 129 private: 130 GrPipelineBuilder* fPipelineBuilder; 131 int fColorEffectCnt; 132 int fCoverageEffectCnt; 133 }; 134 135 /// @} 136 137 /////////////////////////////////////////////////////////////////////////// 138 /// @name Blending 139 //// 140 141 /** 142 * This function returns true if the render target destination pixel values will be read for 143 * blending during draw. 144 */ 145 bool willBlendWithDst(const GrPrimitiveProcessor*) const; 146 147 /** 148 * Installs a GrXPFactory. This object controls how src color, fractional pixel coverage, 149 * and the dst color are blended. 150 */ setXPFactory(const GrXPFactory * xpFactory)151 const GrXPFactory* setXPFactory(const GrXPFactory* xpFactory) { 152 fXPFactory.reset(SkRef(xpFactory)); 153 return xpFactory; 154 } 155 156 /** 157 * Sets a GrXPFactory that will ignore src color and perform a set operation between the draws 158 * output coverage and the destination. This is useful to render coverage masks as CSG. 159 */ 160 void setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage = false) { 161 fXPFactory.reset(GrCoverageSetOpXPFactory::Create(regionOp, invertCoverage)); 162 } 163 164 /** 165 * Sets a GrXPFactory that disables color writes to the destination. This is useful when 166 * rendering to the stencil buffer. 167 */ setDisableColorXPFactory()168 void setDisableColorXPFactory() { 169 fXPFactory.reset(GrDisableColorXPFactory::Create()); 170 } 171 getXPFactory()172 const GrXPFactory* getXPFactory() const { 173 if (!fXPFactory) { 174 fXPFactory.reset(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode)); 175 } 176 return fXPFactory.get(); 177 } 178 179 /** 180 * Checks whether the xp will need a copy of the destination to correctly blend. 181 */ 182 bool willXPNeedDstCopy(const GrDrawTargetCaps& caps, const GrProcOptInfo& colorPOI, 183 const GrProcOptInfo& coveragePOI) const; 184 185 /// @} 186 187 188 /////////////////////////////////////////////////////////////////////////// 189 /// @name Render Target 190 //// 191 192 /** 193 * Retrieves the currently set render-target. 194 * 195 * @return The currently set render target. 196 */ getRenderTarget()197 GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); } 198 199 /** 200 * Sets the render-target used at the next drawing call 201 * 202 * @param target The render target to set. 203 */ setRenderTarget(GrRenderTarget * target)204 void setRenderTarget(GrRenderTarget* target) { fRenderTarget.reset(SkSafeRef(target)); } 205 206 /// @} 207 208 /////////////////////////////////////////////////////////////////////////// 209 /// @name Stencil 210 //// 211 getStencil()212 const GrStencilSettings& getStencil() const { return fStencilSettings; } 213 214 /** 215 * Sets the stencil settings to use for the next draw. 216 * Changing the clip has the side-effect of possibly zeroing 217 * out the client settable stencil bits. So multipass algorithms 218 * using stencil should not change the clip between passes. 219 * @param settings the stencil settings to use. 220 */ setStencil(const GrStencilSettings & settings)221 void setStencil(const GrStencilSettings& settings) { fStencilSettings = settings; } 222 223 /** 224 * Shortcut to disable stencil testing and ops. 225 */ disableStencil()226 void disableStencil() { fStencilSettings.setDisabled(); } 227 stencil()228 GrStencilSettings* stencil() { return &fStencilSettings; } 229 230 /** 231 * AutoRestoreStencil 232 * 233 * This simple struct saves and restores the stencil settings 234 */ 235 class AutoRestoreStencil : public ::SkNoncopyable { 236 public: AutoRestoreStencil()237 AutoRestoreStencil() : fPipelineBuilder(NULL) {} 238 AutoRestoreStencil(GrPipelineBuilder * ds)239 AutoRestoreStencil(GrPipelineBuilder* ds) : fPipelineBuilder(NULL) { this->set(ds); } 240 ~AutoRestoreStencil()241 ~AutoRestoreStencil() { this->set(NULL); } 242 set(GrPipelineBuilder * ds)243 void set(GrPipelineBuilder* ds) { 244 if (fPipelineBuilder) { 245 fPipelineBuilder->setStencil(fStencilSettings); 246 } 247 fPipelineBuilder = ds; 248 if (ds) { 249 fStencilSettings = ds->getStencil(); 250 } 251 } 252 isSet()253 bool isSet() const { return SkToBool(fPipelineBuilder); } 254 255 private: 256 GrPipelineBuilder* fPipelineBuilder; 257 GrStencilSettings fStencilSettings; 258 }; 259 260 261 /// @} 262 263 /////////////////////////////////////////////////////////////////////////// 264 /// @name State Flags 265 //// 266 267 /** 268 * Flags that affect rendering. Controlled using enable/disableState(). All 269 * default to disabled. 270 */ 271 enum Flags { 272 /** 273 * Perform dithering. TODO: Re-evaluate whether we need this bit 274 */ 275 kDither_Flag = 0x01, 276 /** 277 * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target, 278 * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by 279 * the 3D API. 280 */ 281 kHWAntialias_Flag = 0x02, 282 283 /** 284 * Modifies the vertex shader so that vertices will be positioned at pixel centers. 285 */ 286 kSnapVerticesToPixelCenters_Flag = 0x04, 287 288 kLast_Flag = kSnapVerticesToPixelCenters_Flag, 289 }; 290 isDither()291 bool isDither() const { return SkToBool(fFlags & kDither_Flag); } isHWAntialias()292 bool isHWAntialias() const { return SkToBool(fFlags & kHWAntialias_Flag); } snapVerticesToPixelCenters()293 bool snapVerticesToPixelCenters() const { 294 return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag); } 295 296 /** 297 * Enable render state settings. 298 * 299 * @param flags bitfield of Flags specifying the states to enable 300 */ enableState(uint32_t flags)301 void enableState(uint32_t flags) { fFlags |= flags; } 302 303 /** 304 * Disable render state settings. 305 * 306 * @param flags bitfield of Flags specifying the states to disable 307 */ disableState(uint32_t flags)308 void disableState(uint32_t flags) { fFlags &= ~(flags); } 309 310 /** 311 * Enable or disable flags based on a boolean. 312 * 313 * @param flags bitfield of Flags to enable or disable 314 * @param enable if true enable stateBits, otherwise disable 315 */ setState(uint32_t flags,bool enable)316 void setState(uint32_t flags, bool enable) { 317 if (enable) { 318 this->enableState(flags); 319 } else { 320 this->disableState(flags); 321 } 322 } 323 324 /// @} 325 326 /////////////////////////////////////////////////////////////////////////// 327 /// @name Face Culling 328 //// 329 330 enum DrawFace { 331 kInvalid_DrawFace = -1, 332 333 kBoth_DrawFace, 334 kCCW_DrawFace, 335 kCW_DrawFace, 336 }; 337 338 /** 339 * Gets whether the target is drawing clockwise, counterclockwise, 340 * or both faces. 341 * @return the current draw face(s). 342 */ getDrawFace()343 DrawFace getDrawFace() const { return fDrawFace; } 344 345 /** 346 * Controls whether clockwise, counterclockwise, or both faces are drawn. 347 * @param face the face(s) to draw. 348 */ setDrawFace(DrawFace face)349 void setDrawFace(DrawFace face) { 350 SkASSERT(kInvalid_DrawFace != face); 351 fDrawFace = face; 352 } 353 354 /// @} 355 356 /////////////////////////////////////////////////////////////////////////// 357 358 GrPipelineBuilder& operator=(const GrPipelineBuilder& that); 359 360 // TODO delete when we have Batch colorProcInfo(const GrPrimitiveProcessor * pp)361 const GrProcOptInfo& colorProcInfo(const GrPrimitiveProcessor* pp) const { 362 this->calcColorInvariantOutput(pp); 363 return fColorProcInfo; 364 } 365 coverageProcInfo(const GrPrimitiveProcessor * pp)366 const GrProcOptInfo& coverageProcInfo(const GrPrimitiveProcessor* pp) const { 367 this->calcCoverageInvariantOutput(pp); 368 return fCoverageProcInfo; 369 } 370 colorProcInfo(const GrBatch * batch)371 const GrProcOptInfo& colorProcInfo(const GrBatch* batch) const { 372 this->calcColorInvariantOutput(batch); 373 return fColorProcInfo; 374 } 375 coverageProcInfo(const GrBatch * batch)376 const GrProcOptInfo& coverageProcInfo(const GrBatch* batch) const { 377 this->calcCoverageInvariantOutput(batch); 378 return fCoverageProcInfo; 379 } 380 setClip(const GrClip & clip)381 void setClip(const GrClip& clip) { fClip = clip; } clip()382 const GrClip& clip() const { return fClip; } 383 384 private: 385 // Calculating invariant color / coverage information is expensive, so we partially cache the 386 // results. 387 // 388 // canUseFracCoveragePrimProc() - Called in regular skia draw, caches results but only for a 389 // specific color and coverage. May be called multiple times 390 // willBlendWithDst() - only called by Nvpr, does not cache results 391 // GrOptDrawState constructor - never caches results 392 393 /** 394 * Primproc variants of the calc functions 395 * TODO remove these when batch is everywhere 396 */ 397 void calcColorInvariantOutput(const GrPrimitiveProcessor*) const; 398 void calcCoverageInvariantOutput(const GrPrimitiveProcessor*) const; 399 400 /** 401 * GrBatch provides the initial seed for these loops based off of its initial geometry data 402 */ 403 void calcColorInvariantOutput(const GrBatch*) const; 404 void calcCoverageInvariantOutput(const GrBatch*) const; 405 406 /** 407 * If fColorProcInfoValid is false, function calculates the invariant output for the color 408 * processors and results are stored in fColorProcInfo. 409 */ 410 void calcColorInvariantOutput(GrColor) const; 411 412 /** 413 * If fCoverageProcInfoValid is false, function calculates the invariant output for the coverage 414 * processors and results are stored in fCoverageProcInfo. 415 */ 416 void calcCoverageInvariantOutput(GrColor) const; 417 418 // Some of the auto restore objects assume that no effects are removed during their lifetime. 419 // This is used to assert that this condition holds. 420 SkDEBUGCODE(int fBlockEffectRemovalCnt;) 421 422 typedef SkSTArray<4, GrFragmentStage> FragmentStageArray; 423 424 SkAutoTUnref<GrRenderTarget> fRenderTarget; 425 uint32_t fFlags; 426 GrStencilSettings fStencilSettings; 427 DrawFace fDrawFace; 428 mutable SkAutoTUnref<const GrXPFactory> fXPFactory; 429 FragmentStageArray fColorStages; 430 FragmentStageArray fCoverageStages; 431 GrClip fClip; 432 433 mutable GrProcOptInfo fColorProcInfo; 434 mutable GrProcOptInfo fCoverageProcInfo; 435 mutable bool fColorProcInfoValid; 436 mutable bool fCoverageProcInfoValid; 437 mutable GrColor fColorCache; 438 mutable GrColor fCoverageCache; 439 440 friend class GrPipeline; 441 }; 442 443 #endif 444