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 "GrColor.h" 12 #include "GrMatrix.h" 13 #include "GrNoncopyable.h" 14 #include "GrSamplerState.h" 15 #include "GrStencil.h" 16 17 #include "SkXfermode.h" 18 19 class GrRenderTarget; 20 class GrTexture; 21 22 struct GrDrawState { 23 24 /** 25 * Number of texture stages. Each stage takes as input a color and 26 * 2D texture coordinates. The color input to the first enabled stage is the 27 * per-vertex color or the constant color (setColor/setAlpha) if there are 28 * no per-vertex colors. For subsequent stages the input color is the output 29 * color from the previous enabled stage. The output color of each stage is 30 * the input color modulated with the result of a texture lookup. Texture 31 * lookups are specified by a texture a sampler (setSamplerState). Texture 32 * coordinates for each stage come from the vertices based on a 33 * GrVertexLayout bitfield. The output fragment color is the output color of 34 * the last enabled stage. The presence or absence of texture coordinates 35 * for each stage in the vertex layout indicates whether a stage is enabled 36 * or not. 37 */ 38 enum { 39 kNumStages = 3, 40 kMaxTexCoords = kNumStages 41 }; 42 43 /** 44 * Bitfield used to indicate a set of stages. 45 */ 46 typedef uint32_t StageMask; 47 GR_STATIC_ASSERT(sizeof(StageMask)*8 >= GrDrawState::kNumStages); 48 GrDrawStateGrDrawState49 GrDrawState() { 50 this->reset(); 51 } 52 GrDrawStateGrDrawState53 GrDrawState(const GrDrawState& state) { 54 *this = state; 55 } 56 57 /** 58 * Resets to the default state. Sampler states will not be modified. 59 */ resetGrDrawState60 void reset() { 61 // make sure any pad is zero for memcmp 62 // all GrDrawState members should default to something valid by the 63 // the memset except those initialized individually below. There should 64 // be no padding between the individually initialized members. 65 static const size_t kMemsetSize = 66 reinterpret_cast<intptr_t>(&fColor) - 67 reinterpret_cast<intptr_t>(this); 68 memset(this, 0, kMemsetSize); 69 // pedantic assertion that our ptrs will 70 // be NULL (0 ptr is mem addr 0) 71 GrAssert((intptr_t)(void*)NULL == 0LL); 72 GR_STATIC_ASSERT(0 == kBoth_DrawFace); 73 GrAssert(fStencilSettings.isDisabled()); 74 75 // memset exceptions 76 fColor = 0xffffffff; 77 fCoverage = 0xffffffff; 78 fFirstCoverageStage = kNumStages; 79 fColorFilterMode = SkXfermode::kDst_Mode; 80 fSrcBlend = kOne_BlendCoeff; 81 fDstBlend = kZero_BlendCoeff; 82 fViewMatrix.reset(); 83 84 // ensure values that will be memcmp'ed in == but not memset in reset() 85 // are tightly packed 86 GrAssert(kMemsetSize + sizeof(fColor) + sizeof(fCoverage) + 87 sizeof(fFirstCoverageStage) + sizeof(fColorFilterMode) + 88 sizeof(fSrcBlend) + sizeof(fDstBlend) + sizeof(GrMatrix) == 89 reinterpret_cast<intptr_t>(&fEdgeAANumEdges) - 90 reinterpret_cast<intptr_t>(this)); 91 92 fEdgeAANumEdges = 0; 93 } 94 95 /////////////////////////////////////////////////////////////////////////// 96 /// @name Color 97 //// 98 99 /** 100 * Sets color for next draw to a premultiplied-alpha color. 101 * 102 * @param color the color to set. 103 */ setColorGrDrawState104 void setColor(GrColor color) { fColor = color; } 105 getColorGrDrawState106 GrColor getColor() const { return fColor; } 107 108 /** 109 * Sets the color to be used for the next draw to be 110 * (r,g,b,a) = (alpha, alpha, alpha, alpha). 111 * 112 * @param alpha The alpha value to set as the color. 113 */ setAlphaGrDrawState114 void setAlpha(uint8_t a) { 115 this->setColor((a << 24) | (a << 16) | (a << 8) | a); 116 } 117 118 /** 119 * Add a color filter that can be represented by a color and a mode. Applied 120 * after color-computing texture stages. 121 */ setColorFilterGrDrawState122 void setColorFilter(GrColor c, SkXfermode::Mode mode) { 123 fColorFilterColor = c; 124 fColorFilterMode = mode; 125 } 126 getColorFilterColorGrDrawState127 GrColor getColorFilterColor() const { return fColorFilterColor; } getColorFilterModeGrDrawState128 SkXfermode::Mode getColorFilterMode() const { return fColorFilterMode; } 129 130 /// @} 131 132 /////////////////////////////////////////////////////////////////////////// 133 /// @name Coverage 134 //// 135 136 /** 137 * Sets a constant fractional coverage to be applied to the draw. The 138 * initial value (after construction or reset()) is 0xff. The constant 139 * coverage is ignored when per-vertex coverage is provided. 140 */ setCoverageGrDrawState141 void setCoverage(uint8_t coverage) { 142 fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage); 143 } 144 145 /** 146 * Version of above that specifies 4 channel per-vertex color. The value 147 * should be premultiplied. 148 */ setCoverage4GrDrawState149 void setCoverage4(GrColor coverage) { 150 fCoverage = coverage; 151 } 152 getCoverageGrDrawState153 GrColor getCoverage() const { 154 return fCoverage; 155 } 156 157 /// @} 158 159 /////////////////////////////////////////////////////////////////////////// 160 /// @name Textures 161 //// 162 163 /** 164 * Sets the texture used at the next drawing call 165 * 166 * @param stage The texture stage for which the texture will be set 167 * 168 * @param texture The texture to set. Can be NULL though there is no 169 * advantage to settings a NULL texture if doing non-textured drawing 170 */ setTextureGrDrawState171 void setTexture(int stage, GrTexture* texture) { 172 GrAssert((unsigned)stage < kNumStages); 173 fTextures[stage] = texture; 174 } 175 176 /** 177 * Retrieves the currently set texture. 178 * 179 * @return The currently set texture. The return value will be NULL if no 180 * texture has been set, NULL was most recently passed to 181 * setTexture, or the last setTexture was destroyed. 182 */ getTextureGrDrawState183 const GrTexture* getTexture(int stage) const { 184 GrAssert((unsigned)stage < kNumStages); 185 return fTextures[stage]; 186 } getTextureGrDrawState187 GrTexture* getTexture(int stage) { 188 GrAssert((unsigned)stage < kNumStages); 189 return fTextures[stage]; 190 } 191 192 /// @} 193 194 /////////////////////////////////////////////////////////////////////////// 195 /// @name Samplers 196 //// 197 198 /** 199 * Returns the current sampler for a stage. 200 */ getSamplerGrDrawState201 const GrSamplerState& getSampler(int stage) const { 202 GrAssert((unsigned)stage < kNumStages); 203 return fSamplerStates[stage]; 204 } 205 206 /** 207 * Writable pointer to a stage's sampler. 208 */ samplerGrDrawState209 GrSamplerState* sampler(int stage) { 210 GrAssert((unsigned)stage < kNumStages); 211 return fSamplerStates + stage; 212 } 213 214 /** 215 * Preconcats the matrix of all samplers in the mask with the same matrix. 216 */ preConcatSamplerMatricesGrDrawState217 void preConcatSamplerMatrices(StageMask stageMask, const GrMatrix& matrix) { 218 GrAssert(!(stageMask & kIllegalStageMaskBits)); 219 for (int i = 0; i < kNumStages; ++i) { 220 if ((1 << i) & stageMask) { 221 fSamplerStates[i].preConcatMatrix(matrix); 222 } 223 } 224 } 225 226 /// @} 227 228 /////////////////////////////////////////////////////////////////////////// 229 /// @name Coverage / Color Stages 230 //// 231 232 /** 233 * A common pattern is to compute a color with the initial stages and then 234 * modulate that color by a coverage value in later stage(s) (AA, mask- 235 * filters, glyph mask, etc). Color-filters, xfermodes, etc should be 236 * computed based on the pre-coverage-modulated color. The division of 237 * stages between color-computing and coverage-computing is specified by 238 * this method. Initially this is kNumStages (all stages 239 * are color-computing). 240 */ setFirstCoverageStageGrDrawState241 void setFirstCoverageStage(int firstCoverageStage) { 242 GrAssert((unsigned)firstCoverageStage <= kNumStages); 243 fFirstCoverageStage = firstCoverageStage; 244 } 245 246 /** 247 * Gets the index of the first coverage-computing stage. 248 */ getFirstCoverageStageGrDrawState249 int getFirstCoverageStage() const { 250 return fFirstCoverageStage; 251 } 252 253 ///@} 254 255 /////////////////////////////////////////////////////////////////////////// 256 /// @name Blending 257 //// 258 259 /** 260 * Sets the blending function coeffecients. 261 * 262 * The blend function will be: 263 * D' = sat(S*srcCoef + D*dstCoef) 264 * 265 * where D is the existing destination color, S is the incoming source 266 * color, and D' is the new destination color that will be written. sat() 267 * is the saturation function. 268 * 269 * @param srcCoef coeffecient applied to the src color. 270 * @param dstCoef coeffecient applied to the dst color. 271 */ setBlendFuncGrDrawState272 void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) { 273 fSrcBlend = srcCoeff; 274 fDstBlend = dstCoeff; 275 #if GR_DEBUG 276 switch (dstCoeff) { 277 case kDC_BlendCoeff: 278 case kIDC_BlendCoeff: 279 case kDA_BlendCoeff: 280 case kIDA_BlendCoeff: 281 GrPrintf("Unexpected dst blend coeff. Won't work correctly with" 282 "coverage stages.\n"); 283 break; 284 default: 285 break; 286 } 287 switch (srcCoeff) { 288 case kSC_BlendCoeff: 289 case kISC_BlendCoeff: 290 case kSA_BlendCoeff: 291 case kISA_BlendCoeff: 292 GrPrintf("Unexpected src blend coeff. Won't work correctly with" 293 "coverage stages.\n"); 294 break; 295 default: 296 break; 297 } 298 #endif 299 } 300 getSrcBlendCoeffGrDrawState301 GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; } getDstBlendCoeffGrDrawState302 GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; } 303 getDstBlendCoeffGrDrawState304 void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff, 305 GrBlendCoeff* dstBlendCoeff) const { 306 *srcBlendCoeff = fSrcBlend; 307 *dstBlendCoeff = fDstBlend; 308 } 309 310 /** 311 * Sets the blending function constant referenced by the following blending 312 * coeffecients: 313 * kConstC_BlendCoeff 314 * kIConstC_BlendCoeff 315 * kConstA_BlendCoeff 316 * kIConstA_BlendCoeff 317 * 318 * @param constant the constant to set 319 */ setBlendConstantGrDrawState320 void setBlendConstant(GrColor constant) { fBlendConstant = constant; } 321 322 /** 323 * Retrieves the last value set by setBlendConstant() 324 * @return the blending constant value 325 */ getBlendConstantGrDrawState326 GrColor getBlendConstant() const { return fBlendConstant; } 327 328 /// @} 329 330 /////////////////////////////////////////////////////////////////////////// 331 /// @name View Matrix 332 //// 333 334 /** 335 * Sets the matrix applied to veretx positions. 336 * 337 * In the post-view-matrix space the rectangle [0,w]x[0,h] 338 * fully covers the render target. (w and h are the width and height of the 339 * the rendertarget.) 340 */ setViewMatrixGrDrawState341 void setViewMatrix(const GrMatrix& m) { fViewMatrix = m; } 342 343 /** 344 * Gets a writable pointer to the view matrix. 345 */ viewMatrixGrDrawState346 GrMatrix* viewMatrix() { return &fViewMatrix; } 347 348 /** 349 * Multiplies the current view matrix by a matrix 350 * 351 * After this call V' = V*m where V is the old view matrix, 352 * m is the parameter to this function, and V' is the new view matrix. 353 * (We consider positions to be column vectors so position vector p is 354 * transformed by matrix X as p' = X*p.) 355 * 356 * @param m the matrix used to modify the view matrix. 357 */ preConcatViewMatrixGrDrawState358 void preConcatViewMatrix(const GrMatrix& m) { fViewMatrix.preConcat(m); } 359 360 /** 361 * Multiplies the current view matrix by a matrix 362 * 363 * After this call V' = m*V where V is the old view matrix, 364 * m is the parameter to this function, and V' is the new view matrix. 365 * (We consider positions to be column vectors so position vector p is 366 * transformed by matrix X as p' = X*p.) 367 * 368 * @param m the matrix used to modify the view matrix. 369 */ postConcatViewMatrixGrDrawState370 void postConcatViewMatrix(const GrMatrix& m) { fViewMatrix.postConcat(m); } 371 372 /** 373 * Retrieves the current view matrix 374 * @return the current view matrix. 375 */ getViewMatrixGrDrawState376 const GrMatrix& getViewMatrix() const { return fViewMatrix; } 377 378 /** 379 * Retrieves the inverse of the current view matrix. 380 * 381 * If the current view matrix is invertible, return true, and if matrix 382 * is non-null, copy the inverse into it. If the current view matrix is 383 * non-invertible, return false and ignore the matrix parameter. 384 * 385 * @param matrix if not null, will receive a copy of the current inverse. 386 */ getViewInverseGrDrawState387 bool getViewInverse(GrMatrix* matrix) const { 388 // TODO: determine whether we really need to leave matrix unmodified 389 // at call sites when inversion fails. 390 GrMatrix inverse; 391 if (fViewMatrix.invert(&inverse)) { 392 if (matrix) { 393 *matrix = inverse; 394 } 395 return true; 396 } 397 return false; 398 } 399 400 class AutoViewMatrixRestore : public ::GrNoncopyable { 401 public: AutoViewMatrixRestoreGrDrawState402 AutoViewMatrixRestore() : fDrawState(NULL) {} AutoViewMatrixRestoreGrDrawState403 AutoViewMatrixRestore(GrDrawState* ds, const GrMatrix& newMatrix) { 404 fDrawState = NULL; 405 this->set(ds, newMatrix); 406 } AutoViewMatrixRestoreGrDrawState407 AutoViewMatrixRestore(GrDrawState* ds) { 408 fDrawState = NULL; 409 this->set(ds); 410 } ~AutoViewMatrixRestoreGrDrawState411 ~AutoViewMatrixRestore() { 412 this->set(NULL, GrMatrix::I()); 413 } setGrDrawState414 void set(GrDrawState* ds, const GrMatrix& newMatrix) { 415 if (NULL != fDrawState) { 416 fDrawState->setViewMatrix(fSavedMatrix); 417 } 418 if (NULL != ds) { 419 fSavedMatrix = ds->getViewMatrix(); 420 ds->setViewMatrix(newMatrix); 421 } 422 fDrawState = ds; 423 } setGrDrawState424 void set(GrDrawState* ds) { 425 if (NULL != fDrawState) { 426 fDrawState->setViewMatrix(fSavedMatrix); 427 } 428 if (NULL != ds) { 429 fSavedMatrix = ds->getViewMatrix(); 430 } 431 fDrawState = ds; 432 } 433 private: 434 GrDrawState* fDrawState; 435 GrMatrix fSavedMatrix; 436 }; 437 438 /// @} 439 440 /////////////////////////////////////////////////////////////////////////// 441 /// @name Render Target 442 //// 443 444 /** 445 * Sets the rendertarget used at the next drawing call 446 * 447 * @param target The render target to set. 448 */ setRenderTargetGrDrawState449 void setRenderTarget(GrRenderTarget* target) { fRenderTarget = target; } 450 451 /** 452 * Retrieves the currently set rendertarget. 453 * 454 * @return The currently set render target. 455 */ getRenderTargetGrDrawState456 const GrRenderTarget* getRenderTarget() const { return fRenderTarget; } getRenderTargetGrDrawState457 GrRenderTarget* getRenderTarget() { return fRenderTarget; } 458 459 class AutoRenderTargetRestore : public ::GrNoncopyable { 460 public: AutoRenderTargetRestoreGrDrawState461 AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {} AutoRenderTargetRestoreGrDrawState462 AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) { 463 fDrawState = NULL; 464 this->set(ds, newTarget); 465 } ~AutoRenderTargetRestoreGrDrawState466 ~AutoRenderTargetRestore() { this->set(NULL, NULL); } setGrDrawState467 void set(GrDrawState* ds, GrRenderTarget* newTarget) { 468 if (NULL != fDrawState) { 469 fDrawState->setRenderTarget(fSavedTarget); 470 } 471 if (NULL != ds) { 472 fSavedTarget = ds->getRenderTarget(); 473 ds->setRenderTarget(newTarget); 474 } 475 fDrawState = ds; 476 } 477 private: 478 GrDrawState* fDrawState; 479 GrRenderTarget* fSavedTarget; 480 }; 481 482 /// @} 483 484 /////////////////////////////////////////////////////////////////////////// 485 /// @name Stencil 486 //// 487 488 /** 489 * Sets the stencil settings to use for the next draw. 490 * Changing the clip has the side-effect of possibly zeroing 491 * out the client settable stencil bits. So multipass algorithms 492 * using stencil should not change the clip between passes. 493 * @param settings the stencil settings to use. 494 */ setStencilGrDrawState495 void setStencil(const GrStencilSettings& settings) { 496 fStencilSettings = settings; 497 } 498 499 /** 500 * Shortcut to disable stencil testing and ops. 501 */ disableStencilGrDrawState502 void disableStencil() { 503 fStencilSettings.setDisabled(); 504 } 505 getStencilGrDrawState506 const GrStencilSettings& getStencil() const { return fStencilSettings; } 507 stencilGrDrawState508 GrStencilSettings* stencil() { return &fStencilSettings; } 509 510 /// @} 511 512 /////////////////////////////////////////////////////////////////////////// 513 /// @name Color Matrix 514 //// 515 516 /** 517 * Sets the color matrix to use for the next draw. 518 * @param matrix the 5x4 matrix to apply to the incoming color 519 */ setColorMatrixGrDrawState520 void setColorMatrix(const float matrix[20]) { 521 memcpy(fColorMatrix, matrix, sizeof(fColorMatrix)); 522 } 523 getColorMatrixGrDrawState524 const float* getColorMatrix() const { return fColorMatrix; } 525 526 /// @} 527 528 /////////////////////////////////////////////////////////////////////////// 529 // @name Edge AA 530 // There are two ways to perform antialiasing using edge equations. One 531 // is to specify an (linear or quadratic) edge eq per-vertex. This requires 532 // splitting vertices shared by primitives. 533 // 534 // The other is via setEdgeAAData which sets a set of edges and each 535 // is tested against all the edges. 536 //// 537 538 /** 539 * When specifying edges as vertex data this enum specifies what type of 540 * edges are in use. The edges are always 4 GrScalars in memory, even when 541 * the edge type requires fewer than 4. 542 */ 543 enum VertexEdgeType { 544 /* 1-pixel wide line 545 2D implicit line eq (a*x + b*y +c = 0). 4th component unused */ 546 kHairLine_EdgeType, 547 /* Quadratic specified by u^2-v canonical coords (only 2 548 components used). Coverage based on signed distance with negative 549 being inside, positive outside.*/ 550 kQuad_EdgeType, 551 /* Same as above but for hairline quadratics. Uses unsigned distance. 552 Coverage is min(0, 1-distance). */ 553 kHairQuad_EdgeType, 554 555 kVertexEdgeTypeCnt 556 }; 557 558 /** 559 * Determines the interpretation per-vertex edge data when the 560 * kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges 561 * are not specified the value of this setting has no effect. 562 */ setVertexEdgeTypeGrDrawState563 void setVertexEdgeType(VertexEdgeType type) { 564 GrAssert(type >=0 && type < kVertexEdgeTypeCnt); 565 fVertexEdgeType = type; 566 } 567 getVertexEdgeTypeGrDrawState568 VertexEdgeType getVertexEdgeType() const { return fVertexEdgeType; } 569 570 /** 571 * The absolute maximum number of edges that may be specified for 572 * a single draw call when performing edge antialiasing. This is used for 573 * the size of several static buffers, so implementations of getMaxEdges() 574 * (below) should clamp to this value. 575 */ 576 enum { 577 // TODO: this should be 32 when GrTesselatedPathRenderer is used 578 // Visual Studio 2010 does not permit a member array of size 0. 579 kMaxEdges = 1 580 }; 581 582 class Edge { 583 public: EdgeGrDrawState584 Edge() {} EdgeGrDrawState585 Edge(float x, float y, float z) : fX(x), fY(y), fZ(z) {} intersectGrDrawState586 GrPoint intersect(const Edge& other) { 587 return GrPoint::Make( 588 SkFloatToScalar((fY * other.fZ - other.fY * fZ) / 589 (fX * other.fY - other.fX * fY)), 590 SkFloatToScalar((fX * other.fZ - other.fX * fZ) / 591 (other.fX * fY - fX * other.fY))); 592 } 593 float fX, fY, fZ; 594 }; 595 596 /** 597 * Sets the edge data required for edge antialiasing. 598 * 599 * @param edges 3 * numEdges float values, representing the edge 600 * equations in Ax + By + C form 601 */ setEdgeAADataGrDrawState602 void setEdgeAAData(const Edge* edges, int numEdges) { 603 GrAssert(numEdges <= GrDrawState::kMaxEdges); 604 memcpy(fEdgeAAEdges, edges, numEdges * sizeof(GrDrawState::Edge)); 605 fEdgeAANumEdges = numEdges; 606 } 607 getNumAAEdgesGrDrawState608 int getNumAAEdges() const { return fEdgeAANumEdges; } 609 getAAEdgesGrDrawState610 const Edge* getAAEdges() const { return fEdgeAAEdges; } 611 612 /// @} 613 614 /////////////////////////////////////////////////////////////////////////// 615 /// @name State Flags 616 //// 617 618 /** 619 * Flags that affect rendering. Controlled using enable/disableState(). All 620 * default to disabled. 621 */ 622 enum StateBits { 623 /** 624 * Perform dithering. TODO: Re-evaluate whether we need this bit 625 */ 626 kDither_StateBit = 0x01, 627 /** 628 * Perform HW anti-aliasing. This means either HW FSAA, if supported 629 * by the render target, or smooth-line rendering if a line primitive 630 * is drawn and line smoothing is supported by the 3D API. 631 */ 632 kHWAntialias_StateBit = 0x02, 633 /** 634 * Draws will respect the clip, otherwise the clip is ignored. 635 */ 636 kClip_StateBit = 0x04, 637 /** 638 * Disables writing to the color buffer. Useful when performing stencil 639 * operations. 640 */ 641 kNoColorWrites_StateBit = 0x08, 642 /** 643 * Modifies the behavior of edge AA specified by setEdgeAA. If set, 644 * will test edge pairs for convexity when rasterizing. Set this if the 645 * source polygon is non-convex. 646 */ 647 kEdgeAAConcave_StateBit = 0x10, 648 /** 649 * Draws will apply the color matrix, otherwise the color matrix is 650 * ignored. 651 */ 652 kColorMatrix_StateBit = 0x20, 653 654 // Users of the class may add additional bits to the vector 655 kDummyStateBit, 656 kLastPublicStateBit = kDummyStateBit-1, 657 }; 658 resetStateFlagsGrDrawState659 void resetStateFlags() { 660 fFlagBits = 0; 661 } 662 663 /** 664 * Enable render state settings. 665 * 666 * @param flags bitfield of StateBits specifing the states to enable 667 */ enableStateGrDrawState668 void enableState(uint32_t stateBits) { 669 fFlagBits |= stateBits; 670 } 671 672 /** 673 * Disable render state settings. 674 * 675 * @param flags bitfield of StateBits specifing the states to disable 676 */ disableStateGrDrawState677 void disableState(uint32_t stateBits) { 678 fFlagBits &= ~(stateBits); 679 } 680 isDitherStateGrDrawState681 bool isDitherState() const { 682 return 0 != (fFlagBits & kDither_StateBit); 683 } 684 isHWAntialiasStateGrDrawState685 bool isHWAntialiasState() const { 686 return 0 != (fFlagBits & kHWAntialias_StateBit); 687 } 688 isClipStateGrDrawState689 bool isClipState() const { 690 return 0 != (fFlagBits & kClip_StateBit); 691 } 692 isColorWriteDisabledGrDrawState693 bool isColorWriteDisabled() const { 694 return 0 != (fFlagBits & kNoColorWrites_StateBit); 695 } 696 isConcaveEdgeAAStateGrDrawState697 bool isConcaveEdgeAAState() const { 698 return 0 != (fFlagBits & kEdgeAAConcave_StateBit); 699 } 700 isStateFlagEnabledGrDrawState701 bool isStateFlagEnabled(uint32_t stateBit) const { 702 return 0 != (stateBit & fFlagBits); 703 } 704 copyStateFlagsGrDrawState705 void copyStateFlags(const GrDrawState& ds) { 706 fFlagBits = ds.fFlagBits; 707 } 708 709 /// @} 710 711 /////////////////////////////////////////////////////////////////////////// 712 /// @name Face Culling 713 //// 714 715 enum DrawFace { 716 kBoth_DrawFace, 717 kCCW_DrawFace, 718 kCW_DrawFace, 719 }; 720 721 /** 722 * Controls whether clockwise, counterclockwise, or both faces are drawn. 723 * @param face the face(s) to draw. 724 */ setDrawFaceGrDrawState725 void setDrawFace(DrawFace face) { 726 fDrawFace = face; 727 } 728 729 /** 730 * Gets whether the target is drawing clockwise, counterclockwise, 731 * or both faces. 732 * @return the current draw face(s). 733 */ getDrawFaceGrDrawState734 DrawFace getDrawFace() const { return fDrawFace; } 735 736 /// @} 737 738 /////////////////////////////////////////////////////////////////////////// 739 740 // Most stages are usually not used, so conditionals here 741 // reduce the expected number of bytes touched by 50%. 742 bool operator ==(const GrDrawState& s) const { 743 if (memcmp(this, &s, this->leadingBytes())) return false; 744 745 for (int i = 0; i < kNumStages; i++) { 746 if (fTextures[i] && 747 memcmp(&this->fSamplerStates[i], &s.fSamplerStates[i], 748 sizeof(GrSamplerState))) { 749 return false; 750 } 751 } 752 753 return true; 754 } 755 bool operator !=(const GrDrawState& s) const { return !(*this == s); } 756 757 // Most stages are usually not used, so conditionals here 758 // reduce the expected number of bytes touched by 50%. 759 GrDrawState& operator =(const GrDrawState& s) { 760 memcpy(this, &s, this->leadingBytes()); 761 762 for (int i = 0; i < kNumStages; i++) { 763 if (s.fTextures[i]) { 764 memcpy(&this->fSamplerStates[i], &s.fSamplerStates[i], 765 sizeof(GrSamplerState)); 766 } 767 } 768 769 return *this; 770 } 771 772 private: 773 static const StageMask kIllegalStageMaskBits = ~((1 << kNumStages)-1); 774 // @{ these fields can be initialized with memset to 0 775 GrColor fBlendConstant; 776 GrTexture* fTextures[kNumStages]; 777 GrColor fColorFilterColor; 778 uint32_t fFlagBits; 779 DrawFace fDrawFace; 780 VertexEdgeType fVertexEdgeType; 781 GrStencilSettings fStencilSettings; 782 float fColorMatrix[20]; // 5 x 4 matrix 783 GrRenderTarget* fRenderTarget; 784 // @} 785 786 // @{ Initialized to values other than zero 787 GrColor fColor; 788 GrColor fCoverage; 789 int fFirstCoverageStage; 790 SkXfermode::Mode fColorFilterMode; 791 GrBlendCoeff fSrcBlend; 792 GrBlendCoeff fDstBlend; 793 GrMatrix fViewMatrix; 794 // @} 795 796 // @{ Data for GrTesselatedPathRenderer 797 // TODO: currently ignored in copying & comparison for performance. 798 // Must be considered if GrTesselatedPathRenderer is being used. 799 int fEdgeAANumEdges; 800 Edge fEdgeAAEdges[kMaxEdges]; 801 // @} 802 803 // This field must be last; it will not be copied or compared 804 // if the corresponding fTexture[] is NULL. 805 GrSamplerState fSamplerStates[kNumStages]; 806 leadingBytesGrDrawState807 size_t leadingBytes() const { 808 // Can't use offsetof() with non-POD types, so stuck with pointer math. 809 // TODO: ignores GrTesselatedPathRenderer data structures. We don't 810 // have a compile-time flag that lets us know if it's being used, and 811 // checking at runtime seems to cost 5% performance. 812 return (size_t) ((unsigned char*)&fEdgeAANumEdges - 813 (unsigned char*)&fBlendConstant); 814 } 815 816 }; 817 818 #endif 819