GrDrawTarget.cpp revision 0e51577a14f903ffeafa117a75954baeb173ffb9
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 // Check if per-vertex or constant color may have partial alpha 831 if ((layout & kColor_VertexLayoutBit) || 832 0xff != GrColorUnpackA(drawState.getColor())) { 833 return false; 834 } 835 // Check if color filter could introduce an alpha 836 // (TODO: Consider being more aggressive with regards to detecting 0xff 837 // final alpha from color filter). 838 if (SkXfermode::kDst_Mode != drawState.getColorFilterMode()) { 839 return false; 840 } 841 int stageCnt; 842 // Check whether coverage is treated as color 843 if (drawState.isCoverageDrawing()) { 844 if (0xff != GrColorUnpackA(drawState.getCoverage())) { 845 return false; 846 } 847 stageCnt = GrDrawState::kNumStages; 848 } else { 849 stageCnt = drawState.getFirstCoverageStage(); 850 } 851 // Check if a color stage could create a partial alpha 852 for (int s = 0; s < stageCnt; ++s) { 853 const GrEffect* effect = drawState.getStage(s).getEffect(); 854 if (NULL != effect) { 855 // FIXME: The param indicates whether the texture is opaque or not. However, the effect 856 // already controls its textures. It really needs to know whether the incoming color 857 // (from a uni, per-vertex colors, or previous stage) is opaque or not. 858 if (!effect->isOpaque(true)) { 859 return false; 860 } 861 } 862 } 863 return true; 864} 865 866namespace { 867GrVertexLayout default_blend_opts_vertex_layout() { 868 GrVertexLayout layout = 0; 869 return layout; 870} 871} 872 873GrDrawTarget::BlendOptFlags 874GrDrawTarget::getBlendOpts(bool forceCoverage, 875 GrBlendCoeff* srcCoeff, 876 GrBlendCoeff* dstCoeff) const { 877 878 GrVertexLayout layout; 879 if (kNone_GeometrySrcType == this->getGeomSrc().fVertexSrc) { 880 layout = default_blend_opts_vertex_layout(); 881 } else { 882 layout = this->getVertexLayout(); 883 } 884 885 const GrDrawState& drawState = this->getDrawState(); 886 887 GrBlendCoeff bogusSrcCoeff, bogusDstCoeff; 888 if (NULL == srcCoeff) { 889 srcCoeff = &bogusSrcCoeff; 890 } 891 *srcCoeff = drawState.getSrcBlendCoeff(); 892 893 if (NULL == dstCoeff) { 894 dstCoeff = &bogusDstCoeff; 895 } 896 *dstCoeff = drawState.getDstBlendCoeff(); 897 898 if (drawState.isColorWriteDisabled()) { 899 *srcCoeff = kZero_GrBlendCoeff; 900 *dstCoeff = kOne_GrBlendCoeff; 901 } 902 903 bool srcAIsOne = this->srcAlphaWillBeOne(layout); 904 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff || 905 (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne); 906 bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff || 907 (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne); 908 909 bool covIsZero = !drawState.isCoverageDrawing() && 910 !(layout & kCoverage_VertexLayoutBit) && 911 0 == drawState.getCoverage(); 912 // When coeffs are (0,1) there is no reason to draw at all, unless 913 // stenciling is enabled. Having color writes disabled is effectively 914 // (0,1). The same applies when coverage is known to be 0. 915 if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne) || covIsZero) { 916 if (drawState.getStencil().doesWrite()) { 917 return kDisableBlend_BlendOptFlag | 918 kEmitTransBlack_BlendOptFlag; 919 } else { 920 return kSkipDraw_BlendOptFlag; 921 } 922 } 923 924 // check for coverage due to constant coverage, per-vertex coverage, 925 // edge aa or coverage stage 926 bool hasCoverage = forceCoverage || 927 0xffffffff != drawState.getCoverage() || 928 (layout & kCoverage_VertexLayoutBit) || 929 (layout & kEdge_VertexLayoutBit); 930 for (int s = drawState.getFirstCoverageStage(); 931 !hasCoverage && s < GrDrawState::kNumStages; 932 ++s) { 933 if (this->isStageEnabled(s)) { 934 hasCoverage = true; 935 } 936 } 937 938 // if we don't have coverage we can check whether the dst 939 // has to read at all. If not, we'll disable blending. 940 if (!hasCoverage) { 941 if (dstCoeffIsZero) { 942 if (kOne_GrBlendCoeff == *srcCoeff) { 943 // if there is no coverage and coeffs are (1,0) then we 944 // won't need to read the dst at all, it gets replaced by src 945 return kDisableBlend_BlendOptFlag; 946 } else if (kZero_GrBlendCoeff == *srcCoeff) { 947 // if the op is "clear" then we don't need to emit a color 948 // or blend, just write transparent black into the dst. 949 *srcCoeff = kOne_GrBlendCoeff; 950 *dstCoeff = kZero_GrBlendCoeff; 951 return kDisableBlend_BlendOptFlag | kEmitTransBlack_BlendOptFlag; 952 } 953 } 954 } else if (drawState.isCoverageDrawing()) { 955 // we have coverage but we aren't distinguishing it from alpha by request. 956 return kCoverageAsAlpha_BlendOptFlag; 957 } else { 958 // check whether coverage can be safely rolled into alpha 959 // of if we can skip color computation and just emit coverage 960 if (this->canTweakAlphaForCoverage()) { 961 return kCoverageAsAlpha_BlendOptFlag; 962 } 963 if (dstCoeffIsZero) { 964 if (kZero_GrBlendCoeff == *srcCoeff) { 965 // the source color is not included in the blend 966 // the dst coeff is effectively zero so blend works out to: 967 // (c)(0)D + (1-c)D = (1-c)D. 968 *dstCoeff = kISA_GrBlendCoeff; 969 return kEmitCoverage_BlendOptFlag; 970 } else if (srcAIsOne) { 971 // the dst coeff is effectively zero so blend works out to: 972 // cS + (c)(0)D + (1-c)D = cS + (1-c)D. 973 // If Sa is 1 then we can replace Sa with c 974 // and set dst coeff to 1-Sa. 975 *dstCoeff = kISA_GrBlendCoeff; 976 return kCoverageAsAlpha_BlendOptFlag; 977 } 978 } else if (dstCoeffIsOne) { 979 // the dst coeff is effectively one so blend works out to: 980 // cS + (c)(1)D + (1-c)D = cS + D. 981 *dstCoeff = kOne_GrBlendCoeff; 982 return kCoverageAsAlpha_BlendOptFlag; 983 } 984 } 985 return kNone_BlendOpt; 986} 987 988bool GrDrawTarget::willUseHWAALines() const { 989 // there is a conflict between using smooth lines and our use of 990 // premultiplied alpha. Smooth lines tweak the incoming alpha value 991 // but not in a premul-alpha way. So we only use them when our alpha 992 // is 0xff and tweaking the color for partial coverage is OK 993 if (!fCaps.hwAALineSupport() || 994 !this->getDrawState().isHWAntialiasState()) { 995 return false; 996 } 997 BlendOptFlags opts = this->getBlendOpts(); 998 return (kDisableBlend_BlendOptFlag & opts) && 999 (kCoverageAsAlpha_BlendOptFlag & opts); 1000} 1001 1002bool GrDrawTarget::canApplyCoverage() const { 1003 // we can correctly apply coverage if a) we have dual source blending 1004 // or b) one of our blend optimizations applies. 1005 return this->getCaps().dualSourceBlendingSupport() || 1006 kNone_BlendOpt != this->getBlendOpts(true); 1007} 1008 1009//////////////////////////////////////////////////////////////////////////////// 1010 1011void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type, 1012 int instanceCount, 1013 int verticesPerInstance, 1014 int indicesPerInstance) { 1015 if (!verticesPerInstance || !indicesPerInstance) { 1016 return; 1017 } 1018 1019 int instancesPerDraw = this->indexCountInCurrentSource() / 1020 indicesPerInstance; 1021 if (!instancesPerDraw) { 1022 return; 1023 } 1024 1025 instancesPerDraw = GrMin(instanceCount, instancesPerDraw); 1026 int startVertex = 0; 1027 while (instanceCount) { 1028 this->drawIndexed(type, 1029 startVertex, 1030 0, 1031 verticesPerInstance * instancesPerDraw, 1032 indicesPerInstance * instancesPerDraw); 1033 startVertex += verticesPerInstance; 1034 instanceCount -= instancesPerDraw; 1035 } 1036} 1037 1038//////////////////////////////////////////////////////////////////////////////// 1039 1040void GrDrawTarget::drawRect(const GrRect& rect, 1041 const SkMatrix* matrix, 1042 const GrRect* srcRects[], 1043 const SkMatrix* srcMatrices[]) { 1044 GrVertexLayout layout = GetRectVertexLayout(srcRects); 1045 1046 AutoReleaseGeometry geo(this, layout, 4, 0); 1047 if (!geo.succeeded()) { 1048 GrPrintf("Failed to get space for vertices!\n"); 1049 return; 1050 } 1051 1052 SetRectVertices(rect, matrix, srcRects, 1053 srcMatrices, SK_ColorBLACK, layout, geo.vertices()); 1054 1055 drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4); 1056} 1057 1058GrVertexLayout GrDrawTarget::GetRectVertexLayout(const GrRect* srcRects[]) { 1059 if (NULL == srcRects) { 1060 return 0; 1061 } 1062 1063 GrVertexLayout layout = 0; 1064 for (int i = 0; i < GrDrawState::kNumStages; ++i) { 1065 int numTC = 0; 1066 if (NULL != srcRects[i]) { 1067 layout |= StageTexCoordVertexLayoutBit(i, numTC); 1068 ++numTC; 1069 } 1070 } 1071 return layout; 1072} 1073 1074// This method fills int the four vertices for drawing 'rect'. 1075// matrix - is applied to each vertex 1076// srcRects - provide the uvs for each vertex 1077// srcMatrices - are applied to the corresponding 'srcRect' 1078// color - vertex color (replicated in each vertex) 1079// layout - specifies which uvs and/or color are present 1080// vertices - storage for the resulting vertices 1081// Note: the color parameter will only be used when kColor_VertexLayoutBit 1082// is present in 'layout' 1083void GrDrawTarget::SetRectVertices(const GrRect& rect, 1084 const SkMatrix* matrix, 1085 const GrRect* srcRects[], 1086 const SkMatrix* srcMatrices[], 1087 GrColor color, 1088 GrVertexLayout layout, 1089 void* vertices) { 1090#if GR_DEBUG 1091 // check that the layout and srcRects agree 1092 for (int i = 0; i < GrDrawState::kNumStages; ++i) { 1093 if (VertexTexCoordsForStage(i, layout) >= 0) { 1094 GR_DEBUGASSERT(NULL != srcRects && NULL != srcRects[i]); 1095 } else { 1096 GR_DEBUGASSERT(NULL == srcRects || NULL == srcRects[i]); 1097 } 1098 } 1099#endif 1100 1101 int stageOffsets[GrDrawState::kNumStages], colorOffset; 1102 int vsize = VertexSizeAndOffsetsByStage(layout, stageOffsets, 1103 &colorOffset, NULL, NULL); 1104 1105 GrTCast<GrPoint*>(vertices)->setRectFan(rect.fLeft, rect.fTop, 1106 rect.fRight, rect.fBottom, 1107 vsize); 1108 if (NULL != matrix) { 1109 matrix->mapPointsWithStride(GrTCast<GrPoint*>(vertices), vsize, 4); 1110 } 1111 1112 for (int i = 0; i < GrDrawState::kNumStages; ++i) { 1113 if (stageOffsets[i] > 0) { 1114 GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(vertices) + 1115 stageOffsets[i]); 1116 coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop, 1117 srcRects[i]->fRight, srcRects[i]->fBottom, 1118 vsize); 1119 if (NULL != srcMatrices && NULL != srcMatrices[i]) { 1120 srcMatrices[i]->mapPointsWithStride(coords, vsize, 4); 1121 } 1122 } 1123 } 1124 1125 if (layout & kColor_VertexLayoutBit) { 1126 1127 GrColor* vertCol = GrTCast<GrColor*>(GrTCast<intptr_t>(vertices) + colorOffset); 1128 1129 for (int i = 0; i < 4; ++i) { 1130 *vertCol = color; 1131 vertCol = (GrColor*) ((intptr_t) vertCol + vsize); 1132 } 1133 } 1134} 1135 1136//////////////////////////////////////////////////////////////////////////////// 1137 1138GrDrawTarget::AutoStateRestore::AutoStateRestore() { 1139 fDrawTarget = NULL; 1140} 1141 1142GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target, 1143 ASRInit init) { 1144 fDrawTarget = NULL; 1145 this->set(target, init); 1146} 1147 1148GrDrawTarget::AutoStateRestore::~AutoStateRestore() { 1149 if (NULL != fDrawTarget) { 1150 fDrawTarget->setDrawState(fSavedState); 1151 fSavedState->unref(); 1152 } 1153} 1154 1155void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target, ASRInit init) { 1156 GrAssert(NULL == fDrawTarget); 1157 fDrawTarget = target; 1158 fSavedState = target->drawState(); 1159 GrAssert(fSavedState); 1160 fSavedState->ref(); 1161 if (kReset_ASRInit == init) { 1162 // calls the default cons 1163 fTempState.init(); 1164 } else { 1165 GrAssert(kPreserve_ASRInit == init); 1166 // calls the copy cons 1167 fTempState.set(*fSavedState); 1168 } 1169 target->setDrawState(fTempState.get()); 1170} 1171 1172//////////////////////////////////////////////////////////////////////////////// 1173 1174GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry( 1175 GrDrawTarget* target, 1176 GrVertexLayout vertexLayout, 1177 int vertexCount, 1178 int indexCount) { 1179 fTarget = NULL; 1180 this->set(target, vertexLayout, vertexCount, indexCount); 1181} 1182 1183GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() { 1184 fTarget = NULL; 1185} 1186 1187GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() { 1188 this->reset(); 1189} 1190 1191bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget* target, 1192 GrVertexLayout vertexLayout, 1193 int vertexCount, 1194 int indexCount) { 1195 this->reset(); 1196 fTarget = target; 1197 bool success = true; 1198 if (NULL != fTarget) { 1199 fTarget = target; 1200 success = target->reserveVertexAndIndexSpace(vertexLayout, 1201 vertexCount, 1202 indexCount, 1203 &fVertices, 1204 &fIndices); 1205 if (!success) { 1206 fTarget = NULL; 1207 this->reset(); 1208 } 1209 } 1210 GrAssert(success == (NULL != fTarget)); 1211 return success; 1212} 1213 1214void GrDrawTarget::AutoReleaseGeometry::reset() { 1215 if (NULL != fTarget) { 1216 if (NULL != fVertices) { 1217 fTarget->resetVertexSource(); 1218 } 1219 if (NULL != fIndices) { 1220 fTarget->resetIndexSource(); 1221 } 1222 fTarget = NULL; 1223 } 1224 fVertices = NULL; 1225 fIndices = NULL; 1226} 1227 1228GrDrawTarget::AutoClipRestore::AutoClipRestore(GrDrawTarget* target, const SkIRect& newClip) { 1229 fTarget = target; 1230 fClip = fTarget->getClip(); 1231 fStack.init(); 1232 fStack.get()->clipDevRect(newClip, SkRegion::kReplace_Op); 1233 fReplacementClip.fClipStack = fStack.get(); 1234 target->setClip(&fReplacementClip); 1235} 1236 1237void GrDrawTarget::Caps::print() const { 1238 static const char* gNY[] = {"NO", "YES"}; 1239 GrPrintf("8 Bit Palette Support : %s\n", gNY[fInternals.f8BitPaletteSupport]); 1240 GrPrintf("NPOT Texture Tile Support : %s\n", gNY[fInternals.fNPOTTextureTileSupport]); 1241 GrPrintf("Two Sided Stencil Support : %s\n", gNY[fInternals.fTwoSidedStencilSupport]); 1242 GrPrintf("Stencil Wrap Ops Support : %s\n", gNY[fInternals.fStencilWrapOpsSupport]); 1243 GrPrintf("HW AA Lines Support : %s\n", gNY[fInternals.fHWAALineSupport]); 1244 GrPrintf("Shader Derivative Support : %s\n", gNY[fInternals.fShaderDerivativeSupport]); 1245 GrPrintf("Geometry Shader Support : %s\n", gNY[fInternals.fGeometryShaderSupport]); 1246 GrPrintf("FSAA Support : %s\n", gNY[fInternals.fFSAASupport]); 1247 GrPrintf("Dual Source Blending Support: %s\n", gNY[fInternals.fDualSourceBlendingSupport]); 1248 GrPrintf("Buffer Lock Support : %s\n", gNY[fInternals.fBufferLockSupport]); 1249 GrPrintf("Path Stenciling Support : %s\n", gNY[fInternals.fPathStencilingSupport]); 1250 GrPrintf("Max Texture Size : %d\n", fInternals.fMaxTextureSize); 1251 GrPrintf("Max Render Target Size : %d\n", fInternals.fMaxRenderTargetSize); 1252} 1253