GrDrawTarget.cpp revision c43649962221c348d656d425a3fa9b29c78231d4
1 2/* 3 * Copyright 2010 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 11#include "GrDrawTarget.h" 12#include "GrGpuVertex.h" 13#include "GrTexture.h" 14#include "GrVertexBuffer.h" 15#include "GrIndexBuffer.h" 16 17namespace { 18 19// recursive helper for creating mask with all the tex coord bits set for 20// one stage 21template <int N> 22int stage_mask_recur(int stage) { 23 return GrDrawTarget::StageTexCoordVertexLayoutBit(stage, N) | 24 stage_mask_recur<N+1>(stage); 25} 26template<> 27int stage_mask_recur<GrDrawState::kNumStages>(int) { return 0; } 28 29// mask of all tex coord indices for one stage 30int stage_tex_coord_mask(int stage) { 31 return stage_mask_recur<0>(stage); 32} 33 34// mask of all bits relevant to one stage 35int stage_mask(int stage) { 36 return stage_tex_coord_mask(stage) | 37 GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(stage); 38} 39 40// recursive helper for creating mask of with all bits set relevant to one 41// texture coordinate index 42template <int N> 43int tex_coord_mask_recur(int texCoordIdx) { 44 return GrDrawTarget::StageTexCoordVertexLayoutBit(N, texCoordIdx) | 45 tex_coord_mask_recur<N+1>(texCoordIdx); 46} 47template<> 48int tex_coord_mask_recur<GrDrawState::kMaxTexCoords>(int) { return 0; } 49 50// mask of all bits relevant to one texture coordinate index 51int tex_coord_idx_mask(int texCoordIdx) { 52 return tex_coord_mask_recur<0>(texCoordIdx); 53} 54 55bool check_layout(GrVertexLayout layout) { 56 // can only have 1 or 0 bits set for each stage. 57 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 58 int stageBits = layout & stage_mask(s); 59 if (stageBits && !GrIsPow2(stageBits)) { 60 return false; 61 } 62 } 63 return true; 64} 65 66int num_tex_coords(GrVertexLayout layout) { 67 int cnt = 0; 68 // figure out how many tex coordinates are present 69 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { 70 if (tex_coord_idx_mask(t) & layout) { 71 ++cnt; 72 } 73 } 74 return cnt; 75} 76 77} //unnamed namespace 78 79size_t GrDrawTarget::VertexSize(GrVertexLayout vertexLayout) { 80 GrAssert(check_layout(vertexLayout)); 81 82 size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 83 sizeof(GrGpuTextVertex) : 84 sizeof(GrPoint); 85 86 size_t size = vecSize; // position 87 size += num_tex_coords(vertexLayout) * vecSize; 88 if (vertexLayout & kColor_VertexLayoutBit) { 89 size += sizeof(GrColor); 90 } 91 if (vertexLayout & kCoverage_VertexLayoutBit) { 92 size += sizeof(GrColor); 93 } 94 if (vertexLayout & kEdge_VertexLayoutBit) { 95 size += 4 * sizeof(GrScalar); 96 } 97 return size; 98} 99 100//////////////////////////////////////////////////////////////////////////////// 101 102/** 103 * Functions for computing offsets of various components from the layout 104 * bitfield. 105 * 106 * Order of vertex components: 107 * Position 108 * Tex Coord 0 109 * ... 110 * Tex Coord GrDrawState::kMaxTexCoords-1 111 * Color 112 * Coverage 113 */ 114 115int GrDrawTarget::VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout) { 116 GrAssert(check_layout(vertexLayout)); 117 if (StagePosAsTexCoordVertexLayoutBit(stage) & vertexLayout) { 118 return 0; 119 } 120 int tcIdx = VertexTexCoordsForStage(stage, vertexLayout); 121 if (tcIdx >= 0) { 122 123 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 124 sizeof(GrGpuTextVertex) : 125 sizeof(GrPoint); 126 int offset = vecSize; // position 127 // figure out how many tex coordinates are present and precede this one. 128 for (int t = 0; t < tcIdx; ++t) { 129 if (tex_coord_idx_mask(t) & vertexLayout) { 130 offset += vecSize; 131 } 132 } 133 return offset; 134 } 135 136 return -1; 137} 138 139int GrDrawTarget::VertexColorOffset(GrVertexLayout vertexLayout) { 140 GrAssert(check_layout(vertexLayout)); 141 142 if (vertexLayout & kColor_VertexLayoutBit) { 143 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 144 sizeof(GrGpuTextVertex) : 145 sizeof(GrPoint); 146 return vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos 147 } 148 return -1; 149} 150 151int GrDrawTarget::VertexCoverageOffset(GrVertexLayout vertexLayout) { 152 GrAssert(check_layout(vertexLayout)); 153 154 if (vertexLayout & kCoverage_VertexLayoutBit) { 155 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 156 sizeof(GrGpuTextVertex) : 157 sizeof(GrPoint); 158 159 int offset = vecSize * (num_tex_coords(vertexLayout) + 1); 160 if (vertexLayout & kColor_VertexLayoutBit) { 161 offset += sizeof(GrColor); 162 } 163 return offset; 164 } 165 return -1; 166} 167 168int GrDrawTarget::VertexEdgeOffset(GrVertexLayout vertexLayout) { 169 GrAssert(check_layout(vertexLayout)); 170 171 // edge pts are after the pos, tex coords, and color 172 if (vertexLayout & kEdge_VertexLayoutBit) { 173 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 174 sizeof(GrGpuTextVertex) : 175 sizeof(GrPoint); 176 int offset = vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos 177 if (vertexLayout & kColor_VertexLayoutBit) { 178 offset += sizeof(GrColor); 179 } 180 if (vertexLayout & kCoverage_VertexLayoutBit) { 181 offset += sizeof(GrColor); 182 } 183 return offset; 184 } 185 return -1; 186} 187 188int GrDrawTarget::VertexSizeAndOffsetsByIdx( 189 GrVertexLayout vertexLayout, 190 int texCoordOffsetsByIdx[GrDrawState::kMaxTexCoords], 191 int* colorOffset, 192 int* coverageOffset, 193 int* edgeOffset) { 194 GrAssert(check_layout(vertexLayout)); 195 196 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 197 sizeof(GrGpuTextVertex) : 198 sizeof(GrPoint); 199 int size = vecSize; // position 200 201 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { 202 if (tex_coord_idx_mask(t) & vertexLayout) { 203 if (NULL != texCoordOffsetsByIdx) { 204 texCoordOffsetsByIdx[t] = size; 205 } 206 size += vecSize; 207 } else { 208 if (NULL != texCoordOffsetsByIdx) { 209 texCoordOffsetsByIdx[t] = -1; 210 } 211 } 212 } 213 if (kColor_VertexLayoutBit & vertexLayout) { 214 if (NULL != colorOffset) { 215 *colorOffset = size; 216 } 217 size += sizeof(GrColor); 218 } else { 219 if (NULL != colorOffset) { 220 *colorOffset = -1; 221 } 222 } 223 if (kCoverage_VertexLayoutBit & vertexLayout) { 224 if (NULL != coverageOffset) { 225 *coverageOffset = size; 226 } 227 size += sizeof(GrColor); 228 } else { 229 if (NULL != coverageOffset) { 230 *coverageOffset = -1; 231 } 232 } 233 if (kEdge_VertexLayoutBit & vertexLayout) { 234 if (NULL != edgeOffset) { 235 *edgeOffset = size; 236 } 237 size += 4 * sizeof(GrScalar); 238 } else { 239 if (NULL != edgeOffset) { 240 *edgeOffset = -1; 241 } 242 } 243 return size; 244} 245 246int GrDrawTarget::VertexSizeAndOffsetsByStage( 247 GrVertexLayout vertexLayout, 248 int texCoordOffsetsByStage[GrDrawState::kNumStages], 249 int* colorOffset, 250 int* coverageOffset, 251 int* edgeOffset) { 252 GrAssert(check_layout(vertexLayout)); 253 254 int texCoordOffsetsByIdx[GrDrawState::kMaxTexCoords]; 255 int size = VertexSizeAndOffsetsByIdx(vertexLayout, 256 (NULL == texCoordOffsetsByStage) ? 257 NULL : 258 texCoordOffsetsByIdx, 259 colorOffset, 260 coverageOffset, 261 edgeOffset); 262 if (NULL != texCoordOffsetsByStage) { 263 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 264 int tcIdx; 265 if (StagePosAsTexCoordVertexLayoutBit(s) & vertexLayout) { 266 texCoordOffsetsByStage[s] = 0; 267 } else if ((tcIdx = VertexTexCoordsForStage(s, vertexLayout)) >= 0) { 268 texCoordOffsetsByStage[s] = texCoordOffsetsByIdx[tcIdx]; 269 } else { 270 texCoordOffsetsByStage[s] = -1; 271 } 272 } 273 } 274 return size; 275} 276 277//////////////////////////////////////////////////////////////////////////////// 278 279bool GrDrawTarget::VertexUsesStage(int stage, GrVertexLayout vertexLayout) { 280 GrAssert(stage < GrDrawState::kNumStages); 281 GrAssert(check_layout(vertexLayout)); 282 return !!(stage_mask(stage) & vertexLayout); 283} 284 285bool GrDrawTarget::VertexUsesTexCoordIdx(int coordIndex, 286 GrVertexLayout vertexLayout) { 287 GrAssert(coordIndex < GrDrawState::kMaxTexCoords); 288 GrAssert(check_layout(vertexLayout)); 289 return !!(tex_coord_idx_mask(coordIndex) & vertexLayout); 290} 291 292int GrDrawTarget::VertexTexCoordsForStage(int stage, 293 GrVertexLayout vertexLayout) { 294 GrAssert(stage < GrDrawState::kNumStages); 295 GrAssert(check_layout(vertexLayout)); 296 int bit = vertexLayout & stage_tex_coord_mask(stage); 297 if (bit) { 298 // figure out which set of texture coordates is used 299 // bits are ordered T0S0, T0S1, T0S2, ..., T1S0, T1S1, ... 300 // and start at bit 0. 301 GR_STATIC_ASSERT(sizeof(GrVertexLayout) <= sizeof(uint32_t)); 302 return (32 - Gr_clz(bit) - 1) / GrDrawState::kNumStages; 303 } 304 return -1; 305} 306 307//////////////////////////////////////////////////////////////////////////////// 308 309void GrDrawTarget::VertexLayoutUnitTest() { 310 // not necessarily exhaustive 311 static bool run; 312 if (!run) { 313 run = true; 314 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 315 316 GrAssert(!VertexUsesStage(s, 0)); 317 GrAssert(-1 == VertexStageCoordOffset(s, 0)); 318 GrVertexLayout stageMask = 0; 319 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { 320 stageMask |= StageTexCoordVertexLayoutBit(s,t); 321 } 322 GrAssert(1 == GrDrawState::kMaxTexCoords || 323 !check_layout(stageMask)); 324 GrAssert(stage_tex_coord_mask(s) == stageMask); 325 stageMask |= StagePosAsTexCoordVertexLayoutBit(s); 326 GrAssert(stage_mask(s) == stageMask); 327 GrAssert(!check_layout(stageMask)); 328 } 329 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { 330 GrVertexLayout tcMask = 0; 331 GrAssert(!VertexUsesTexCoordIdx(t, 0)); 332 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 333 tcMask |= StageTexCoordVertexLayoutBit(s,t); 334 GrAssert(VertexUsesStage(s, tcMask)); 335 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask)); 336 GrAssert(VertexUsesTexCoordIdx(t, tcMask)); 337 GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask)); 338 GrAssert(t == VertexTexCoordsForStage(s, tcMask)); 339 for (int s2 = s + 1; s2 < GrDrawState::kNumStages; ++s2) { 340 GrAssert(-1 == VertexStageCoordOffset(s2, tcMask)); 341 GrAssert(!VertexUsesStage(s2, tcMask)); 342 GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask)); 343 344 #if GR_DEBUG 345 GrVertexLayout posAsTex = tcMask | StagePosAsTexCoordVertexLayoutBit(s2); 346 #endif 347 GrAssert(0 == VertexStageCoordOffset(s2, posAsTex)); 348 GrAssert(VertexUsesStage(s2, posAsTex)); 349 GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex)); 350 GrAssert(-1 == VertexTexCoordsForStage(s2, posAsTex)); 351 GrAssert(-1 == VertexEdgeOffset(posAsTex)); 352 } 353 GrAssert(-1 == VertexEdgeOffset(tcMask)); 354 GrAssert(-1 == VertexColorOffset(tcMask)); 355 GrAssert(-1 == VertexCoverageOffset(tcMask)); 356 #if GR_DEBUG 357 GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit; 358 #endif 359 GrAssert(-1 == VertexCoverageOffset(withColor)); 360 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor)); 361 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor)); 362 #if GR_DEBUG 363 GrVertexLayout withEdge = tcMask | kEdge_VertexLayoutBit; 364 #endif 365 GrAssert(-1 == VertexColorOffset(withEdge)); 366 GrAssert(2*sizeof(GrPoint) == VertexEdgeOffset(withEdge)); 367 GrAssert(4*sizeof(GrPoint) == VertexSize(withEdge)); 368 #if GR_DEBUG 369 GrVertexLayout withColorAndEdge = withColor | kEdge_VertexLayoutBit; 370 #endif 371 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColorAndEdge)); 372 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexEdgeOffset(withColorAndEdge)); 373 GrAssert(4*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColorAndEdge)); 374 #if GR_DEBUG 375 GrVertexLayout withCoverage = tcMask | kCoverage_VertexLayoutBit; 376 #endif 377 GrAssert(-1 == VertexColorOffset(withCoverage)); 378 GrAssert(2*sizeof(GrPoint) == VertexCoverageOffset(withCoverage)); 379 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withCoverage)); 380 #if GR_DEBUG 381 GrVertexLayout withCoverageAndColor = tcMask | kCoverage_VertexLayoutBit | 382 kColor_VertexLayoutBit; 383 #endif 384 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withCoverageAndColor)); 385 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexCoverageOffset(withCoverageAndColor)); 386 GrAssert(2*sizeof(GrPoint) + 2 * sizeof(GrColor) == VertexSize(withCoverageAndColor)); 387 } 388 GrAssert(tex_coord_idx_mask(t) == tcMask); 389 GrAssert(check_layout(tcMask)); 390 391 int stageOffsets[GrDrawState::kNumStages]; 392 int colorOffset; 393 int edgeOffset; 394 int coverageOffset; 395 int size; 396 size = VertexSizeAndOffsetsByStage(tcMask, 397 stageOffsets, &colorOffset, 398 &coverageOffset, &edgeOffset); 399 GrAssert(2*sizeof(GrPoint) == size); 400 GrAssert(-1 == colorOffset); 401 GrAssert(-1 == coverageOffset); 402 GrAssert(-1 == edgeOffset); 403 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 404 GrAssert(VertexUsesStage(s, tcMask)); 405 GrAssert(sizeof(GrPoint) == stageOffsets[s]); 406 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask)); 407 } 408 } 409 } 410} 411 412//////////////////////////////////////////////////////////////////////////////// 413 414#define DEBUG_INVAL_BUFFER 0xdeadcafe 415#define DEBUG_INVAL_START_IDX -1 416 417GrDrawTarget::GrDrawTarget() { 418#if GR_DEBUG 419 VertexLayoutUnitTest(); 420#endif 421 GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back(); 422#if GR_DEBUG 423 geoSrc.fVertexCount = DEBUG_INVAL_START_IDX; 424 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; 425 geoSrc.fIndexCount = DEBUG_INVAL_START_IDX; 426 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; 427#endif 428 geoSrc.fVertexSrc = kNone_GeometrySrcType; 429 geoSrc.fIndexSrc = kNone_GeometrySrcType; 430} 431 432GrDrawTarget::~GrDrawTarget() { 433 GrAssert(1 == fGeoSrcStateStack.count()); 434 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 435 GrAssert(kNone_GeometrySrcType == geoSrc.fIndexSrc); 436 GrAssert(kNone_GeometrySrcType == geoSrc.fVertexSrc); 437} 438 439void GrDrawTarget::releaseGeometry() { 440 int popCnt = fGeoSrcStateStack.count() - 1; 441 while (popCnt) { 442 this->popGeometrySource(); 443 --popCnt; 444 } 445 this->resetVertexSource(); 446 this->resetIndexSource(); 447} 448 449void GrDrawTarget::setClip(const GrClip& clip) { 450 clipWillBeSet(clip); 451 fClip = clip; 452} 453 454const GrClip& GrDrawTarget::getClip() const { 455 return fClip; 456} 457 458void GrDrawTarget::setTexture(int stage, GrTexture* tex) { 459 GrAssert(stage >= 0 && stage < GrDrawState::kNumStages); 460 fCurrDrawState.fTextures[stage] = tex; 461} 462 463const GrTexture* GrDrawTarget::getTexture(int stage) const { 464 GrAssert(stage >= 0 && stage < GrDrawState::kNumStages); 465 return fCurrDrawState.fTextures[stage]; 466} 467 468GrTexture* GrDrawTarget::getTexture(int stage) { 469 GrAssert(stage >= 0 && stage < GrDrawState::kNumStages); 470 return fCurrDrawState.fTextures[stage]; 471} 472 473void GrDrawTarget::setRenderTarget(GrRenderTarget* target) { 474 fCurrDrawState.fRenderTarget = target; 475} 476 477const GrRenderTarget* GrDrawTarget::getRenderTarget() const { 478 return fCurrDrawState.fRenderTarget; 479} 480 481GrRenderTarget* GrDrawTarget::getRenderTarget() { 482 return fCurrDrawState.fRenderTarget; 483} 484 485void GrDrawTarget::setViewMatrix(const GrMatrix& m) { 486 fCurrDrawState.fViewMatrix = m; 487} 488 489void GrDrawTarget::preConcatViewMatrix(const GrMatrix& matrix) { 490 fCurrDrawState.fViewMatrix.preConcat(matrix); 491} 492 493void GrDrawTarget::postConcatViewMatrix(const GrMatrix& matrix) { 494 fCurrDrawState.fViewMatrix.postConcat(matrix); 495} 496 497const GrMatrix& GrDrawTarget::getViewMatrix() const { 498 return fCurrDrawState.fViewMatrix; 499} 500 501bool GrDrawTarget::getViewInverse(GrMatrix* matrix) const { 502 // Mike: Can we cache this somewhere? 503 // Brian: Sure, do we use it often? 504 505 GrMatrix inverse; 506 if (fCurrDrawState.fViewMatrix.invert(&inverse)) { 507 if (matrix) { 508 *matrix = inverse; 509 } 510 return true; 511 } 512 return false; 513} 514 515void GrDrawTarget::setSamplerState(int stage, const GrSamplerState& state) { 516 GrAssert(stage >= 0 && stage < GrDrawState::kNumStages); 517 fCurrDrawState.fSamplerStates[stage] = state; 518} 519 520void GrDrawTarget::enableState(uint32_t bits) { 521 fCurrDrawState.fFlagBits |= bits; 522} 523 524void GrDrawTarget::disableState(uint32_t bits) { 525 fCurrDrawState.fFlagBits &= ~(bits); 526} 527 528void GrDrawTarget::setBlendFunc(GrBlendCoeff srcCoeff, 529 GrBlendCoeff dstCoeff) { 530 fCurrDrawState.fSrcBlend = srcCoeff; 531 fCurrDrawState.fDstBlend = dstCoeff; 532#if GR_DEBUG 533 switch (dstCoeff) { 534 case kDC_BlendCoeff: 535 case kIDC_BlendCoeff: 536 case kDA_BlendCoeff: 537 case kIDA_BlendCoeff: 538 GrPrintf("Unexpected dst blend coeff. Won't work correctly with" 539 "coverage stages.\n"); 540 break; 541 default: 542 break; 543 } 544 switch (srcCoeff) { 545 case kSC_BlendCoeff: 546 case kISC_BlendCoeff: 547 case kSA_BlendCoeff: 548 case kISA_BlendCoeff: 549 GrPrintf("Unexpected src blend coeff. Won't work correctly with" 550 "coverage stages.\n"); 551 break; 552 default: 553 break; 554 } 555#endif 556} 557 558void GrDrawTarget::setColor(GrColor c) { 559 fCurrDrawState.fColor = c; 560} 561 562void GrDrawTarget::setColorFilter(GrColor c, SkXfermode::Mode mode) { 563 fCurrDrawState.fColorFilterColor = c; 564 fCurrDrawState.fColorFilterXfermode = mode; 565} 566 567void GrDrawTarget::setAlpha(uint8_t a) { 568 this->setColor((a << 24) | (a << 16) | (a << 8) | a); 569} 570 571void GrDrawTarget::saveCurrentDrawState(SavedDrawState* state) const { 572 state->fState = fCurrDrawState; 573} 574 575void GrDrawTarget::restoreDrawState(const SavedDrawState& state) { 576 fCurrDrawState = state.fState; 577} 578 579void GrDrawTarget::copyDrawState(const GrDrawTarget& srcTarget) { 580 fCurrDrawState = srcTarget.fCurrDrawState; 581} 582 583bool GrDrawTarget::reserveVertexSpace(GrVertexLayout vertexLayout, 584 int vertexCount, 585 void** vertices) { 586 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 587 bool acquired = false; 588 if (vertexCount > 0) { 589 GrAssert(NULL != vertices); 590 this->releasePreviousVertexSource(); 591 geoSrc.fVertexSrc = kNone_GeometrySrcType; 592 593 acquired = this->onReserveVertexSpace(vertexLayout, 594 vertexCount, 595 vertices); 596 } 597 if (acquired) { 598 geoSrc.fVertexSrc = kReserved_GeometrySrcType; 599 geoSrc.fVertexCount = vertexCount; 600 geoSrc.fVertexLayout = vertexLayout; 601 } else if (NULL != vertices) { 602 *vertices = NULL; 603 } 604 return acquired; 605} 606 607bool GrDrawTarget::reserveIndexSpace(int indexCount, 608 void** indices) { 609 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 610 bool acquired = false; 611 if (indexCount > 0) { 612 GrAssert(NULL != indices); 613 this->releasePreviousIndexSource(); 614 geoSrc.fIndexSrc = kNone_GeometrySrcType; 615 616 acquired = this->onReserveIndexSpace(indexCount, indices); 617 } 618 if (acquired) { 619 geoSrc.fIndexSrc = kReserved_GeometrySrcType; 620 geoSrc.fIndexCount = indexCount; 621 } else if (NULL != indices) { 622 *indices = NULL; 623 } 624 return acquired; 625 626} 627 628bool GrDrawTarget::geometryHints(GrVertexLayout vertexLayout, 629 int32_t* vertexCount, 630 int32_t* indexCount) const { 631 if (NULL != vertexCount) { 632 *vertexCount = -1; 633 } 634 if (NULL != indexCount) { 635 *indexCount = -1; 636 } 637 return false; 638} 639 640void GrDrawTarget::releasePreviousVertexSource() { 641 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 642 switch (geoSrc.fVertexSrc) { 643 case kNone_GeometrySrcType: 644 break; 645 case kArray_GeometrySrcType: 646 this->releaseVertexArray(); 647 break; 648 case kReserved_GeometrySrcType: 649 this->releaseReservedVertexSpace(); 650 break; 651 case kBuffer_GeometrySrcType: 652 geoSrc.fVertexBuffer->unref(); 653#if GR_DEBUG 654 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; 655#endif 656 break; 657 default: 658 GrCrash("Unknown Vertex Source Type."); 659 break; 660 } 661} 662 663void GrDrawTarget::releasePreviousIndexSource() { 664 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 665 switch (geoSrc.fIndexSrc) { 666 case kNone_GeometrySrcType: // these two don't require 667 break; 668 case kArray_GeometrySrcType: 669 this->releaseIndexArray(); 670 break; 671 case kReserved_GeometrySrcType: 672 this->releaseReservedIndexSpace(); 673 break; 674 case kBuffer_GeometrySrcType: 675 geoSrc.fIndexBuffer->unref(); 676#if GR_DEBUG 677 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; 678#endif 679 break; 680 default: 681 GrCrash("Unknown Index Source Type."); 682 break; 683 } 684} 685 686void GrDrawTarget::setVertexSourceToArray(GrVertexLayout vertexLayout, 687 const void* vertexArray, 688 int vertexCount) { 689 this->releasePreviousVertexSource(); 690 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 691 geoSrc.fVertexSrc = kArray_GeometrySrcType; 692 geoSrc.fVertexLayout = vertexLayout; 693 geoSrc.fVertexCount = vertexCount; 694 this->onSetVertexSourceToArray(vertexArray, vertexCount); 695} 696 697void GrDrawTarget::setIndexSourceToArray(const void* indexArray, 698 int indexCount) { 699 this->releasePreviousIndexSource(); 700 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 701 geoSrc.fIndexSrc = kArray_GeometrySrcType; 702 geoSrc.fIndexCount = indexCount; 703 this->onSetIndexSourceToArray(indexArray, indexCount); 704} 705 706void GrDrawTarget::setVertexSourceToBuffer(GrVertexLayout vertexLayout, 707 const GrVertexBuffer* buffer) { 708 this->releasePreviousVertexSource(); 709 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 710 geoSrc.fVertexSrc = kBuffer_GeometrySrcType; 711 geoSrc.fVertexBuffer = buffer; 712 buffer->ref(); 713 geoSrc.fVertexLayout = vertexLayout; 714} 715 716void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) { 717 this->releasePreviousIndexSource(); 718 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 719 geoSrc.fIndexSrc = kBuffer_GeometrySrcType; 720 geoSrc.fIndexBuffer = buffer; 721 buffer->ref(); 722} 723 724void GrDrawTarget::resetVertexSource() { 725 this->releasePreviousVertexSource(); 726 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 727 geoSrc.fVertexSrc = kNone_GeometrySrcType; 728} 729 730void GrDrawTarget::resetIndexSource() { 731 this->releasePreviousIndexSource(); 732 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 733 geoSrc.fIndexSrc = kNone_GeometrySrcType; 734} 735 736void GrDrawTarget::pushGeometrySource() { 737 this->geometrySourceWillPush(); 738 GeometrySrcState& newState = fGeoSrcStateStack.push_back(); 739 newState.fIndexSrc = kNone_GeometrySrcType; 740 newState.fVertexSrc = kNone_GeometrySrcType; 741#if GR_DEBUG 742 newState.fVertexCount = ~0; 743 newState.fVertexBuffer = (GrVertexBuffer*)~0; 744 newState.fIndexCount = ~0; 745 newState.fIndexBuffer = (GrIndexBuffer*)~0; 746#endif 747} 748 749void GrDrawTarget::popGeometrySource() { 750 const GeometrySrcState& geoSrc = this->getGeomSrc(); 751 // if popping last element then pops are unbalanced with pushes 752 GrAssert(fGeoSrcStateStack.count() > 1); 753 754 this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1)); 755 this->releasePreviousVertexSource(); 756 this->releasePreviousIndexSource(); 757 fGeoSrcStateStack.pop_back(); 758} 759 760//////////////////////////////////////////////////////////////////////////////// 761 762bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex, 763 int startIndex, int vertexCount, 764 int indexCount) const { 765#if GR_DEBUG 766 const GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 767 int maxVertex = startVertex + vertexCount; 768 int maxValidVertex; 769 switch (geoSrc.fVertexSrc) { 770 case kNone_GeometrySrcType: 771 GrCrash("Attempting to draw without vertex src."); 772 case kReserved_GeometrySrcType: // fallthrough 773 case kArray_GeometrySrcType: 774 maxValidVertex = geoSrc.fVertexCount; 775 break; 776 case kBuffer_GeometrySrcType: 777 maxValidVertex = geoSrc.fVertexBuffer->sizeInBytes() / 778 VertexSize(geoSrc.fVertexLayout); 779 break; 780 } 781 if (maxVertex > maxValidVertex) { 782 GrCrash("Drawing outside valid vertex range."); 783 } 784 if (indexCount > 0) { 785 int maxIndex = startIndex + indexCount; 786 int maxValidIndex; 787 switch (geoSrc.fIndexSrc) { 788 case kNone_GeometrySrcType: 789 GrCrash("Attempting to draw indexed geom without index src."); 790 case kReserved_GeometrySrcType: // fallthrough 791 case kArray_GeometrySrcType: 792 maxValidIndex = geoSrc.fIndexCount; 793 break; 794 case kBuffer_GeometrySrcType: 795 maxValidIndex = geoSrc.fIndexBuffer->sizeInBytes() / sizeof(uint16_t); 796 break; 797 } 798 if (maxIndex > maxValidIndex) { 799 GrCrash("Index reads outside valid index range."); 800 } 801 } 802#endif 803 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 804 if (this->isStageEnabled(s) && 805 GrPixelConfigIsUnpremultiplied(fCurrDrawState.fTextures[s]->config())) { 806 return false; 807 } 808 } 809 return true; 810} 811 812void GrDrawTarget::drawIndexed(GrPrimitiveType type, int startVertex, 813 int startIndex, int vertexCount, 814 int indexCount) { 815 if (indexCount > 0 && 816 this->checkDraw(type, startVertex, startIndex, 817 vertexCount, indexCount)) { 818 this->onDrawIndexed(type, startVertex, startIndex, 819 vertexCount, indexCount); 820 } 821} 822 823void GrDrawTarget::drawNonIndexed(GrPrimitiveType type, 824 int startVertex, 825 int vertexCount) { 826 if (vertexCount > 0 && 827 this->checkDraw(type, startVertex, -1, vertexCount, -1)) { 828 this->onDrawNonIndexed(type, startVertex, vertexCount); 829 } 830} 831 832//////////////////////////////////////////////////////////////////////////////// 833 834// Some blend modes allow folding a partial coverage value into the color's 835// alpha channel, while others will blend incorrectly. 836bool GrDrawTarget::canTweakAlphaForCoverage() const { 837 /** 838 * The fractional coverage is f 839 * The src and dst coeffs are Cs and Cd 840 * The dst and src colors are S and D 841 * We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D 842 * By tweaking the source color's alpha we're replacing S with S'=fS. It's 843 * obvious that that first term will always be ok. The second term can be 844 * rearranged as [1-(1-Cd)f]D. By substituing in the various possbilities 845 * for Cd we find that only 1, ISA, and ISC produce the correct depth 846 * coeffecient in terms of S' and D. 847 */ 848 return kOne_BlendCoeff == fCurrDrawState.fDstBlend|| 849 kISA_BlendCoeff == fCurrDrawState.fDstBlend || 850 kISC_BlendCoeff == fCurrDrawState.fDstBlend; 851} 852 853 854bool GrDrawTarget::srcAlphaWillBeOne() const { 855 const GrVertexLayout& layout = this->getGeomSrc().fVertexLayout; 856 857 // Check if per-vertex or constant color may have partial alpha 858 if ((layout & kColor_VertexLayoutBit) || 859 0xff != GrColorUnpackA(fCurrDrawState.fColor)) { 860 return false; 861 } 862 // Check if color filter could introduce an alpha 863 // (TODO: Consider being more aggressive with regards to detecting 0xff 864 // final alpha from color filter). 865 if (SkXfermode::kDst_Mode != fCurrDrawState.fColorFilterXfermode) { 866 return false; 867 } 868 // Check if a color stage could create a partial alpha 869 for (int s = 0; s < fCurrDrawState.fFirstCoverageStage; ++s) { 870 if (StageWillBeUsed(s, layout, fCurrDrawState)) { 871 GrAssert(NULL != fCurrDrawState.fTextures[s]); 872 GrPixelConfig config = fCurrDrawState.fTextures[s]->config(); 873 if (!GrPixelConfigIsOpaque(config)) { 874 return false; 875 } 876 } 877 } 878 return true; 879} 880 881GrDrawTarget::BlendOptFlags 882GrDrawTarget::getBlendOpts(bool forceCoverage, 883 GrBlendCoeff* srcCoeff, 884 GrBlendCoeff* dstCoeff) const { 885 886 const GrVertexLayout& layout = this->getGeomSrc().fVertexLayout; 887 888 GrBlendCoeff bogusSrcCoeff, bogusDstCoeff; 889 if (NULL == srcCoeff) { 890 srcCoeff = &bogusSrcCoeff; 891 } 892 *srcCoeff = fCurrDrawState.fSrcBlend; 893 894 if (NULL == dstCoeff) { 895 dstCoeff = &bogusDstCoeff; 896 } 897 *dstCoeff = fCurrDrawState.fDstBlend; 898 899 // We don't ever expect source coeffecients to reference the source 900 GrAssert(kSA_BlendCoeff != *srcCoeff && 901 kISA_BlendCoeff != *srcCoeff && 902 kSC_BlendCoeff != *srcCoeff && 903 kISC_BlendCoeff != *srcCoeff); 904 // same for dst 905 GrAssert(kDA_BlendCoeff != *dstCoeff && 906 kIDA_BlendCoeff != *dstCoeff && 907 kDC_BlendCoeff != *dstCoeff && 908 kIDC_BlendCoeff != *dstCoeff); 909 910 if (SkToBool(kNoColorWrites_StateBit & fCurrDrawState.fFlagBits)) { 911 *srcCoeff = kZero_BlendCoeff; 912 *dstCoeff = kOne_BlendCoeff; 913 } 914 915 bool srcAIsOne = this->srcAlphaWillBeOne(); 916 bool dstCoeffIsOne = kOne_BlendCoeff == *dstCoeff || 917 (kSA_BlendCoeff == *dstCoeff && srcAIsOne); 918 bool dstCoeffIsZero = kZero_BlendCoeff == *dstCoeff || 919 (kISA_BlendCoeff == *dstCoeff && srcAIsOne); 920 921 922 // When coeffs are (0,1) there is no reason to draw at all, unless 923 // stenciling is enabled. Having color writes disabled is effectively 924 // (0,1). 925 if ((kZero_BlendCoeff == *srcCoeff && dstCoeffIsOne)) { 926 if (fCurrDrawState.fStencilSettings.doesWrite()) { 927 if (fCaps.fShaderSupport) { 928 return kDisableBlend_BlendOptFlag | 929 kEmitTransBlack_BlendOptFlag; 930 } else { 931 return kDisableBlend_BlendOptFlag; 932 } 933 } else { 934 return kSkipDraw_BlendOptFlag; 935 } 936 } 937 938 // check for coverage due to edge aa or coverage texture stage 939 bool hasCoverage = forceCoverage || 940 fCurrDrawState.fEdgeAANumEdges > 0 || 941 (layout & kCoverage_VertexLayoutBit) || 942 (layout & kEdge_VertexLayoutBit); 943 for (int s = fCurrDrawState.fFirstCoverageStage; 944 !hasCoverage && s < GrDrawState::kNumStages; 945 ++s) { 946 if (StageWillBeUsed(s, layout, fCurrDrawState)) { 947 hasCoverage = true; 948 } 949 } 950 951 // if we don't have coverage we can check whether the dst 952 // has to read at all. If not, we'll disable blending. 953 if (!hasCoverage) { 954 if (dstCoeffIsZero) { 955 if (kOne_BlendCoeff == *srcCoeff) { 956 // if there is no coverage and coeffs are (1,0) then we 957 // won't need to read the dst at all, it gets replaced by src 958 return kDisableBlend_BlendOptFlag; 959 } else if (kZero_BlendCoeff == *srcCoeff && 960 fCaps.fShaderSupport) { 961 // if the op is "clear" then we don't need to emit a color 962 // or blend, just write transparent black into the dst. 963 *srcCoeff = kOne_BlendCoeff; 964 *dstCoeff = kZero_BlendCoeff; 965 return kDisableBlend_BlendOptFlag | 966 kEmitTransBlack_BlendOptFlag; 967 } 968 } 969 } else { 970 // check whether coverage can be safely rolled into alpha 971 // of if we can skip color computation and just emit coverage 972 if (this->canTweakAlphaForCoverage()) { 973 return kCoverageAsAlpha_BlendOptFlag; 974 } 975 // We haven't implemented support for these optimizations in the 976 // fixed pipe (which is on its deathbed) 977 if (fCaps.fShaderSupport) { 978 if (dstCoeffIsZero) { 979 if (kZero_BlendCoeff == *srcCoeff) { 980 // the source color is not included in the blend 981 // the dst coeff is effectively zero so blend works out to: 982 // (c)(0)D + (1-c)D = (1-c)D. 983 *dstCoeff = kISA_BlendCoeff; 984 return kEmitCoverage_BlendOptFlag; 985 } else if (srcAIsOne) { 986 // the dst coeff is effectively zero so blend works out to: 987 // cS + (c)(0)D + (1-c)D = cS + (1-c)D. 988 // If Sa is 1 then we can replace Sa with c 989 // and set dst coeff to 1-Sa. 990 *dstCoeff = kISA_BlendCoeff; 991 return kCoverageAsAlpha_BlendOptFlag; 992 } 993 } else if (dstCoeffIsOne) { 994 // the dst coeff is effectively one so blend works out to: 995 // cS + (c)(1)D + (1-c)D = cS + D. 996 *dstCoeff = kOne_BlendCoeff; 997 return kCoverageAsAlpha_BlendOptFlag; 998 } 999 } 1000 } 1001 return kNone_BlendOpt; 1002} 1003 1004bool GrDrawTarget::willUseHWAALines() const { 1005 // there is a conflict between using smooth lines and our use of 1006 // premultiplied alpha. Smooth lines tweak the incoming alpha value 1007 // but not in a premul-alpha way. So we only use them when our alpha 1008 // is 0xff and tweaking the color for partial coverage is OK 1009 if (!fCaps.fHWAALineSupport || 1010 !(kHWAntialias_StateBit & fCurrDrawState.fFlagBits)) { 1011 return false; 1012 } 1013 BlendOptFlags opts = this->getBlendOpts(); 1014 return (kDisableBlend_BlendOptFlag & opts) && 1015 (kCoverageAsAlpha_BlendOptFlag & opts); 1016} 1017 1018bool GrDrawTarget::canApplyCoverage() const { 1019 // we can correctly apply coverage if a) we have dual source blending 1020 // or b) one of our blend optimizations applies. 1021 return this->getCaps().fDualSourceBlendingSupport || 1022 kNone_BlendOpt != this->getBlendOpts(true); 1023} 1024 1025bool GrDrawTarget::drawWillReadDst() const { 1026 return SkToBool((kDisableBlend_BlendOptFlag | kSkipDraw_BlendOptFlag) & 1027 this->getBlendOpts()); 1028} 1029 1030/////////////////////////////////////////////////////////////////////////////// 1031 1032void GrDrawTarget::setEdgeAAData(const GrDrawState::Edge* edges, int numEdges) { 1033 GrAssert(numEdges <= GrDrawState::kMaxEdges); 1034 memcpy(fCurrDrawState.fEdgeAAEdges, edges, 1035 numEdges * sizeof(GrDrawState::Edge)); 1036 fCurrDrawState.fEdgeAANumEdges = numEdges; 1037} 1038 1039 1040//////////////////////////////////////////////////////////////////////////////// 1041 1042void GrDrawTarget::drawRect(const GrRect& rect, 1043 const GrMatrix* matrix, 1044 StageBitfield stageEnableBitfield, 1045 const GrRect* srcRects[], 1046 const GrMatrix* srcMatrices[]) { 1047 GrVertexLayout layout = GetRectVertexLayout(stageEnableBitfield, srcRects); 1048 1049 AutoReleaseGeometry geo(this, layout, 4, 0); 1050 if (!geo.succeeded()) { 1051 GrPrintf("Failed to get space for vertices!\n"); 1052 return; 1053 } 1054 1055 SetRectVertices(rect, matrix, srcRects, 1056 srcMatrices, layout, geo.vertices()); 1057 1058 drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4); 1059} 1060 1061GrVertexLayout GrDrawTarget::GetRectVertexLayout(StageBitfield stageEnableBitfield, 1062 const GrRect* srcRects[]) { 1063 GrVertexLayout layout = 0; 1064 1065 for (int i = 0; i < GrDrawState::kNumStages; ++i) { 1066 int numTC = 0; 1067 if (stageEnableBitfield & (1 << i)) { 1068 if (NULL != srcRects && NULL != srcRects[i]) { 1069 layout |= StageTexCoordVertexLayoutBit(i, numTC); 1070 ++numTC; 1071 } else { 1072 layout |= StagePosAsTexCoordVertexLayoutBit(i); 1073 } 1074 } 1075 } 1076 return layout; 1077} 1078 1079void GrDrawTarget::clipWillBeSet(const GrClip& clip) { 1080} 1081 1082void GrDrawTarget::SetRectVertices(const GrRect& rect, 1083 const GrMatrix* matrix, 1084 const GrRect* srcRects[], 1085 const GrMatrix* srcMatrices[], 1086 GrVertexLayout layout, 1087 void* vertices) { 1088#if GR_DEBUG 1089 // check that the layout and srcRects agree 1090 for (int i = 0; i < GrDrawState::kNumStages; ++i) { 1091 if (VertexTexCoordsForStage(i, layout) >= 0) { 1092 GR_DEBUGASSERT(NULL != srcRects && NULL != srcRects[i]); 1093 } else { 1094 GR_DEBUGASSERT(NULL == srcRects || NULL == srcRects[i]); 1095 } 1096 } 1097#endif 1098 1099 int stageOffsets[GrDrawState::kNumStages]; 1100 int vsize = VertexSizeAndOffsetsByStage(layout, stageOffsets, 1101 NULL, NULL, NULL); 1102 1103 GrTCast<GrPoint*>(vertices)->setRectFan(rect.fLeft, rect.fTop, 1104 rect.fRight, rect.fBottom, 1105 vsize); 1106 if (NULL != matrix) { 1107 matrix->mapPointsWithStride(GrTCast<GrPoint*>(vertices), vsize, 4); 1108 } 1109 1110 for (int i = 0; i < GrDrawState::kNumStages; ++i) { 1111 if (stageOffsets[i] > 0) { 1112 GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(vertices) + 1113 stageOffsets[i]); 1114 coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop, 1115 srcRects[i]->fRight, srcRects[i]->fBottom, 1116 vsize); 1117 if (NULL != srcMatrices && NULL != srcMatrices[i]) { 1118 srcMatrices[i]->mapPointsWithStride(coords, vsize, 4); 1119 } 1120 } 1121 } 1122} 1123 1124//////////////////////////////////////////////////////////////////////////////// 1125 1126GrDrawTarget::AutoStateRestore::AutoStateRestore() { 1127 fDrawTarget = NULL; 1128} 1129 1130GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target) { 1131 fDrawTarget = target; 1132 if (NULL != fDrawTarget) { 1133 fDrawTarget->saveCurrentDrawState(&fDrawState); 1134 } 1135} 1136 1137GrDrawTarget::AutoStateRestore::~AutoStateRestore() { 1138 if (NULL != fDrawTarget) { 1139 fDrawTarget->restoreDrawState(fDrawState); 1140 } 1141} 1142 1143void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target) { 1144 if (target != fDrawTarget) { 1145 if (NULL != fDrawTarget) { 1146 fDrawTarget->restoreDrawState(fDrawState); 1147 } 1148 if (NULL != target) { 1149 target->saveCurrentDrawState(&fDrawState); 1150 } 1151 fDrawTarget = target; 1152 } 1153} 1154 1155//////////////////////////////////////////////////////////////////////////////// 1156 1157GrDrawTarget::AutoDeviceCoordDraw::AutoDeviceCoordDraw(GrDrawTarget* target, 1158 int stageMask) { 1159 GrAssert(NULL != target); 1160 1161 fDrawTarget = target; 1162 fViewMatrix = target->getViewMatrix(); 1163 fStageMask = stageMask; 1164 if (fStageMask) { 1165 GrMatrix invVM; 1166 if (fViewMatrix.invert(&invVM)) { 1167 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 1168 if (fStageMask & (1 << s)) { 1169 fSamplerMatrices[s] = target->getSamplerMatrix(s); 1170 } 1171 } 1172 target->preConcatSamplerMatrices(fStageMask, invVM); 1173 } else { 1174 // sad trombone sound 1175 fStageMask = 0; 1176 } 1177 } 1178 target->setViewMatrix(GrMatrix::I()); 1179} 1180 1181GrDrawTarget::AutoDeviceCoordDraw::~AutoDeviceCoordDraw() { 1182 fDrawTarget->setViewMatrix(fViewMatrix); 1183 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 1184 if (fStageMask & (1 << s)) { 1185 fDrawTarget->setSamplerMatrix(s, fSamplerMatrices[s]); 1186 } 1187 } 1188} 1189 1190//////////////////////////////////////////////////////////////////////////////// 1191 1192GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry( 1193 GrDrawTarget* target, 1194 GrVertexLayout vertexLayout, 1195 int vertexCount, 1196 int indexCount) { 1197 fTarget = NULL; 1198 this->set(target, vertexLayout, vertexCount, indexCount); 1199} 1200 1201GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() { 1202 fTarget = NULL; 1203} 1204 1205GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() { 1206 this->reset(); 1207} 1208 1209bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget* target, 1210 GrVertexLayout vertexLayout, 1211 int vertexCount, 1212 int indexCount) { 1213 this->reset(); 1214 fTarget = target; 1215 bool success = true; 1216 if (NULL != fTarget) { 1217 fTarget = target; 1218 if (vertexCount > 0) { 1219 success = target->reserveVertexSpace(vertexLayout, 1220 vertexCount, 1221 &fVertices); 1222 if (!success) { 1223 this->reset(); 1224 } 1225 } 1226 if (success && indexCount > 0) { 1227 success = target->reserveIndexSpace(indexCount, &fIndices); 1228 if (!success) { 1229 this->reset(); 1230 } 1231 } 1232 } 1233 GrAssert(success == (NULL != fTarget)); 1234 return success; 1235} 1236 1237void GrDrawTarget::AutoReleaseGeometry::reset() { 1238 if (NULL != fTarget) { 1239 if (NULL != fVertices) { 1240 fTarget->resetVertexSource(); 1241 } 1242 if (NULL != fIndices) { 1243 fTarget->resetIndexSource(); 1244 } 1245 fTarget = NULL; 1246 } 1247 fVertices = NULL; 1248 fIndices = NULL; 1249} 1250 1251void GrDrawTarget::Caps::print() const { 1252 static const char* gNY[] = {"NO", "YES"}; 1253 GrPrintf("8 Bit Palette Support : %s\n", gNY[f8BitPaletteSupport]); 1254 GrPrintf("NPOT Texture Support : %s\n", gNY[fNPOTTextureSupport]); 1255 GrPrintf("NPOT Texture Tile Support : %s\n", gNY[fNPOTTextureTileSupport]); 1256 GrPrintf("NPOT Render Target Support : %s\n", gNY[fNPOTRenderTargetSupport]); 1257 GrPrintf("Two Sided Stencil Support : %s\n", gNY[fTwoSidedStencilSupport]); 1258 GrPrintf("Stencil Wrap Ops Support : %s\n", gNY[fStencilWrapOpsSupport]); 1259 GrPrintf("HW AA Lines Support : %s\n", gNY[fHWAALineSupport]); 1260 GrPrintf("Shader Support : %s\n", gNY[fShaderSupport]); 1261 GrPrintf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport]); 1262 GrPrintf("Geometry Shader Support : %s\n", gNY[fGeometryShaderSupport]); 1263 GrPrintf("FSAA Support : %s\n", gNY[fFSAASupport]); 1264 GrPrintf("Dual Source Blending Support: %s\n", gNY[fDualSourceBlendingSupport]); 1265 GrPrintf("Buffer Lock Support : %s\n", gNY[fBufferLockSupport]); 1266 GrPrintf("Min Render Target Width : %d\n", fMinRenderTargetWidth); 1267 GrPrintf("Min Render Target Height : %d\n", fMinRenderTargetHeight); 1268 GrPrintf("Max Texture Size : %d\n", fMaxTextureSize); 1269 GrPrintf("Max Render Target Size : %d\n", fMaxRenderTargetSize); 1270} 1271 1272