1 /* 2 Copyright 2010 Google Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 18 #include "GrDrawTarget.h" 19 #include "GrGpuVertex.h" 20 #include "GrTexture.h" 21 22 namespace { 23 24 // recursive helper for creating mask with all the tex coord bits set for 25 // one stage 26 template <int N> 27 int stage_mask_recur(int stage) { 28 return GrDrawTarget::StageTexCoordVertexLayoutBit(stage, N) | 29 stage_mask_recur<N+1>(stage); 30 } 31 template<> 32 int stage_mask_recur<GrDrawTarget::kNumStages>(int) { return 0; } 33 34 // mask of all tex coord indices for one stage 35 int stage_tex_coord_mask(int stage) { 36 return stage_mask_recur<0>(stage); 37 } 38 39 // mask of all bits relevant to one stage 40 int stage_mask(int stage) { 41 return stage_tex_coord_mask(stage) | 42 GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(stage); 43 } 44 45 // recursive helper for creating mask of with all bits set relevant to one 46 // texture coordinate index 47 template <int N> 48 int tex_coord_mask_recur(int texCoordIdx) { 49 return GrDrawTarget::StageTexCoordVertexLayoutBit(N, texCoordIdx) | 50 tex_coord_mask_recur<N+1>(texCoordIdx); 51 } 52 template<> 53 int tex_coord_mask_recur<GrDrawTarget::kMaxTexCoords>(int) { return 0; } 54 55 // mask of all bits relevant to one texture coordinate index 56 int tex_coord_idx_mask(int texCoordIdx) { 57 return tex_coord_mask_recur<0>(texCoordIdx); 58 } 59 60 bool check_layout(GrVertexLayout layout) { 61 // can only have 1 or 0 bits set for each stage. 62 for (int s = 0; s < GrDrawTarget::kNumStages; ++s) { 63 int stageBits = layout & stage_mask(s); 64 if (stageBits && !GrIsPow2(stageBits)) { 65 return false; 66 } 67 } 68 return true; 69 } 70 71 } //unnamed namespace 72 73 size_t GrDrawTarget::VertexSize(GrVertexLayout vertexLayout) { 74 GrAssert(check_layout(vertexLayout)); 75 76 size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 77 sizeof(GrGpuTextVertex) : 78 sizeof(GrPoint); 79 80 size_t size = vecSize; // position 81 for (int t = 0; t < kMaxTexCoords; ++t) { 82 if (tex_coord_idx_mask(t) & vertexLayout) { 83 size += vecSize; 84 } 85 } 86 if (vertexLayout & kColor_VertexLayoutBit) { 87 size += sizeof(GrColor); 88 } 89 return size; 90 } 91 92 int GrDrawTarget::VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout) { 93 GrAssert(check_layout(vertexLayout)); 94 if (StagePosAsTexCoordVertexLayoutBit(stage) & vertexLayout) { 95 return 0; 96 } 97 int tcIdx = VertexTexCoordsForStage(stage, vertexLayout); 98 if (tcIdx >= 0) { 99 100 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 101 sizeof(GrGpuTextVertex) : 102 sizeof(GrPoint); 103 int offset = vecSize; // position 104 // figure out how many tex coordinates are present and precede this one. 105 for (int t = 0; t < tcIdx; ++t) { 106 if (tex_coord_idx_mask(t) & vertexLayout) { 107 offset += vecSize; 108 } 109 } 110 return offset; 111 } 112 113 return -1; 114 } 115 116 int GrDrawTarget::VertexColorOffset(GrVertexLayout vertexLayout) { 117 GrAssert(check_layout(vertexLayout)); 118 119 if (vertexLayout & kColor_VertexLayoutBit) { 120 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 121 sizeof(GrGpuTextVertex) : 122 sizeof(GrPoint); 123 int offset = vecSize; // position 124 // figure out how many tex coordinates are present and precede this one. 125 for (int t = 0; t < kMaxTexCoords; ++t) { 126 if (tex_coord_idx_mask(t) & vertexLayout) { 127 offset += vecSize; 128 } 129 } 130 return offset; 131 } 132 return -1; 133 } 134 135 int GrDrawTarget::VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout, 136 int texCoordOffsetsByIdx[kMaxTexCoords], 137 int* colorOffset) { 138 GrAssert(check_layout(vertexLayout)); 139 140 GrAssert(NULL != texCoordOffsetsByIdx); 141 GrAssert(NULL != colorOffset); 142 143 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 144 sizeof(GrGpuTextVertex) : 145 sizeof(GrPoint); 146 int size = vecSize; // position 147 148 for (int t = 0; t < kMaxTexCoords; ++t) { 149 if (tex_coord_idx_mask(t) & vertexLayout) { 150 texCoordOffsetsByIdx[t] = size; 151 size += vecSize; 152 } else { 153 texCoordOffsetsByIdx[t] = -1; 154 } 155 } 156 if (kColor_VertexLayoutBit & vertexLayout) { 157 *colorOffset = size; 158 size += sizeof(GrColor); 159 } else { 160 *colorOffset = -1; 161 } 162 return size; 163 } 164 165 int GrDrawTarget::VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout, 166 int texCoordOffsetsByStage[kNumStages], 167 int* colorOffset) { 168 GrAssert(check_layout(vertexLayout)); 169 170 GrAssert(NULL != texCoordOffsetsByStage); 171 GrAssert(NULL != colorOffset); 172 173 int texCoordOffsetsByIdx[kMaxTexCoords]; 174 int size = VertexSizeAndOffsetsByIdx(vertexLayout, 175 texCoordOffsetsByIdx, 176 colorOffset); 177 for (int s = 0; s < kNumStages; ++s) { 178 int tcIdx; 179 if (StagePosAsTexCoordVertexLayoutBit(s) & vertexLayout) { 180 texCoordOffsetsByStage[s] = 0; 181 } else if ((tcIdx = VertexTexCoordsForStage(s, vertexLayout)) >= 0) { 182 texCoordOffsetsByStage[s] = texCoordOffsetsByIdx[tcIdx]; 183 } else { 184 texCoordOffsetsByStage[s] = -1; 185 } 186 } 187 return size; 188 } 189 190 bool GrDrawTarget::VertexUsesStage(int stage, GrVertexLayout vertexLayout) { 191 GrAssert(stage < kNumStages); 192 GrAssert(check_layout(vertexLayout)); 193 return !!(stage_mask(stage) & vertexLayout); 194 } 195 196 bool GrDrawTarget::VertexUsesTexCoordIdx(int coordIndex, 197 GrVertexLayout vertexLayout) { 198 GrAssert(coordIndex < kMaxTexCoords); 199 GrAssert(check_layout(vertexLayout)); 200 return !!(tex_coord_idx_mask(coordIndex) & vertexLayout); 201 } 202 203 int GrDrawTarget::VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout) { 204 GrAssert(stage < kNumStages); 205 GrAssert(check_layout(vertexLayout)); 206 int bit = vertexLayout & stage_tex_coord_mask(stage); 207 if (bit) { 208 // figure out which set of texture coordates is used 209 // bits are ordered T0S0, T0S1, T0S2, ..., T1S0, T1S1, ... 210 // and start at bit 0. 211 GR_STATIC_ASSERT(sizeof(GrVertexLayout) <= sizeof(uint32_t)); 212 return (32 - Gr_clz(bit) - 1) / kNumStages; 213 } 214 return -1; 215 } 216 217 void GrDrawTarget::VertexLayoutUnitTest() { 218 // not necessarily exhaustive 219 static bool run; 220 if (!run) { 221 run = true; 222 for (int s = 0; s < kNumStages; ++s) { 223 224 GrAssert(!VertexUsesStage(s, 0)); 225 GrAssert(-1 == VertexStageCoordOffset(s, 0)); 226 GrVertexLayout stageMask = 0; 227 for (int t = 0; t < kMaxTexCoords; ++t) { 228 stageMask |= StageTexCoordVertexLayoutBit(s,t); 229 } 230 GrAssert(1 == kMaxTexCoords || !check_layout(stageMask)); 231 GrAssert(stage_tex_coord_mask(s) == stageMask); 232 stageMask |= StagePosAsTexCoordVertexLayoutBit(s); 233 GrAssert(stage_mask(s) == stageMask); 234 GrAssert(!check_layout(stageMask)); 235 } 236 for (int t = 0; t < kMaxTexCoords; ++t) { 237 GrVertexLayout tcMask = 0; 238 GrAssert(!VertexUsesTexCoordIdx(t, 0)); 239 for (int s = 0; s < kNumStages; ++s) { 240 tcMask |= StageTexCoordVertexLayoutBit(s,t); 241 GrAssert(VertexUsesStage(s, tcMask)); 242 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask)); 243 GrAssert(VertexUsesTexCoordIdx(t, tcMask)); 244 GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask)); 245 GrAssert(t == VertexTexCoordsForStage(s, tcMask)); 246 for (int s2 = s + 1; s2 < kNumStages; ++s2) { 247 GrAssert(-1 == VertexStageCoordOffset(s2, tcMask)); 248 GrAssert(!VertexUsesStage(s2, tcMask)); 249 GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask)); 250 251 #if GR_DEBUG 252 GrVertexLayout posAsTex = tcMask | StagePosAsTexCoordVertexLayoutBit(s2); 253 #endif 254 GrAssert(0 == VertexStageCoordOffset(s2, posAsTex)); 255 GrAssert(VertexUsesStage(s2, posAsTex)); 256 GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex)); 257 GrAssert(-1 == VertexTexCoordsForStage(s2, posAsTex)); 258 } 259 #if GR_DEBUG 260 GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit; 261 #endif 262 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor)); 263 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor)); 264 } 265 GrAssert(tex_coord_idx_mask(t) == tcMask); 266 GrAssert(check_layout(tcMask)); 267 268 int stageOffsets[kNumStages]; 269 int colorOffset; 270 int size; 271 size = VertexSizeAndOffsetsByStage(tcMask, stageOffsets, &colorOffset); 272 GrAssert(2*sizeof(GrPoint) == size); 273 GrAssert(-1 == colorOffset); 274 for (int s = 0; s < kNumStages; ++s) { 275 GrAssert(VertexUsesStage(s, tcMask)); 276 GrAssert(sizeof(GrPoint) == stageOffsets[s]); 277 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask)); 278 } 279 } 280 } 281 } 282 283 //////////////////////////////////////////////////////////////////////////////// 284 285 GrDrawTarget::GrDrawTarget() { 286 #if GR_DEBUG 287 VertexLayoutUnitTest(); 288 #endif 289 fReservedGeometry.fLocked = false; 290 #if GR_DEBUG 291 fReservedGeometry.fVertexCount = ~0; 292 fReservedGeometry.fIndexCount = ~0; 293 #endif 294 fGeometrySrc.fVertexSrc = kReserved_GeometrySrcType; 295 fGeometrySrc.fIndexSrc = kReserved_GeometrySrcType; 296 } 297 298 void GrDrawTarget::setClip(const GrClip& clip) { 299 clipWillBeSet(clip); 300 fClip = clip; 301 } 302 303 const GrClip& GrDrawTarget::getClip() const { 304 return fClip; 305 } 306 307 void GrDrawTarget::setTexture(int stage, GrTexture* tex) { 308 GrAssert(stage >= 0 && stage < kNumStages); 309 fCurrDrawState.fTextures[stage] = tex; 310 } 311 312 const GrTexture* GrDrawTarget::getTexture(int stage) const { 313 GrAssert(stage >= 0 && stage < kNumStages); 314 return fCurrDrawState.fTextures[stage]; 315 } 316 317 GrTexture* GrDrawTarget::getTexture(int stage) { 318 GrAssert(stage >= 0 && stage < kNumStages); 319 return fCurrDrawState.fTextures[stage]; 320 } 321 322 void GrDrawTarget::setRenderTarget(GrRenderTarget* target) { 323 fCurrDrawState.fRenderTarget = target; 324 } 325 326 const GrRenderTarget* GrDrawTarget::getRenderTarget() const { 327 return fCurrDrawState.fRenderTarget; 328 } 329 330 GrRenderTarget* GrDrawTarget::getRenderTarget() { 331 return fCurrDrawState.fRenderTarget; 332 } 333 334 void GrDrawTarget::setViewMatrix(const GrMatrix& m) { 335 fCurrDrawState.fViewMatrix = m; 336 } 337 338 void GrDrawTarget::preConcatViewMatrix(const GrMatrix& matrix) { 339 fCurrDrawState.fViewMatrix.preConcat(matrix); 340 } 341 342 void GrDrawTarget::postConcatViewMatrix(const GrMatrix& matrix) { 343 fCurrDrawState.fViewMatrix.postConcat(matrix); 344 } 345 346 const GrMatrix& GrDrawTarget::getViewMatrix() const { 347 return fCurrDrawState.fViewMatrix; 348 } 349 350 bool GrDrawTarget::getViewInverse(GrMatrix* matrix) const { 351 // Mike: Can we cache this somewhere? 352 // Brian: Sure, do we use it often? 353 354 GrMatrix inverse; 355 if (fCurrDrawState.fViewMatrix.invert(&inverse)) { 356 if (matrix) { 357 *matrix = inverse; 358 } 359 return true; 360 } 361 return false; 362 } 363 364 void GrDrawTarget::setSamplerState(int stage, const GrSamplerState& state) { 365 GrAssert(stage >= 0 && stage < kNumStages); 366 fCurrDrawState.fSamplerStates[stage] = state; 367 } 368 369 void GrDrawTarget::enableState(uint32_t bits) { 370 fCurrDrawState.fFlagBits |= bits; 371 } 372 373 void GrDrawTarget::disableState(uint32_t bits) { 374 fCurrDrawState.fFlagBits &= ~(bits); 375 } 376 377 void GrDrawTarget::setBlendFunc(GrBlendCoeff srcCoeff, 378 GrBlendCoeff dstCoeff) { 379 fCurrDrawState.fSrcBlend = srcCoeff; 380 fCurrDrawState.fDstBlend = dstCoeff; 381 #if GR_DEBUG 382 switch (dstCoeff) { 383 case kDC_BlendCoeff: 384 case kIDC_BlendCoeff: 385 case kDA_BlendCoeff: 386 case kIDA_BlendCoeff: 387 GrPrintf("Unexpected dst blend coeff. Won't work correctly with" 388 "coverage stages.\n"); 389 break; 390 default: 391 break; 392 } 393 switch (srcCoeff) { 394 case kSC_BlendCoeff: 395 case kISC_BlendCoeff: 396 case kSA_BlendCoeff: 397 case kISA_BlendCoeff: 398 GrPrintf("Unexpected src blend coeff. Won't work correctly with" 399 "coverage stages.\n"); 400 break; 401 default: 402 break; 403 } 404 #endif 405 } 406 407 void GrDrawTarget::setColor(GrColor c) { 408 fCurrDrawState.fColor = c; 409 } 410 411 void GrDrawTarget::setColorFilter(GrColor c, SkXfermode::Mode mode) { 412 fCurrDrawState.fColorFilterColor = c; 413 fCurrDrawState.fColorFilterXfermode = mode; 414 } 415 416 void GrDrawTarget::setAlpha(uint8_t a) { 417 this->setColor((a << 24) | (a << 16) | (a << 8) | a); 418 } 419 420 void GrDrawTarget::saveCurrentDrawState(SavedDrawState* state) const { 421 state->fState = fCurrDrawState; 422 } 423 424 void GrDrawTarget::restoreDrawState(const SavedDrawState& state) { 425 fCurrDrawState = state.fState; 426 } 427 428 void GrDrawTarget::copyDrawState(const GrDrawTarget& srcTarget) { 429 fCurrDrawState = srcTarget.fCurrDrawState; 430 } 431 432 433 bool GrDrawTarget::reserveAndLockGeometry(GrVertexLayout vertexLayout, 434 uint32_t vertexCount, 435 uint32_t indexCount, 436 void** vertices, 437 void** indices) { 438 GrAssert(!fReservedGeometry.fLocked); 439 fReservedGeometry.fVertexCount = vertexCount; 440 fReservedGeometry.fIndexCount = indexCount; 441 442 fReservedGeometry.fLocked = this->onAcquireGeometry(vertexLayout, 443 vertices, 444 indices); 445 if (fReservedGeometry.fLocked) { 446 if (vertexCount) { 447 fGeometrySrc.fVertexSrc = kReserved_GeometrySrcType; 448 fGeometrySrc.fVertexLayout = vertexLayout; 449 } else if (NULL != vertices) { 450 *vertices = NULL; 451 } 452 if (indexCount) { 453 fGeometrySrc.fIndexSrc = kReserved_GeometrySrcType; 454 } else if (NULL != indices) { 455 *indices = NULL; 456 } 457 } 458 return fReservedGeometry.fLocked; 459 } 460 461 bool GrDrawTarget::geometryHints(GrVertexLayout vertexLayout, 462 int32_t* vertexCount, 463 int32_t* indexCount) const { 464 GrAssert(!fReservedGeometry.fLocked); 465 if (NULL != vertexCount) { 466 *vertexCount = -1; 467 } 468 if (NULL != indexCount) { 469 *indexCount = -1; 470 } 471 return false; 472 } 473 474 void GrDrawTarget::releaseReservedGeometry() { 475 GrAssert(fReservedGeometry.fLocked); 476 this->onReleaseGeometry(); 477 fReservedGeometry.fLocked = false; 478 } 479 480 void GrDrawTarget::setVertexSourceToArray(GrVertexLayout vertexLayout, 481 const void* vertexArray, 482 int vertexCount) { 483 fGeometrySrc.fVertexSrc = kArray_GeometrySrcType; 484 fGeometrySrc.fVertexLayout = vertexLayout; 485 this->onSetVertexSourceToArray(vertexArray, vertexCount); 486 } 487 488 void GrDrawTarget::setIndexSourceToArray(const void* indexArray, 489 int indexCount) { 490 fGeometrySrc.fIndexSrc = kArray_GeometrySrcType; 491 this->onSetIndexSourceToArray(indexArray, indexCount); 492 } 493 494 void GrDrawTarget::setVertexSourceToBuffer(GrVertexLayout vertexLayout, 495 const GrVertexBuffer* buffer) { 496 fGeometrySrc.fVertexSrc = kBuffer_GeometrySrcType; 497 fGeometrySrc.fVertexBuffer = buffer; 498 fGeometrySrc.fVertexLayout = vertexLayout; 499 } 500 501 void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) { 502 fGeometrySrc.fIndexSrc = kBuffer_GeometrySrcType; 503 fGeometrySrc.fIndexBuffer = buffer; 504 } 505 506 /////////////////////////////////////////////////////////////////////////////// 507 508 bool GrDrawTarget::canDisableBlend() const { 509 // If we compute a coverage value (using edge AA or a coverage stage) then 510 // we can't force blending off. 511 if (fCurrDrawState.fEdgeAANumEdges > 0) { 512 return false; 513 } 514 for (int s = fCurrDrawState.fFirstCoverageStage; s < kNumStages; ++s) { 515 if (this->isStageEnabled(s)) { 516 return false; 517 } 518 } 519 520 if ((kOne_BlendCoeff == fCurrDrawState.fSrcBlend) && 521 (kZero_BlendCoeff == fCurrDrawState.fDstBlend)) { 522 return true; 523 } 524 525 // If we have vertex color without alpha then we can't force blend off 526 if ((fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) || 527 0xff != GrColorUnpackA(fCurrDrawState.fColor)) { 528 return false; 529 } 530 531 // If the src coef will always be 1... 532 if (kSA_BlendCoeff != fCurrDrawState.fSrcBlend && 533 kOne_BlendCoeff != fCurrDrawState.fSrcBlend) { 534 return false; 535 } 536 537 // ...and the dst coef is always 0... 538 if (kISA_BlendCoeff != fCurrDrawState.fDstBlend && 539 kZero_BlendCoeff != fCurrDrawState.fDstBlend) { 540 return false; 541 } 542 543 // ...and there isn't a texture stage with an alpha channel... 544 for (int s = 0; s < fCurrDrawState.fFirstCoverageStage; ++s) { 545 if (this->isStageEnabled(s)) { 546 GrAssert(NULL != fCurrDrawState.fTextures[s]); 547 548 GrPixelConfig config = fCurrDrawState.fTextures[s]->config(); 549 550 if (!GrPixelConfigIsOpaque(config)) { 551 return false; 552 } 553 } 554 } 555 556 // ...and there isn't an interesting color filter... 557 // TODO: Consider being more aggressive with regards to disabling 558 // blending when a color filter is used. 559 if (SkXfermode::kDst_Mode != fCurrDrawState.fColorFilterXfermode) { 560 return false; 561 } 562 563 // ...then we disable blend. 564 return true; 565 } 566 567 /////////////////////////////////////////////////////////////////////////////// 568 void GrDrawTarget::setEdgeAAData(const Edge* edges, int numEdges) { 569 GrAssert(numEdges <= kMaxEdges); 570 memcpy(fCurrDrawState.fEdgeAAEdges, edges, numEdges * sizeof(Edge)); 571 fCurrDrawState.fEdgeAANumEdges = numEdges; 572 } 573 574 575 /////////////////////////////////////////////////////////////////////////////// 576 void GrDrawTarget::drawRect(const GrRect& rect, 577 const GrMatrix* matrix, 578 StageBitfield stageEnableBitfield, 579 const GrRect* srcRects[], 580 const GrMatrix* srcMatrices[]) { 581 GrVertexLayout layout = GetRectVertexLayout(stageEnableBitfield, srcRects); 582 583 AutoReleaseGeometry geo(this, layout, 4, 0); 584 585 SetRectVertices(rect, matrix, srcRects, 586 srcMatrices, layout, geo.vertices()); 587 588 drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4); 589 } 590 591 GrVertexLayout GrDrawTarget::GetRectVertexLayout(StageBitfield stageEnableBitfield, 592 const GrRect* srcRects[]) { 593 GrVertexLayout layout = 0; 594 595 for (int i = 0; i < kNumStages; ++i) { 596 int numTC = 0; 597 if (stageEnableBitfield & (1 << i)) { 598 if (NULL != srcRects && NULL != srcRects[i]) { 599 layout |= StageTexCoordVertexLayoutBit(i, numTC); 600 ++numTC; 601 } else { 602 layout |= StagePosAsTexCoordVertexLayoutBit(i); 603 } 604 } 605 } 606 return layout; 607 } 608 void GrDrawTarget::SetRectVertices(const GrRect& rect, 609 const GrMatrix* matrix, 610 const GrRect* srcRects[], 611 const GrMatrix* srcMatrices[], 612 GrVertexLayout layout, 613 void* vertices) { 614 #if GR_DEBUG 615 // check that the layout and srcRects agree 616 for (int i = 0; i < kNumStages; ++i) { 617 if (VertexTexCoordsForStage(i, layout) >= 0) { 618 GR_DEBUGASSERT(NULL != srcRects && NULL != srcRects[i]); 619 } else { 620 GR_DEBUGASSERT(NULL == srcRects || NULL == srcRects[i]); 621 } 622 } 623 #endif 624 625 int stageOffsets[kNumStages]; 626 int colorOffset; 627 int vsize = VertexSizeAndOffsetsByStage(layout, stageOffsets, &colorOffset); 628 GrAssert(-1 == colorOffset); 629 630 GrTCast<GrPoint*>(vertices)->setRectFan(rect.fLeft, rect.fTop, 631 rect.fRight, rect.fBottom, 632 vsize); 633 if (NULL != matrix) { 634 matrix->mapPointsWithStride(GrTCast<GrPoint*>(vertices), vsize, 4); 635 } 636 637 for (int i = 0; i < kNumStages; ++i) { 638 if (stageOffsets[i] > 0) { 639 GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(vertices) + 640 stageOffsets[i]); 641 coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop, 642 srcRects[i]->fRight, srcRects[i]->fBottom, 643 vsize); 644 if (NULL != srcMatrices && NULL != srcMatrices[i]) { 645 srcMatrices[i]->mapPointsWithStride(coords, vsize, 4); 646 } 647 } 648 } 649 } 650 651 /////////////////////////////////////////////////////////////////////////////// 652 GrDrawTarget::AutoStateRestore::AutoStateRestore() { 653 fDrawTarget = NULL; 654 } 655 656 GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target) { 657 fDrawTarget = target; 658 if (NULL != fDrawTarget) { 659 fDrawTarget->saveCurrentDrawState(&fDrawState); 660 } 661 } 662 663 GrDrawTarget::AutoStateRestore::~AutoStateRestore() { 664 if (NULL != fDrawTarget) { 665 fDrawTarget->restoreDrawState(fDrawState); 666 } 667 } 668 669 void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target) { 670 if (target != fDrawTarget) { 671 if (NULL != fDrawTarget) { 672 fDrawTarget->restoreDrawState(fDrawState); 673 } 674 if (NULL != target) { 675 fDrawTarget->saveCurrentDrawState(&fDrawState); 676 } 677 fDrawTarget = target; 678 } 679 } 680