1 /* 2 * Copyright 2012 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 #include "GrDrawState.h" 9 10 #include "GrGpuVertex.h" 11 #include "GrPaint.h" 12 13 void GrDrawState::setFromPaint(const GrPaint& paint) { 14 for (int i = 0; i < GrPaint::kMaxColorStages; ++i) { 15 int s = i + GrPaint::kFirstColorStage; 16 if (paint.isColorStageEnabled(i)) { 17 fStages[s] = paint.getColorStage(i); 18 } else { 19 fStages[s].setEffect(NULL); 20 } 21 } 22 23 this->setFirstCoverageStage(GrPaint::kFirstCoverageStage); 24 25 for (int i = 0; i < GrPaint::kMaxCoverageStages; ++i) { 26 int s = i + GrPaint::kFirstCoverageStage; 27 if (paint.isCoverageStageEnabled(i)) { 28 fStages[s] = paint.getCoverageStage(i); 29 } else { 30 fStages[s].setEffect(NULL); 31 } 32 } 33 34 // disable all stages not accessible via the paint 35 for (int s = GrPaint::kTotalStages; s < GrDrawState::kNumStages; ++s) { 36 this->disableStage(s); 37 } 38 39 this->setColor(paint.getColor()); 40 41 this->setState(GrDrawState::kDither_StateBit, paint.isDither()); 42 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); 43 44 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff()); 45 this->setColorFilter(paint.getColorFilterColor(), paint.getColorFilterMode()); 46 this->setCoverage(paint.getCoverage()); 47 } 48 49 //////////////////////////////////////////////////////////////////////////////// 50 51 namespace { 52 53 /** 54 * This function generates some masks that we like to have known at compile 55 * time. When the number of stages or tex coords is bumped or the way bits 56 * are defined in GrDrawState.h changes this function should be rerun to 57 * generate the new masks. (We attempted to force the compiler to generate the 58 * masks using recursive templates but always wound up with static initializers 59 * under gcc, even if they were just a series of immediate->memory moves.) 60 * 61 */ 62 void gen_mask_arrays(GrVertexLayout* stageTexCoordMasks, 63 GrVertexLayout* texCoordMasks) { 64 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 65 stageTexCoordMasks[s] = 0; 66 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { 67 stageTexCoordMasks[s] |= GrDrawState::StageTexCoordVertexLayoutBit(s, t); 68 } 69 } 70 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { 71 texCoordMasks[t] = 0; 72 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 73 texCoordMasks[t] |= GrDrawState::StageTexCoordVertexLayoutBit(s, t); 74 } 75 } 76 } 77 78 /** 79 * Uncomment and run the gen_globals function to generate 80 * the code that declares the global masks. 81 * 82 * #if 0'ed out to avoid unused function warning. 83 */ 84 85 #if 0 86 void gen_globals() { 87 GrVertexLayout stageTexCoordMasks[GrDrawState::kNumStages]; 88 GrVertexLayout texCoordMasks[GrDrawState::kMaxTexCoords]; 89 gen_mask_arrays(stageTexCoordMasks, texCoordMasks); 90 91 GrPrintf("const GrVertexLayout gStageTexCoordMasks[] = {\n"); 92 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 93 GrPrintf(" 0x%x,\n", stageTexCoordMasks[s]); 94 } 95 GrPrintf("};\n"); 96 GrPrintf("GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageTexCoordMasks));\n\n"); 97 GrPrintf("const GrVertexLayout gTexCoordMasks[] = {\n"); 98 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { 99 GrPrintf(" 0x%x,\n", texCoordMasks[t]); 100 } 101 GrPrintf("};\n"); 102 GrPrintf("GR_STATIC_ASSERT(GrDrawState::kMaxTexCoords == GR_ARRAY_COUNT(gTexCoordMasks));\n"); 103 } 104 #endif 105 106 /* These values were generated by the above function */ 107 108 const GrVertexLayout gStageTexCoordMasks[] = { 109 0x108421, 110 0x210842, 111 0x421084, 112 0x842108, 113 0x1084210, 114 }; 115 GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageTexCoordMasks)); 116 117 const GrVertexLayout gTexCoordMasks[] = { 118 0x1f, 119 0x3e0, 120 0x7c00, 121 0xf8000, 122 0x1f00000, 123 }; 124 GR_STATIC_ASSERT(GrDrawState::kMaxTexCoords == GR_ARRAY_COUNT(gTexCoordMasks)); 125 126 #ifdef SK_DEBUG 127 bool check_layout(GrVertexLayout layout) { 128 // can only have 1 or 0 bits set for each stage. 129 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 130 int stageBits = layout & gStageTexCoordMasks[s]; 131 if (stageBits && !GrIsPow2(stageBits)) { 132 return false; 133 } 134 } 135 return true; 136 } 137 #endif 138 139 int num_tex_coords(GrVertexLayout layout) { 140 int cnt = 0; 141 // figure out how many tex coordinates are present 142 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { 143 if (gTexCoordMasks[t] & layout) { 144 ++cnt; 145 } 146 } 147 return cnt; 148 } 149 150 } //unnamed namespace 151 152 size_t GrDrawState::VertexSize(GrVertexLayout vertexLayout) { 153 GrAssert(check_layout(vertexLayout)); 154 155 size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 156 sizeof(GrGpuTextVertex) : 157 sizeof(GrPoint); 158 159 size_t size = vecSize; // position 160 size += num_tex_coords(vertexLayout) * vecSize; 161 if (vertexLayout & kColor_VertexLayoutBit) { 162 size += sizeof(GrColor); 163 } 164 if (vertexLayout & kCoverage_VertexLayoutBit) { 165 size += sizeof(GrColor); 166 } 167 if (vertexLayout & kEdge_VertexLayoutBit) { 168 size += 4 * sizeof(SkScalar); 169 } 170 return size; 171 } 172 173 //////////////////////////////////////////////////////////////////////////////// 174 175 /** 176 * Functions for computing offsets of various components from the layout 177 * bitfield. 178 * 179 * Order of vertex components: 180 * Position 181 * Tex Coord 0 182 * ... 183 * Tex Coord GrDrawState::kMaxTexCoords-1 184 * Color 185 * Coverage 186 */ 187 188 int GrDrawState::VertexStageCoordOffset(int stageIdx, GrVertexLayout vertexLayout) { 189 GrAssert(check_layout(vertexLayout)); 190 191 if (!StageUsesTexCoords(vertexLayout, stageIdx)) { 192 return 0; 193 } 194 int tcIdx = VertexTexCoordsForStage(stageIdx, vertexLayout); 195 if (tcIdx >= 0) { 196 197 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 198 sizeof(GrGpuTextVertex) : 199 sizeof(GrPoint); 200 int offset = vecSize; // position 201 // figure out how many tex coordinates are present and precede this one. 202 for (int t = 0; t < tcIdx; ++t) { 203 if (gTexCoordMasks[t] & vertexLayout) { 204 offset += vecSize; 205 } 206 } 207 return offset; 208 } 209 210 return -1; 211 } 212 213 int GrDrawState::VertexColorOffset(GrVertexLayout vertexLayout) { 214 GrAssert(check_layout(vertexLayout)); 215 216 if (vertexLayout & kColor_VertexLayoutBit) { 217 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 218 sizeof(GrGpuTextVertex) : 219 sizeof(GrPoint); 220 return vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos 221 } 222 return -1; 223 } 224 225 int GrDrawState::VertexCoverageOffset(GrVertexLayout vertexLayout) { 226 GrAssert(check_layout(vertexLayout)); 227 228 if (vertexLayout & kCoverage_VertexLayoutBit) { 229 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 230 sizeof(GrGpuTextVertex) : 231 sizeof(GrPoint); 232 233 int offset = vecSize * (num_tex_coords(vertexLayout) + 1); 234 if (vertexLayout & kColor_VertexLayoutBit) { 235 offset += sizeof(GrColor); 236 } 237 return offset; 238 } 239 return -1; 240 } 241 242 int GrDrawState::VertexEdgeOffset(GrVertexLayout vertexLayout) { 243 GrAssert(check_layout(vertexLayout)); 244 245 // edge pts are after the pos, tex coords, and color 246 if (vertexLayout & kEdge_VertexLayoutBit) { 247 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 248 sizeof(GrGpuTextVertex) : 249 sizeof(GrPoint); 250 int offset = vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos 251 if (vertexLayout & kColor_VertexLayoutBit) { 252 offset += sizeof(GrColor); 253 } 254 if (vertexLayout & kCoverage_VertexLayoutBit) { 255 offset += sizeof(GrColor); 256 } 257 return offset; 258 } 259 return -1; 260 } 261 262 int GrDrawState::VertexSizeAndOffsetsByIdx( 263 GrVertexLayout vertexLayout, 264 int texCoordOffsetsByIdx[kMaxTexCoords], 265 int* colorOffset, 266 int* coverageOffset, 267 int* edgeOffset) { 268 GrAssert(check_layout(vertexLayout)); 269 270 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 271 sizeof(GrGpuTextVertex) : 272 sizeof(GrPoint); 273 int size = vecSize; // position 274 275 for (int t = 0; t < kMaxTexCoords; ++t) { 276 if (gTexCoordMasks[t] & vertexLayout) { 277 if (NULL != texCoordOffsetsByIdx) { 278 texCoordOffsetsByIdx[t] = size; 279 } 280 size += vecSize; 281 } else { 282 if (NULL != texCoordOffsetsByIdx) { 283 texCoordOffsetsByIdx[t] = -1; 284 } 285 } 286 } 287 if (kColor_VertexLayoutBit & vertexLayout) { 288 if (NULL != colorOffset) { 289 *colorOffset = size; 290 } 291 size += sizeof(GrColor); 292 } else { 293 if (NULL != colorOffset) { 294 *colorOffset = -1; 295 } 296 } 297 if (kCoverage_VertexLayoutBit & vertexLayout) { 298 if (NULL != coverageOffset) { 299 *coverageOffset = size; 300 } 301 size += sizeof(GrColor); 302 } else { 303 if (NULL != coverageOffset) { 304 *coverageOffset = -1; 305 } 306 } 307 if (kEdge_VertexLayoutBit & vertexLayout) { 308 if (NULL != edgeOffset) { 309 *edgeOffset = size; 310 } 311 size += 4 * sizeof(SkScalar); 312 } else { 313 if (NULL != edgeOffset) { 314 *edgeOffset = -1; 315 } 316 } 317 return size; 318 } 319 320 int GrDrawState::VertexSizeAndOffsetsByStage( 321 GrVertexLayout vertexLayout, 322 int texCoordOffsetsByStage[GrDrawState::kNumStages], 323 int* colorOffset, 324 int* coverageOffset, 325 int* edgeOffset) { 326 GrAssert(check_layout(vertexLayout)); 327 328 int texCoordOffsetsByIdx[kMaxTexCoords]; 329 int size = VertexSizeAndOffsetsByIdx(vertexLayout, 330 (NULL == texCoordOffsetsByStage) ? 331 NULL : 332 texCoordOffsetsByIdx, 333 colorOffset, 334 coverageOffset, 335 edgeOffset); 336 if (NULL != texCoordOffsetsByStage) { 337 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 338 int tcIdx = VertexTexCoordsForStage(s, vertexLayout); 339 texCoordOffsetsByStage[s] = 340 tcIdx < 0 ? 0 : texCoordOffsetsByIdx[tcIdx]; 341 } 342 } 343 return size; 344 } 345 346 //////////////////////////////////////////////////////////////////////////////// 347 348 bool GrDrawState::VertexUsesTexCoordIdx(int coordIndex, 349 GrVertexLayout vertexLayout) { 350 GrAssert(coordIndex < kMaxTexCoords); 351 GrAssert(check_layout(vertexLayout)); 352 return !!(gTexCoordMasks[coordIndex] & vertexLayout); 353 } 354 355 int GrDrawState::VertexTexCoordsForStage(int stageIdx, 356 GrVertexLayout vertexLayout) { 357 GrAssert(stageIdx < GrDrawState::kNumStages); 358 GrAssert(check_layout(vertexLayout)); 359 int bit = vertexLayout & gStageTexCoordMasks[stageIdx]; 360 if (bit) { 361 // figure out which set of texture coordates is used 362 // bits are ordered T0S0, T0S1, T0S2, ..., T1S0, T1S1, ... 363 // and start at bit 0. 364 GR_STATIC_ASSERT(sizeof(GrVertexLayout) <= sizeof(uint32_t)); 365 return (32 - SkCLZ(bit) - 1) / GrDrawState::kNumStages; 366 } 367 return -1; 368 } 369 370 //////////////////////////////////////////////////////////////////////////////// 371 372 void GrDrawState::VertexLayoutUnitTest() { 373 // Ensure that our globals mask arrays are correct 374 GrVertexLayout stageTexCoordMasks[GrDrawState::kNumStages]; 375 GrVertexLayout texCoordMasks[kMaxTexCoords]; 376 gen_mask_arrays(stageTexCoordMasks, texCoordMasks); 377 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 378 GrAssert(stageTexCoordMasks[s] == gStageTexCoordMasks[s]); 379 } 380 for (int t = 0; t < kMaxTexCoords; ++t) { 381 GrAssert(texCoordMasks[t] == gTexCoordMasks[t]); 382 } 383 384 // not necessarily exhaustive 385 static bool run; 386 if (!run) { 387 run = true; 388 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 389 390 GrVertexLayout stageMask = 0; 391 for (int t = 0; t < kMaxTexCoords; ++t) { 392 stageMask |= StageTexCoordVertexLayoutBit(s,t); 393 } 394 GrAssert(1 == kMaxTexCoords || 395 !check_layout(stageMask)); 396 GrAssert(gStageTexCoordMasks[s] == stageMask); 397 GrAssert(!check_layout(stageMask)); 398 } 399 for (int t = 0; t < kMaxTexCoords; ++t) { 400 GrVertexLayout tcMask = 0; 401 GrAssert(!VertexUsesTexCoordIdx(t, 0)); 402 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 403 tcMask |= StageTexCoordVertexLayoutBit(s,t); 404 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask)); 405 GrAssert(VertexUsesTexCoordIdx(t, tcMask)); 406 GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask)); 407 GrAssert(t == VertexTexCoordsForStage(s, tcMask)); 408 for (int s2 = s + 1; s2 < GrDrawState::kNumStages; ++s2) { 409 GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask)); 410 411 #if GR_DEBUG 412 GrVertexLayout posAsTex = tcMask; 413 #endif 414 GrAssert(0 == VertexStageCoordOffset(s2, posAsTex)); 415 GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex)); 416 GrAssert(-1 == VertexTexCoordsForStage(s2, posAsTex)); 417 GrAssert(-1 == VertexEdgeOffset(posAsTex)); 418 } 419 GrAssert(-1 == VertexEdgeOffset(tcMask)); 420 GrAssert(-1 == VertexColorOffset(tcMask)); 421 GrAssert(-1 == VertexCoverageOffset(tcMask)); 422 #if GR_DEBUG 423 GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit; 424 #endif 425 GrAssert(-1 == VertexCoverageOffset(withColor)); 426 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor)); 427 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor)); 428 #if GR_DEBUG 429 GrVertexLayout withEdge = tcMask | kEdge_VertexLayoutBit; 430 #endif 431 GrAssert(-1 == VertexColorOffset(withEdge)); 432 GrAssert(2*sizeof(GrPoint) == VertexEdgeOffset(withEdge)); 433 GrAssert(4*sizeof(GrPoint) == VertexSize(withEdge)); 434 #if GR_DEBUG 435 GrVertexLayout withColorAndEdge = withColor | kEdge_VertexLayoutBit; 436 #endif 437 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColorAndEdge)); 438 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexEdgeOffset(withColorAndEdge)); 439 GrAssert(4*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColorAndEdge)); 440 #if GR_DEBUG 441 GrVertexLayout withCoverage = tcMask | kCoverage_VertexLayoutBit; 442 #endif 443 GrAssert(-1 == VertexColorOffset(withCoverage)); 444 GrAssert(2*sizeof(GrPoint) == VertexCoverageOffset(withCoverage)); 445 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withCoverage)); 446 #if GR_DEBUG 447 GrVertexLayout withCoverageAndColor = tcMask | kCoverage_VertexLayoutBit | 448 kColor_VertexLayoutBit; 449 #endif 450 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withCoverageAndColor)); 451 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexCoverageOffset(withCoverageAndColor)); 452 GrAssert(2*sizeof(GrPoint) + 2 * sizeof(GrColor) == VertexSize(withCoverageAndColor)); 453 } 454 GrAssert(gTexCoordMasks[t] == tcMask); 455 GrAssert(check_layout(tcMask)); 456 457 int stageOffsets[GrDrawState::kNumStages]; 458 int colorOffset; 459 int edgeOffset; 460 int coverageOffset; 461 int size; 462 size = VertexSizeAndOffsetsByStage(tcMask, 463 stageOffsets, &colorOffset, 464 &coverageOffset, &edgeOffset); 465 GrAssert(2*sizeof(GrPoint) == size); 466 GrAssert(-1 == colorOffset); 467 GrAssert(-1 == coverageOffset); 468 GrAssert(-1 == edgeOffset); 469 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 470 GrAssert(sizeof(GrPoint) == stageOffsets[s]); 471 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask)); 472 } 473 } 474 } 475 } 476 477 //////////////////////////////////////////////////////////////////////////////// 478 479 bool GrDrawState::StageUsesTexCoords(GrVertexLayout layout, int stageIdx) { 480 return SkToBool(layout & gStageTexCoordMasks[stageIdx]); 481 } 482 483 bool GrDrawState::srcAlphaWillBeOne(GrVertexLayout layout) const { 484 485 uint32_t validComponentFlags; 486 GrColor color; 487 // Check if per-vertex or constant color may have partial alpha 488 if (layout & kColor_VertexLayoutBit) { 489 validComponentFlags = 0; 490 } else { 491 validComponentFlags = GrEffect::kAll_ValidComponentFlags; 492 color = this->getColor(); 493 } 494 495 // Run through the color stages 496 int stageCnt = getFirstCoverageStage(); 497 for (int s = 0; s < stageCnt; ++s) { 498 const GrEffectRef* effect = this->getStage(s).getEffect(); 499 if (NULL != effect) { 500 (*effect)->getConstantColorComponents(&color, &validComponentFlags); 501 } 502 } 503 504 // Check if the color filter could introduce an alpha. 505 // We could skip the above work when this is true, but it is rare and the right fix is to make 506 // the color filter a GrEffect and implement getConstantColorComponents() for it. 507 if (SkXfermode::kDst_Mode != this->getColorFilterMode()) { 508 validComponentFlags = 0; 509 } 510 511 // Check whether coverage is treated as color. If so we run through the coverage computation. 512 if (this->isCoverageDrawing()) { 513 GrColor coverageColor = this->getCoverage(); 514 GrColor oldColor = color; 515 color = 0; 516 for (int c = 0; c < 4; ++c) { 517 if (validComponentFlags & (1 << c)) { 518 U8CPU a = (oldColor >> (c * 8)) & 0xff; 519 U8CPU b = (coverageColor >> (c * 8)) & 0xff; 520 color |= (SkMulDiv255Round(a, b) << (c * 8)); 521 } 522 } 523 for (int s = this->getFirstCoverageStage(); s < GrDrawState::kNumStages; ++s) { 524 const GrEffectRef* effect = this->getStage(s).getEffect(); 525 if (NULL != effect) { 526 (*effect)->getConstantColorComponents(&color, &validComponentFlags); 527 } 528 } 529 } 530 return (GrEffect::kA_ValidComponentFlag & validComponentFlags) && 0xff == GrColorUnpackA(color); 531 } 532 533 bool GrDrawState::hasSolidCoverage(GrVertexLayout layout) const { 534 // If we're drawing coverage directly then coverage is effectively treated as color. 535 if (this->isCoverageDrawing()) { 536 return true; 537 } 538 539 GrColor coverage; 540 uint32_t validComponentFlags; 541 // Initialize to an unknown starting coverage if per-vertex coverage is specified. 542 if (layout & kCoverage_VertexLayoutBit) { 543 validComponentFlags = 0; 544 } else { 545 coverage = fCommon.fCoverage; 546 validComponentFlags = GrEffect::kAll_ValidComponentFlags; 547 } 548 549 // Run through the coverage stages and see if the coverage will be all ones at the end. 550 for (int s = this->getFirstCoverageStage(); s < GrDrawState::kNumStages; ++s) { 551 const GrEffectRef* effect = this->getStage(s).getEffect(); 552 if (NULL != effect) { 553 (*effect)->getConstantColorComponents(&coverage, &validComponentFlags); 554 } 555 } 556 return (GrEffect::kAll_ValidComponentFlags == validComponentFlags) && (0xffffffff == coverage); 557 } 558 559 //////////////////////////////////////////////////////////////////////////////// 560 561 void GrDrawState::AutoViewMatrixRestore::restore() { 562 if (NULL != fDrawState) { 563 fDrawState->setViewMatrix(fViewMatrix); 564 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 565 if (fRestoreMask & (1 << s)) { 566 fDrawState->fStages[s].restoreCoordChange(fSavedCoordChanges[s]); 567 } 568 } 569 } 570 fDrawState = NULL; 571 } 572 573 void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState, 574 const SkMatrix& preconcatMatrix, 575 uint32_t explicitCoordStageMask) { 576 this->restore(); 577 578 fDrawState = drawState; 579 if (NULL == drawState) { 580 return; 581 } 582 583 fRestoreMask = 0; 584 fViewMatrix = drawState->getViewMatrix(); 585 drawState->preConcatViewMatrix(preconcatMatrix); 586 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 587 if (!(explicitCoordStageMask & (1 << s)) && drawState->isStageEnabled(s)) { 588 fRestoreMask |= (1 << s); 589 fDrawState->fStages[s].saveCoordChange(&fSavedCoordChanges[s]); 590 drawState->fStages[s].preConcatCoordChange(preconcatMatrix); 591 } 592 } 593 } 594 595 //////////////////////////////////////////////////////////////////////////////// 596 597 void GrDrawState::AutoDeviceCoordDraw::restore() { 598 if (NULL != fDrawState) { 599 fDrawState->setViewMatrix(fViewMatrix); 600 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 601 if (fRestoreMask & (1 << s)) { 602 fDrawState->fStages[s].restoreCoordChange(fSavedCoordChanges[s]); 603 } 604 } 605 } 606 fDrawState = NULL; 607 } 608 609 bool GrDrawState::AutoDeviceCoordDraw::set(GrDrawState* drawState, 610 uint32_t explicitCoordStageMask) { 611 GrAssert(NULL != drawState); 612 613 this->restore(); 614 615 fDrawState = drawState; 616 if (NULL == fDrawState) { 617 return false; 618 } 619 620 fViewMatrix = drawState->getViewMatrix(); 621 fRestoreMask = 0; 622 SkMatrix invVM; 623 bool inverted = false; 624 625 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 626 if (!(explicitCoordStageMask & (1 << s)) && drawState->isStageEnabled(s)) { 627 if (!inverted && !fViewMatrix.invert(&invVM)) { 628 // sad trombone sound 629 fDrawState = NULL; 630 return false; 631 } else { 632 inverted = true; 633 } 634 fRestoreMask |= (1 << s); 635 GrEffectStage* stage = drawState->fStages + s; 636 stage->saveCoordChange(&fSavedCoordChanges[s]); 637 stage->preConcatCoordChange(invVM); 638 } 639 } 640 drawState->viewMatrix()->reset(); 641 return true; 642 } 643