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