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