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