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