1 /* 2 * Copyright 2011 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 GrDrawState_DEFINED 9 #define GrDrawState_DEFINED 10 11 #include "GrBackendEffectFactory.h" 12 #include "GrColor.h" 13 #include "GrEffectStage.h" 14 #include "GrPaint.h" 15 #include "GrPoint.h" 16 #include "GrRefCnt.h" 17 #include "GrRenderTarget.h" 18 #include "GrStencil.h" 19 #include "GrTemplates.h" 20 #include "GrTexture.h" 21 #include "GrTypesPriv.h" 22 #include "effects/GrSimpleTextureEffect.h" 23 24 #include "SkMatrix.h" 25 #include "SkXfermode.h" 26 27 class GrDrawState : public GrRefCnt { 28 public: 29 SK_DECLARE_INST_COUNT(GrDrawState) 30 31 GrDrawState() { 32 GR_DEBUGCODE(fBlockEffectRemovalCnt = 0;) 33 this->reset(); 34 } 35 36 GrDrawState(const SkMatrix& initialViewMatrix) { 37 GR_DEBUGCODE(fBlockEffectRemovalCnt = 0;) 38 this->reset(initialViewMatrix); 39 } 40 41 /** 42 * Copies another draw state. 43 **/ 44 GrDrawState(const GrDrawState& state) : INHERITED() { 45 GR_DEBUGCODE(fBlockEffectRemovalCnt = 0;) 46 *this = state; 47 } 48 49 /** 50 * Copies another draw state with a preconcat to the view matrix. 51 **/ 52 GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix) { 53 GR_DEBUGCODE(fBlockEffectRemovalCnt = 0;) 54 *this = state; 55 if (!preConcatMatrix.isIdentity()) { 56 for (int i = 0; i < fColorStages.count(); ++i) { 57 fColorStages[i].localCoordChange(preConcatMatrix); 58 } 59 for (int i = 0; i < fCoverageStages.count(); ++i) { 60 fCoverageStages[i].localCoordChange(preConcatMatrix); 61 } 62 } 63 } 64 65 virtual ~GrDrawState() { GrAssert(0 == fBlockEffectRemovalCnt); } 66 67 /** 68 * Resets to the default state. GrEffects will be removed from all stages. 69 */ 70 void reset() { this->onReset(NULL); } 71 72 void reset(const SkMatrix& initialViewMatrix) { this->onReset(&initialViewMatrix); } 73 74 /** 75 * Initializes the GrDrawState based on a GrPaint, view matrix and render target. Note that 76 * GrDrawState encompasses more than GrPaint. Aspects of GrDrawState that have no GrPaint 77 * equivalents are set to default values. Clipping will be enabled. 78 */ 79 void setFromPaint(const GrPaint& , const SkMatrix& viewMatrix, GrRenderTarget*); 80 81 /////////////////////////////////////////////////////////////////////////// 82 /// @name Vertex Attributes 83 //// 84 85 enum { 86 kMaxVertexAttribCnt = kLast_GrVertexAttribBinding + 4, 87 }; 88 89 /** 90 * The format of vertices is represented as an array of GrVertexAttribs, with each representing 91 * the type of the attribute, its offset, and semantic binding (see GrVertexAttrib in 92 * GrTypesPriv.h). 93 * 94 * The mapping of attributes with kEffect bindings to GrEffect inputs is specified when 95 * setEffect is called. 96 */ 97 98 /** 99 * Sets vertex attributes for next draw. The object driving the templatization 100 * should be a global GrVertexAttrib array that is never changed. 101 */ 102 template <const GrVertexAttrib A[]> void setVertexAttribs(int count) { 103 this->setVertexAttribs(A, count); 104 } 105 106 const GrVertexAttrib* getVertexAttribs() const { return fCommon.fVAPtr; } 107 int getVertexAttribCount() const { return fCommon.fVACount; } 108 109 size_t getVertexSize() const; 110 111 /** 112 * Sets default vertex attributes for next draw. The default is a single attribute: 113 * {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribType} 114 */ 115 void setDefaultVertexAttribs(); 116 117 /** 118 * Getters for index into getVertexAttribs() for particular bindings. -1 is returned if the 119 * binding does not appear in the current attribs. These bindings should appear only once in 120 * the attrib array. 121 */ 122 123 int positionAttributeIndex() const { 124 return fCommon.fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding]; 125 } 126 int localCoordAttributeIndex() const { 127 return fCommon.fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding]; 128 } 129 int colorVertexAttributeIndex() const { 130 return fCommon.fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding]; 131 } 132 int coverageVertexAttributeIndex() const { 133 return fCommon.fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding]; 134 } 135 136 bool hasLocalCoordAttribute() const { 137 return -1 != fCommon.fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding]; 138 } 139 bool hasColorVertexAttribute() const { 140 return -1 != fCommon.fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding]; 141 } 142 bool hasCoverageVertexAttribute() const { 143 return -1 != fCommon.fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding]; 144 } 145 146 bool validateVertexAttribs() const; 147 148 /** 149 * Helper to save/restore vertex attribs 150 */ 151 class AutoVertexAttribRestore { 152 public: 153 AutoVertexAttribRestore(GrDrawState* drawState) { 154 GrAssert(NULL != drawState); 155 fDrawState = drawState; 156 fVAPtr = drawState->fCommon.fVAPtr; 157 fVACount = drawState->fCommon.fVACount; 158 fDrawState->setDefaultVertexAttribs(); 159 } 160 161 ~AutoVertexAttribRestore(){ 162 fDrawState->fCommon.fVAPtr = fVAPtr; 163 fDrawState->fCommon.fVACount = fVACount; 164 } 165 166 private: 167 GrDrawState* fDrawState; 168 const GrVertexAttrib* fVAPtr; 169 int fVACount; 170 }; 171 172 /** 173 * Accessing positions, local coords, or colors, of a vertex within an array is a hassle 174 * involving casts and simple math. These helpers exist to keep GrDrawTarget clients' code a bit 175 * nicer looking. 176 */ 177 178 /** 179 * Gets a pointer to a GrPoint of a vertex's position or texture 180 * coordinate. 181 * @param vertices the vertex array 182 * @param vertexIndex the index of the vertex in the array 183 * @param vertexSize the size of each vertex in the array 184 * @param offset the offset in bytes of the vertex component. 185 * Defaults to zero (corresponding to vertex position) 186 * @return pointer to the vertex component as a GrPoint 187 */ 188 static GrPoint* GetVertexPoint(void* vertices, 189 int vertexIndex, 190 int vertexSize, 191 int offset = 0) { 192 intptr_t start = GrTCast<intptr_t>(vertices); 193 return GrTCast<GrPoint*>(start + offset + 194 vertexIndex * vertexSize); 195 } 196 static const GrPoint* GetVertexPoint(const void* vertices, 197 int vertexIndex, 198 int vertexSize, 199 int offset = 0) { 200 intptr_t start = GrTCast<intptr_t>(vertices); 201 return GrTCast<const GrPoint*>(start + offset + 202 vertexIndex * vertexSize); 203 } 204 205 /** 206 * Gets a pointer to a GrColor inside a vertex within a vertex array. 207 * @param vertices the vetex array 208 * @param vertexIndex the index of the vertex in the array 209 * @param vertexSize the size of each vertex in the array 210 * @param offset the offset in bytes of the vertex color 211 * @return pointer to the vertex component as a GrColor 212 */ 213 static GrColor* GetVertexColor(void* vertices, 214 int vertexIndex, 215 int vertexSize, 216 int offset) { 217 intptr_t start = GrTCast<intptr_t>(vertices); 218 return GrTCast<GrColor*>(start + offset + 219 vertexIndex * vertexSize); 220 } 221 static const GrColor* GetVertexColor(const void* vertices, 222 int vertexIndex, 223 int vertexSize, 224 int offset) { 225 const intptr_t start = GrTCast<intptr_t>(vertices); 226 return GrTCast<const GrColor*>(start + offset + 227 vertexIndex * vertexSize); 228 } 229 230 /// @} 231 232 /** 233 * Determines whether src alpha is guaranteed to be one for all src pixels 234 */ 235 bool srcAlphaWillBeOne() const; 236 237 /** 238 * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw. 239 */ 240 bool hasSolidCoverage() const; 241 242 /// @} 243 244 /////////////////////////////////////////////////////////////////////////// 245 /// @name Color 246 //// 247 248 /** 249 * Sets color for next draw to a premultiplied-alpha color. 250 * 251 * @param color the color to set. 252 */ 253 void setColor(GrColor color) { fCommon.fColor = color; } 254 255 GrColor getColor() const { return fCommon.fColor; } 256 257 /** 258 * Sets the color to be used for the next draw to be 259 * (r,g,b,a) = (alpha, alpha, alpha, alpha). 260 * 261 * @param alpha The alpha value to set as the color. 262 */ 263 void setAlpha(uint8_t a) { 264 this->setColor((a << 24) | (a << 16) | (a << 8) | a); 265 } 266 267 /** 268 * Add a color filter that can be represented by a color and a mode. Applied 269 * after color-computing effect stages. 270 */ 271 void setColorFilter(GrColor c, SkXfermode::Mode mode) { 272 fCommon.fColorFilterColor = c; 273 fCommon.fColorFilterMode = mode; 274 } 275 276 GrColor getColorFilterColor() const { return fCommon.fColorFilterColor; } 277 SkXfermode::Mode getColorFilterMode() const { return fCommon.fColorFilterMode; } 278 279 /** 280 * Constructor sets the color to be 'color' which is undone by the destructor. 281 */ 282 class AutoColorRestore : public ::GrNoncopyable { 283 public: 284 AutoColorRestore() : fDrawState(NULL), fOldColor(0) {} 285 286 AutoColorRestore(GrDrawState* drawState, GrColor color) { 287 fDrawState = NULL; 288 this->set(drawState, color); 289 } 290 291 void reset() { 292 if (NULL != fDrawState) { 293 fDrawState->setColor(fOldColor); 294 fDrawState = NULL; 295 } 296 } 297 298 void set(GrDrawState* drawState, GrColor color) { 299 this->reset(); 300 fDrawState = drawState; 301 fOldColor = fDrawState->getColor(); 302 fDrawState->setColor(color); 303 } 304 305 ~AutoColorRestore() { this->reset(); } 306 private: 307 GrDrawState* fDrawState; 308 GrColor fOldColor; 309 }; 310 311 /// @} 312 313 /////////////////////////////////////////////////////////////////////////// 314 /// @name Coverage 315 //// 316 317 /** 318 * Sets a constant fractional coverage to be applied to the draw. The 319 * initial value (after construction or reset()) is 0xff. The constant 320 * coverage is ignored when per-vertex coverage is provided. 321 */ 322 void setCoverage(uint8_t coverage) { 323 fCommon.fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage); 324 } 325 326 /** 327 * Version of above that specifies 4 channel per-vertex color. The value 328 * should be premultiplied. 329 */ 330 void setCoverage4(GrColor coverage) { 331 fCommon.fCoverage = coverage; 332 } 333 334 GrColor getCoverage() const { 335 return fCommon.fCoverage; 336 } 337 338 /// @} 339 340 /////////////////////////////////////////////////////////////////////////// 341 /// @name Effect Stages 342 /// Each stage hosts a GrEffect. The effect produces an output color or coverage in the fragment 343 /// shader. Its inputs are the output from the previous stage as well as some variables 344 /// available to it in the fragment and vertex shader (e.g. the vertex position, the dst color, 345 /// the fragment position, local coordinates). 346 /// 347 /// The stages are divided into two sets, color-computing and coverage-computing. The final 348 /// color stage produces the final pixel color. The coverage-computing stages function exactly 349 /// as the color-computing but the output of the final coverage stage is treated as a fractional 350 /// pixel coverage rather than as input to the src/dst color blend step. 351 /// 352 /// The input color to the first color-stage is either the constant color or interpolated 353 /// per-vertex colors. The input to the first coverage stage is either a constant coverage 354 /// (usually full-coverage) or interpolated per-vertex coverage. 355 /// 356 /// See the documentation of kCoverageDrawing_StateBit for information about disabling the 357 /// the color / coverage distinction. 358 //// 359 360 const GrEffectRef* addColorEffect(const GrEffectRef* effect, int attr0 = -1, int attr1 = -1) { 361 GrAssert(NULL != effect); 362 SkNEW_APPEND_TO_TARRAY(&fColorStages, GrEffectStage, (effect, attr0, attr1)); 363 return effect; 364 } 365 366 const GrEffectRef* addCoverageEffect(const GrEffectRef* effect, int attr0 = -1, int attr1 = -1) { 367 GrAssert(NULL != effect); 368 SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrEffectStage, (effect, attr0, attr1)); 369 return effect; 370 } 371 372 /** 373 * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates. 374 */ 375 void addColorTextureEffect(GrTexture* texture, const SkMatrix& matrix) { 376 GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix); 377 this->addColorEffect(effect)->unref(); 378 } 379 380 void addCoverageTextureEffect(GrTexture* texture, const SkMatrix& matrix) { 381 GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix); 382 this->addCoverageEffect(effect)->unref(); 383 } 384 385 void addColorTextureEffect(GrTexture* texture, 386 const SkMatrix& matrix, 387 const GrTextureParams& params) { 388 GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params); 389 this->addColorEffect(effect)->unref(); 390 } 391 392 void addCoverageTextureEffect(GrTexture* texture, 393 const SkMatrix& matrix, 394 const GrTextureParams& params) { 395 GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params); 396 this->addCoverageEffect(effect)->unref(); 397 } 398 399 /** 400 * When this object is destroyed it will remove any effects from the draw state that were added 401 * after its constructor. 402 */ 403 class AutoRestoreEffects : public ::GrNoncopyable { 404 public: 405 AutoRestoreEffects() : fDrawState(NULL), fColorEffectCnt(0), fCoverageEffectCnt(0) {} 406 407 AutoRestoreEffects(GrDrawState* ds) : fDrawState(NULL), fColorEffectCnt(0), fCoverageEffectCnt(0) { 408 this->set(ds); 409 } 410 411 ~AutoRestoreEffects() { this->set(NULL); } 412 413 void set(GrDrawState* ds) { 414 if (NULL != fDrawState) { 415 int n = fDrawState->fColorStages.count() - fColorEffectCnt; 416 GrAssert(n >= 0); 417 fDrawState->fColorStages.pop_back_n(n); 418 n = fDrawState->fCoverageStages.count() - fCoverageEffectCnt; 419 GrAssert(n >= 0); 420 fDrawState->fCoverageStages.pop_back_n(n); 421 GR_DEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) 422 } 423 fDrawState = ds; 424 if (NULL != ds) { 425 fColorEffectCnt = ds->fColorStages.count(); 426 fCoverageEffectCnt = ds->fCoverageStages.count(); 427 GR_DEBUGCODE(++ds->fBlockEffectRemovalCnt;) 428 } 429 } 430 431 private: 432 GrDrawState* fDrawState; 433 int fColorEffectCnt; 434 int fCoverageEffectCnt; 435 }; 436 437 int numColorStages() const { return fColorStages.count(); } 438 int numCoverageStages() const { return fCoverageStages.count(); } 439 int numTotalStages() const { return this->numColorStages() + this->numCoverageStages(); } 440 441 const GrEffectStage& getColorStage(int stageIdx) const { return fColorStages[stageIdx]; } 442 const GrEffectStage& getCoverageStage(int stageIdx) const { return fCoverageStages[stageIdx]; } 443 444 /** 445 * Checks whether any of the effects will read the dst pixel color. 446 */ 447 bool willEffectReadDstColor() const; 448 449 /// @} 450 451 /////////////////////////////////////////////////////////////////////////// 452 /// @name Blending 453 //// 454 455 /** 456 * Sets the blending function coefficients. 457 * 458 * The blend function will be: 459 * D' = sat(S*srcCoef + D*dstCoef) 460 * 461 * where D is the existing destination color, S is the incoming source 462 * color, and D' is the new destination color that will be written. sat() 463 * is the saturation function. 464 * 465 * @param srcCoef coefficient applied to the src color. 466 * @param dstCoef coefficient applied to the dst color. 467 */ 468 void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) { 469 fCommon.fSrcBlend = srcCoeff; 470 fCommon.fDstBlend = dstCoeff; 471 #if GR_DEBUG 472 switch (dstCoeff) { 473 case kDC_GrBlendCoeff: 474 case kIDC_GrBlendCoeff: 475 case kDA_GrBlendCoeff: 476 case kIDA_GrBlendCoeff: 477 GrPrintf("Unexpected dst blend coeff. Won't work correctly with" 478 "coverage stages.\n"); 479 break; 480 default: 481 break; 482 } 483 switch (srcCoeff) { 484 case kSC_GrBlendCoeff: 485 case kISC_GrBlendCoeff: 486 case kSA_GrBlendCoeff: 487 case kISA_GrBlendCoeff: 488 GrPrintf("Unexpected src blend coeff. Won't work correctly with" 489 "coverage stages.\n"); 490 break; 491 default: 492 break; 493 } 494 #endif 495 } 496 497 GrBlendCoeff getSrcBlendCoeff() const { return fCommon.fSrcBlend; } 498 GrBlendCoeff getDstBlendCoeff() const { return fCommon.fDstBlend; } 499 500 void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff, 501 GrBlendCoeff* dstBlendCoeff) const { 502 *srcBlendCoeff = fCommon.fSrcBlend; 503 *dstBlendCoeff = fCommon.fDstBlend; 504 } 505 506 /** 507 * Sets the blending function constant referenced by the following blending 508 * coefficients: 509 * kConstC_GrBlendCoeff 510 * kIConstC_GrBlendCoeff 511 * kConstA_GrBlendCoeff 512 * kIConstA_GrBlendCoeff 513 * 514 * @param constant the constant to set 515 */ 516 void setBlendConstant(GrColor constant) { fCommon.fBlendConstant = constant; } 517 518 /** 519 * Retrieves the last value set by setBlendConstant() 520 * @return the blending constant value 521 */ 522 GrColor getBlendConstant() const { return fCommon.fBlendConstant; } 523 524 /** 525 * Determines whether multiplying the computed per-pixel color by the pixel's fractional 526 * coverage before the blend will give the correct final destination color. In general it 527 * will not as coverage is applied after blending. 528 */ 529 bool canTweakAlphaForCoverage() const; 530 531 /** 532 * Optimizations for blending / coverage to that can be applied based on the current state. 533 */ 534 enum BlendOptFlags { 535 /** 536 * No optimization 537 */ 538 kNone_BlendOpt = 0, 539 /** 540 * Don't draw at all 541 */ 542 kSkipDraw_BlendOptFlag = 0x1, 543 /** 544 * Emit the src color, disable HW blending (replace dst with src) 545 */ 546 kDisableBlend_BlendOptFlag = 0x2, 547 /** 548 * The coverage value does not have to be computed separately from alpha, the the output 549 * color can be the modulation of the two. 550 */ 551 kCoverageAsAlpha_BlendOptFlag = 0x4, 552 /** 553 * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are 554 * "don't cares". 555 */ 556 kEmitCoverage_BlendOptFlag = 0x8, 557 /** 558 * Emit transparent black instead of the src color, no need to compute coverage. 559 */ 560 kEmitTransBlack_BlendOptFlag = 0x10, 561 }; 562 GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags); 563 564 /** 565 * Determines what optimizations can be applied based on the blend. The coefficients may have 566 * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional 567 * params that receive the tweaked coefficients. Normally the function looks at the current 568 * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively 569 * determine the blend optimizations that would be used if there was partial pixel coverage. 570 * 571 * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for 572 * playback) must call this function and respect the flags that replace the output color. 573 */ 574 BlendOptFlags getBlendOpts(bool forceCoverage = false, 575 GrBlendCoeff* srcCoeff = NULL, 576 GrBlendCoeff* dstCoeff = NULL) const; 577 578 /// @} 579 580 /////////////////////////////////////////////////////////////////////////// 581 /// @name View Matrix 582 //// 583 584 /** 585 * Sets the view matrix to identity and updates any installed effects to compensate for the 586 * coord system change. 587 */ 588 bool setIdentityViewMatrix(); 589 590 /** 591 * Retrieves the current view matrix 592 * @return the current view matrix. 593 */ 594 const SkMatrix& getViewMatrix() const { return fCommon.fViewMatrix; } 595 596 /** 597 * Retrieves the inverse of the current view matrix. 598 * 599 * If the current view matrix is invertible, return true, and if matrix 600 * is non-null, copy the inverse into it. If the current view matrix is 601 * non-invertible, return false and ignore the matrix parameter. 602 * 603 * @param matrix if not null, will receive a copy of the current inverse. 604 */ 605 bool getViewInverse(SkMatrix* matrix) const { 606 // TODO: determine whether we really need to leave matrix unmodified 607 // at call sites when inversion fails. 608 SkMatrix inverse; 609 if (fCommon.fViewMatrix.invert(&inverse)) { 610 if (matrix) { 611 *matrix = inverse; 612 } 613 return true; 614 } 615 return false; 616 } 617 618 //////////////////////////////////////////////////////////////////////////// 619 620 /** 621 * Preconcats the current view matrix and restores the previous view matrix in the destructor. 622 * Effect matrices are automatically adjusted to compensate and adjusted back in the destructor. 623 */ 624 class AutoViewMatrixRestore : public ::GrNoncopyable { 625 public: 626 AutoViewMatrixRestore() : fDrawState(NULL) {} 627 628 AutoViewMatrixRestore(GrDrawState* ds, const SkMatrix& preconcatMatrix) { 629 fDrawState = NULL; 630 this->set(ds, preconcatMatrix); 631 } 632 633 ~AutoViewMatrixRestore() { this->restore(); } 634 635 /** 636 * Can be called prior to destructor to restore the original matrix. 637 */ 638 void restore(); 639 640 void set(GrDrawState* drawState, const SkMatrix& preconcatMatrix); 641 642 /** Sets the draw state's matrix to identity. This can fail because the current view matrix 643 is not invertible. */ 644 bool setIdentity(GrDrawState* drawState); 645 646 private: 647 void doEffectCoordChanges(const SkMatrix& coordChangeMatrix); 648 649 GrDrawState* fDrawState; 650 SkMatrix fViewMatrix; 651 int fNumColorStages; 652 SkAutoSTArray<8, GrEffectStage::SavedCoordChange> fSavedCoordChanges; 653 }; 654 655 /// @} 656 657 /////////////////////////////////////////////////////////////////////////// 658 /// @name Render Target 659 //// 660 661 /** 662 * Sets the render-target used at the next drawing call 663 * 664 * @param target The render target to set. 665 */ 666 void setRenderTarget(GrRenderTarget* target) { 667 fRenderTarget.reset(SkSafeRef(target)); 668 } 669 670 /** 671 * Retrieves the currently set render-target. 672 * 673 * @return The currently set render target. 674 */ 675 const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); } 676 GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); } 677 678 class AutoRenderTargetRestore : public ::GrNoncopyable { 679 public: 680 AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {} 681 AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) { 682 fDrawState = NULL; 683 fSavedTarget = NULL; 684 this->set(ds, newTarget); 685 } 686 ~AutoRenderTargetRestore() { this->restore(); } 687 688 void restore() { 689 if (NULL != fDrawState) { 690 fDrawState->setRenderTarget(fSavedTarget); 691 fDrawState = NULL; 692 } 693 GrSafeSetNull(fSavedTarget); 694 } 695 696 void set(GrDrawState* ds, GrRenderTarget* newTarget) { 697 this->restore(); 698 699 if (NULL != ds) { 700 GrAssert(NULL == fSavedTarget); 701 fSavedTarget = ds->getRenderTarget(); 702 SkSafeRef(fSavedTarget); 703 ds->setRenderTarget(newTarget); 704 fDrawState = ds; 705 } 706 } 707 private: 708 GrDrawState* fDrawState; 709 GrRenderTarget* fSavedTarget; 710 }; 711 712 /// @} 713 714 /////////////////////////////////////////////////////////////////////////// 715 /// @name Stencil 716 //// 717 718 /** 719 * Sets the stencil settings to use for the next draw. 720 * Changing the clip has the side-effect of possibly zeroing 721 * out the client settable stencil bits. So multipass algorithms 722 * using stencil should not change the clip between passes. 723 * @param settings the stencil settings to use. 724 */ 725 void setStencil(const GrStencilSettings& settings) { 726 fCommon.fStencilSettings = settings; 727 } 728 729 /** 730 * Shortcut to disable stencil testing and ops. 731 */ 732 void disableStencil() { 733 fCommon.fStencilSettings.setDisabled(); 734 } 735 736 const GrStencilSettings& getStencil() const { return fCommon.fStencilSettings; } 737 738 GrStencilSettings* stencil() { return &fCommon.fStencilSettings; } 739 740 /// @} 741 742 /////////////////////////////////////////////////////////////////////////// 743 /// @name State Flags 744 //// 745 746 /** 747 * Flags that affect rendering. Controlled using enable/disableState(). All 748 * default to disabled. 749 */ 750 enum StateBits { 751 /** 752 * Perform dithering. TODO: Re-evaluate whether we need this bit 753 */ 754 kDither_StateBit = 0x01, 755 /** 756 * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target, 757 * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by 758 * the 3D API. 759 */ 760 kHWAntialias_StateBit = 0x02, 761 /** 762 * Draws will respect the clip, otherwise the clip is ignored. 763 */ 764 kClip_StateBit = 0x04, 765 /** 766 * Disables writing to the color buffer. Useful when performing stencil 767 * operations. 768 */ 769 kNoColorWrites_StateBit = 0x08, 770 771 /** 772 * Usually coverage is applied after color blending. The color is blended using the coeffs 773 * specified by setBlendFunc(). The blended color is then combined with dst using coeffs 774 * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In 775 * this case there is no distinction between coverage and color and the caller needs direct 776 * control over the blend coeffs. When set, there will be a single blend step controlled by 777 * setBlendFunc() which will use coverage*color as the src color. 778 */ 779 kCoverageDrawing_StateBit = 0x10, 780 781 // Users of the class may add additional bits to the vector 782 kDummyStateBit, 783 kLastPublicStateBit = kDummyStateBit-1, 784 }; 785 786 void resetStateFlags() { 787 fCommon.fFlagBits = 0; 788 } 789 790 /** 791 * Enable render state settings. 792 * 793 * @param stateBits bitfield of StateBits specifying the states to enable 794 */ 795 void enableState(uint32_t stateBits) { 796 fCommon.fFlagBits |= stateBits; 797 } 798 799 /** 800 * Disable render state settings. 801 * 802 * @param stateBits bitfield of StateBits specifying the states to disable 803 */ 804 void disableState(uint32_t stateBits) { 805 fCommon.fFlagBits &= ~(stateBits); 806 } 807 808 /** 809 * Enable or disable stateBits based on a boolean. 810 * 811 * @param stateBits bitfield of StateBits to enable or disable 812 * @param enable if true enable stateBits, otherwise disable 813 */ 814 void setState(uint32_t stateBits, bool enable) { 815 if (enable) { 816 this->enableState(stateBits); 817 } else { 818 this->disableState(stateBits); 819 } 820 } 821 822 bool isDitherState() const { 823 return 0 != (fCommon.fFlagBits & kDither_StateBit); 824 } 825 826 bool isHWAntialiasState() const { 827 return 0 != (fCommon.fFlagBits & kHWAntialias_StateBit); 828 } 829 830 bool isClipState() const { 831 return 0 != (fCommon.fFlagBits & kClip_StateBit); 832 } 833 834 bool isColorWriteDisabled() const { 835 return 0 != (fCommon.fFlagBits & kNoColorWrites_StateBit); 836 } 837 838 bool isCoverageDrawing() const { 839 return 0 != (fCommon.fFlagBits & kCoverageDrawing_StateBit); 840 } 841 842 bool isStateFlagEnabled(uint32_t stateBit) const { 843 return 0 != (stateBit & fCommon.fFlagBits); 844 } 845 846 /// @} 847 848 /////////////////////////////////////////////////////////////////////////// 849 /// @name Face Culling 850 //// 851 852 enum DrawFace { 853 kInvalid_DrawFace = -1, 854 855 kBoth_DrawFace, 856 kCCW_DrawFace, 857 kCW_DrawFace, 858 }; 859 860 /** 861 * Controls whether clockwise, counterclockwise, or both faces are drawn. 862 * @param face the face(s) to draw. 863 */ 864 void setDrawFace(DrawFace face) { 865 GrAssert(kInvalid_DrawFace != face); 866 fCommon.fDrawFace = face; 867 } 868 869 /** 870 * Gets whether the target is drawing clockwise, counterclockwise, 871 * or both faces. 872 * @return the current draw face(s). 873 */ 874 DrawFace getDrawFace() const { return fCommon.fDrawFace; } 875 876 /// @} 877 878 /////////////////////////////////////////////////////////////////////////// 879 880 bool operator ==(const GrDrawState& s) const { 881 if (fRenderTarget.get() != s.fRenderTarget.get() || 882 fColorStages.count() != s.fColorStages.count() || 883 fCoverageStages.count() != s.fCoverageStages.count() || 884 fCommon != s.fCommon) { 885 return false; 886 } 887 for (int i = 0; i < fColorStages.count(); i++) { 888 if (fColorStages[i] != s.fColorStages[i]) { 889 return false; 890 } 891 } 892 for (int i = 0; i < fCoverageStages.count(); i++) { 893 if (fCoverageStages[i] != s.fCoverageStages[i]) { 894 return false; 895 } 896 } 897 return true; 898 } 899 bool operator !=(const GrDrawState& s) const { return !(*this == s); } 900 901 GrDrawState& operator= (const GrDrawState& s) { 902 GrAssert(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); 903 this->setRenderTarget(s.fRenderTarget.get()); 904 fCommon = s.fCommon; 905 fColorStages = s.fColorStages; 906 fCoverageStages = s.fCoverageStages; 907 return *this; 908 } 909 910 private: 911 912 void onReset(const SkMatrix* initialViewMatrix) { 913 GrAssert(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); 914 fColorStages.reset(); 915 fCoverageStages.reset(); 916 917 fRenderTarget.reset(NULL); 918 919 this->setDefaultVertexAttribs(); 920 921 fCommon.fColor = 0xffffffff; 922 if (NULL == initialViewMatrix) { 923 fCommon.fViewMatrix.reset(); 924 } else { 925 fCommon.fViewMatrix = *initialViewMatrix; 926 } 927 fCommon.fSrcBlend = kOne_GrBlendCoeff; 928 fCommon.fDstBlend = kZero_GrBlendCoeff; 929 fCommon.fBlendConstant = 0x0; 930 fCommon.fFlagBits = 0x0; 931 fCommon.fStencilSettings.setDisabled(); 932 fCommon.fCoverage = 0xffffffff; 933 fCommon.fColorFilterMode = SkXfermode::kDst_Mode; 934 fCommon.fColorFilterColor = 0x0; 935 fCommon.fDrawFace = kBoth_DrawFace; 936 } 937 938 /** Fields that are identical in GrDrawState and GrDrawState::DeferredState. */ 939 struct CommonState { 940 // These fields are roughly sorted by decreasing likelihood of being different in op== 941 GrColor fColor; 942 SkMatrix fViewMatrix; 943 GrBlendCoeff fSrcBlend; 944 GrBlendCoeff fDstBlend; 945 GrColor fBlendConstant; 946 uint32_t fFlagBits; 947 const GrVertexAttrib* fVAPtr; 948 int fVACount; 949 GrStencilSettings fStencilSettings; 950 GrColor fCoverage; 951 SkXfermode::Mode fColorFilterMode; 952 GrColor fColorFilterColor; 953 DrawFace fDrawFace; 954 955 // This is simply a different representation of info in fVertexAttribs and thus does 956 // not need to be compared in op==. 957 int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt]; 958 959 bool operator== (const CommonState& other) const { 960 bool result = fColor == other.fColor && 961 fViewMatrix.cheapEqualTo(other.fViewMatrix) && 962 fSrcBlend == other.fSrcBlend && 963 fDstBlend == other.fDstBlend && 964 fBlendConstant == other.fBlendConstant && 965 fFlagBits == other.fFlagBits && 966 fVACount == other.fVACount && 967 !memcmp(fVAPtr, other.fVAPtr, fVACount * sizeof(GrVertexAttrib)) && 968 fStencilSettings == other.fStencilSettings && 969 fCoverage == other.fCoverage && 970 fColorFilterMode == other.fColorFilterMode && 971 fColorFilterColor == other.fColorFilterColor && 972 fDrawFace == other.fDrawFace; 973 GrAssert(!result || 0 == memcmp(fFixedFunctionVertexAttribIndices, 974 other.fFixedFunctionVertexAttribIndices, 975 sizeof(fFixedFunctionVertexAttribIndices))); 976 return result; 977 } 978 bool operator!= (const CommonState& other) const { return !(*this == other); } 979 }; 980 981 /** GrDrawState uses GrEffectStages to hold stage state which holds a ref on GrEffectRef. 982 DeferredState must directly reference GrEffects, however. */ 983 struct SavedEffectStage { 984 SavedEffectStage() : fEffect(NULL) {} 985 const GrEffect* fEffect; 986 GrEffectStage::SavedCoordChange fCoordChange; 987 }; 988 989 public: 990 /** 991 * DeferredState contains all of the data of a GrDrawState but does not hold refs on GrResource 992 * objects. Resources are allowed to hit zero ref count while in DeferredStates. Their internal 993 * dispose mechanism returns them to the cache. This allows recycling resources through the 994 * the cache while they are in a deferred draw queue. 995 */ 996 class DeferredState { 997 public: 998 DeferredState() : fRenderTarget(NULL) { 999 GR_DEBUGCODE(fInitialized = false;) 1000 } 1001 // TODO: Remove this when DeferredState no longer holds a ref to the RT 1002 ~DeferredState() { SkSafeUnref(fRenderTarget); } 1003 1004 void saveFrom(const GrDrawState& drawState) { 1005 fCommon = drawState.fCommon; 1006 // TODO: Here we will copy the GrRenderTarget pointer without taking a ref. 1007 fRenderTarget = drawState.fRenderTarget.get(); 1008 SkSafeRef(fRenderTarget); 1009 // Here we ref the effects directly rather than the effect-refs. TODO: When the effect- 1010 // ref gets fully unref'ed it will cause the underlying effect to unref its resources 1011 // and recycle them to the cache (if no one else is holding a ref to the resources). 1012 fStages.reset(drawState.fColorStages.count() + drawState.fCoverageStages.count()); 1013 fColorStageCnt = drawState.fColorStages.count(); 1014 for (int i = 0; i < fColorStageCnt; ++i) { 1015 fStages[i].saveFrom(drawState.fColorStages[i]); 1016 } 1017 for (int i = 0; i < drawState.fCoverageStages.count(); ++i) { 1018 fStages[i + fColorStageCnt].saveFrom(drawState.fCoverageStages[i]); 1019 } 1020 GR_DEBUGCODE(fInitialized = true;) 1021 } 1022 1023 void restoreTo(GrDrawState* drawState) { 1024 GrAssert(fInitialized); 1025 drawState->fCommon = fCommon; 1026 drawState->setRenderTarget(fRenderTarget); 1027 // reinflate color/cov stage arrays. 1028 drawState->fColorStages.reset(); 1029 for (int i = 0; i < fColorStageCnt; ++i) { 1030 SkNEW_APPEND_TO_TARRAY(&drawState->fColorStages, GrEffectStage, (fStages[i])); 1031 } 1032 int coverageStageCnt = fStages.count() - fColorStageCnt; 1033 drawState->fCoverageStages.reset(); 1034 for (int i = 0; i < coverageStageCnt; ++i) { 1035 SkNEW_APPEND_TO_TARRAY(&drawState->fCoverageStages, 1036 GrEffectStage, (fStages[i + fColorStageCnt])); 1037 } 1038 } 1039 1040 bool isEqual(const GrDrawState& state) const { 1041 int numCoverageStages = fStages.count() - fColorStageCnt; 1042 if (fRenderTarget != state.fRenderTarget.get() || 1043 fColorStageCnt != state.fColorStages.count() || 1044 numCoverageStages != state.fCoverageStages.count() || 1045 fCommon != state.fCommon) { 1046 return false; 1047 } 1048 bool explicitLocalCoords = state.hasLocalCoordAttribute(); 1049 for (int i = 0; i < fColorStageCnt; ++i) { 1050 if (!fStages[i].isEqual(state.fColorStages[i], explicitLocalCoords)) { 1051 return false; 1052 } 1053 } 1054 for (int i = 0; i < numCoverageStages; ++i) { 1055 int s = fColorStageCnt + i; 1056 if (!fStages[s].isEqual(state.fCoverageStages[i], explicitLocalCoords)) { 1057 return false; 1058 } 1059 } 1060 return true; 1061 } 1062 1063 private: 1064 typedef SkAutoSTArray<8, GrEffectStage::DeferredStage> DeferredStageArray; 1065 1066 GrRenderTarget* fRenderTarget; 1067 CommonState fCommon; 1068 int fColorStageCnt; 1069 DeferredStageArray fStages; 1070 1071 GR_DEBUGCODE(bool fInitialized;) 1072 }; 1073 1074 private: 1075 1076 SkAutoTUnref<GrRenderTarget> fRenderTarget; 1077 CommonState fCommon; 1078 1079 typedef SkSTArray<4, GrEffectStage> EffectStageArray; 1080 EffectStageArray fColorStages; 1081 EffectStageArray fCoverageStages; 1082 1083 // Some of the auto restore objects assume that no effects are removed during their lifetime. 1084 // This is used to assert that this condition holds. 1085 GR_DEBUGCODE(int fBlockEffectRemovalCnt;) 1086 1087 /** 1088 * Sets vertex attributes for next draw. 1089 * 1090 * @param attribs the array of vertex attributes to set. 1091 * @param count the number of attributes being set, limited to kMaxVertexAttribCnt. 1092 */ 1093 void setVertexAttribs(const GrVertexAttrib attribs[], int count); 1094 1095 typedef GrRefCnt INHERITED; 1096 }; 1097 1098 GR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags); 1099 1100 #endif 1101