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