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