GrDrawTarget.cpp revision 2b446734cfa8201e5478648988de86b646cb9544
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 "GrRenderTarget.h" 13#include "GrTexture.h" 14#include "GrVertexBuffer.h" 15 16#include "SkStrokeRec.h" 17 18SK_DEFINE_INST_COUNT(GrDrawTarget) 19 20//////////////////////////////////////////////////////////////////////////////// 21 22GrDrawTarget::DrawInfo& GrDrawTarget::DrawInfo::operator =(const DrawInfo& di) { 23 fPrimitiveType = di.fPrimitiveType; 24 fStartVertex = di.fStartVertex; 25 fStartIndex = di.fStartIndex; 26 fVertexCount = di.fVertexCount; 27 fIndexCount = di.fIndexCount; 28 29 fInstanceCount = di.fInstanceCount; 30 fVerticesPerInstance = di.fVerticesPerInstance; 31 fIndicesPerInstance = di.fIndicesPerInstance; 32 33 if (NULL != di.fDevBounds) { 34 GrAssert(di.fDevBounds == &di.fDevBoundsStorage); 35 fDevBoundsStorage = di.fDevBoundsStorage; 36 fDevBounds = &fDevBoundsStorage; 37 } else { 38 fDevBounds = NULL; 39 } 40 return *this; 41} 42 43#if GR_DEBUG 44bool GrDrawTarget::DrawInfo::isInstanced() const { 45 if (fInstanceCount > 0) { 46 GrAssert(0 == fIndexCount % fIndicesPerInstance); 47 GrAssert(0 == fVertexCount % fVerticesPerInstance); 48 GrAssert(fIndexCount / fIndicesPerInstance == fInstanceCount); 49 GrAssert(fVertexCount / fVerticesPerInstance == fInstanceCount); 50 // there is no way to specify a non-zero start index to drawIndexedInstances(). 51 GrAssert(0 == fStartIndex); 52 return true; 53 } else { 54 GrAssert(!fVerticesPerInstance); 55 GrAssert(!fIndicesPerInstance); 56 return false; 57 } 58} 59#endif 60 61void GrDrawTarget::DrawInfo::adjustInstanceCount(int instanceOffset) { 62 GrAssert(this->isInstanced()); 63 GrAssert(instanceOffset + fInstanceCount >= 0); 64 fInstanceCount += instanceOffset; 65 fVertexCount = fVerticesPerInstance * fInstanceCount; 66 fIndexCount = fIndicesPerInstance * fInstanceCount; 67} 68 69void GrDrawTarget::DrawInfo::adjustStartVertex(int vertexOffset) { 70 fStartVertex += vertexOffset; 71 GrAssert(fStartVertex >= 0); 72} 73 74void GrDrawTarget::DrawInfo::adjustStartIndex(int indexOffset) { 75 GrAssert(this->isIndexed()); 76 fStartIndex += indexOffset; 77 GrAssert(fStartIndex >= 0); 78} 79 80//////////////////////////////////////////////////////////////////////////////// 81 82#define DEBUG_INVAL_BUFFER 0xdeadcafe 83#define DEBUG_INVAL_START_IDX -1 84 85GrDrawTarget::GrDrawTarget() : fClip(NULL) { 86 fDrawState = &fDefaultDrawState; 87 // We assume that fDrawState always owns a ref to the object it points at. 88 fDefaultDrawState.ref(); 89 GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back(); 90#if GR_DEBUG 91 geoSrc.fVertexCount = DEBUG_INVAL_START_IDX; 92 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; 93 geoSrc.fIndexCount = DEBUG_INVAL_START_IDX; 94 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; 95#endif 96 geoSrc.fVertexSrc = kNone_GeometrySrcType; 97 geoSrc.fIndexSrc = kNone_GeometrySrcType; 98} 99 100GrDrawTarget::~GrDrawTarget() { 101 GrAssert(1 == fGeoSrcStateStack.count()); 102 SkDEBUGCODE(GeometrySrcState& geoSrc = fGeoSrcStateStack.back()); 103 GrAssert(kNone_GeometrySrcType == geoSrc.fIndexSrc); 104 GrAssert(kNone_GeometrySrcType == geoSrc.fVertexSrc); 105 fDrawState->unref(); 106} 107 108void GrDrawTarget::releaseGeometry() { 109 int popCnt = fGeoSrcStateStack.count() - 1; 110 while (popCnt) { 111 this->popGeometrySource(); 112 --popCnt; 113 } 114 this->resetVertexSource(); 115 this->resetIndexSource(); 116} 117 118void GrDrawTarget::setClip(const GrClipData* clip) { 119 clipWillBeSet(clip); 120 fClip = clip; 121} 122 123const GrClipData* GrDrawTarget::getClip() const { 124 return fClip; 125} 126 127void GrDrawTarget::setDrawState(GrDrawState* drawState) { 128 GrAssert(NULL != fDrawState); 129 if (NULL == drawState) { 130 drawState = &fDefaultDrawState; 131 } 132 if (fDrawState != drawState) { 133 fDrawState->unref(); 134 drawState->ref(); 135 fDrawState = drawState; 136 } 137} 138 139bool GrDrawTarget::reserveVertexSpace(size_t vertexSize, 140 int vertexCount, 141 void** vertices) { 142 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 143 bool acquired = false; 144 if (vertexCount > 0) { 145 GrAssert(NULL != vertices); 146 this->releasePreviousVertexSource(); 147 geoSrc.fVertexSrc = kNone_GeometrySrcType; 148 149 acquired = this->onReserveVertexSpace(vertexSize, 150 vertexCount, 151 vertices); 152 } 153 if (acquired) { 154 geoSrc.fVertexSrc = kReserved_GeometrySrcType; 155 geoSrc.fVertexCount = vertexCount; 156 geoSrc.fVertexSize = vertexSize; 157 } else if (NULL != vertices) { 158 *vertices = NULL; 159 } 160 return acquired; 161} 162 163bool GrDrawTarget::reserveIndexSpace(int indexCount, 164 void** indices) { 165 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 166 bool acquired = false; 167 if (indexCount > 0) { 168 GrAssert(NULL != indices); 169 this->releasePreviousIndexSource(); 170 geoSrc.fIndexSrc = kNone_GeometrySrcType; 171 172 acquired = this->onReserveIndexSpace(indexCount, indices); 173 } 174 if (acquired) { 175 geoSrc.fIndexSrc = kReserved_GeometrySrcType; 176 geoSrc.fIndexCount = indexCount; 177 } else if (NULL != indices) { 178 *indices = NULL; 179 } 180 return acquired; 181 182} 183 184bool GrDrawTarget::reserveVertexAndIndexSpace(int vertexCount, 185 int indexCount, 186 void** vertices, 187 void** indices) { 188 size_t vertexSize = this->drawState()->getVertexSize(); 189 this->willReserveVertexAndIndexSpace(vertexCount, indexCount); 190 if (vertexCount) { 191 if (!this->reserveVertexSpace(vertexSize, vertexCount, vertices)) { 192 if (indexCount) { 193 this->resetIndexSource(); 194 } 195 return false; 196 } 197 } 198 if (indexCount) { 199 if (!this->reserveIndexSpace(indexCount, indices)) { 200 if (vertexCount) { 201 this->resetVertexSource(); 202 } 203 return false; 204 } 205 } 206 return true; 207} 208 209bool GrDrawTarget::geometryHints(int32_t* vertexCount, 210 int32_t* indexCount) const { 211 if (NULL != vertexCount) { 212 *vertexCount = -1; 213 } 214 if (NULL != indexCount) { 215 *indexCount = -1; 216 } 217 return false; 218} 219 220void GrDrawTarget::releasePreviousVertexSource() { 221 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 222 switch (geoSrc.fVertexSrc) { 223 case kNone_GeometrySrcType: 224 break; 225 case kArray_GeometrySrcType: 226 this->releaseVertexArray(); 227 break; 228 case kReserved_GeometrySrcType: 229 this->releaseReservedVertexSpace(); 230 break; 231 case kBuffer_GeometrySrcType: 232 geoSrc.fVertexBuffer->unref(); 233#if GR_DEBUG 234 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; 235#endif 236 break; 237 default: 238 GrCrash("Unknown Vertex Source Type."); 239 break; 240 } 241} 242 243void GrDrawTarget::releasePreviousIndexSource() { 244 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 245 switch (geoSrc.fIndexSrc) { 246 case kNone_GeometrySrcType: // these two don't require 247 break; 248 case kArray_GeometrySrcType: 249 this->releaseIndexArray(); 250 break; 251 case kReserved_GeometrySrcType: 252 this->releaseReservedIndexSpace(); 253 break; 254 case kBuffer_GeometrySrcType: 255 geoSrc.fIndexBuffer->unref(); 256#if GR_DEBUG 257 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; 258#endif 259 break; 260 default: 261 GrCrash("Unknown Index Source Type."); 262 break; 263 } 264} 265 266void GrDrawTarget::setVertexSourceToArray(const void* vertexArray, 267 int vertexCount) { 268 this->releasePreviousVertexSource(); 269 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 270 geoSrc.fVertexSrc = kArray_GeometrySrcType; 271 geoSrc.fVertexSize = this->drawState()->getVertexSize(); 272 geoSrc.fVertexCount = vertexCount; 273 this->onSetVertexSourceToArray(vertexArray, vertexCount); 274} 275 276void GrDrawTarget::setIndexSourceToArray(const void* indexArray, 277 int indexCount) { 278 this->releasePreviousIndexSource(); 279 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 280 geoSrc.fIndexSrc = kArray_GeometrySrcType; 281 geoSrc.fIndexCount = indexCount; 282 this->onSetIndexSourceToArray(indexArray, indexCount); 283} 284 285void GrDrawTarget::setVertexSourceToBuffer(const GrVertexBuffer* buffer) { 286 this->releasePreviousVertexSource(); 287 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 288 geoSrc.fVertexSrc = kBuffer_GeometrySrcType; 289 geoSrc.fVertexBuffer = buffer; 290 buffer->ref(); 291 geoSrc.fVertexSize = this->drawState()->getVertexSize(); 292} 293 294void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) { 295 this->releasePreviousIndexSource(); 296 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 297 geoSrc.fIndexSrc = kBuffer_GeometrySrcType; 298 geoSrc.fIndexBuffer = buffer; 299 buffer->ref(); 300} 301 302void GrDrawTarget::resetVertexSource() { 303 this->releasePreviousVertexSource(); 304 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 305 geoSrc.fVertexSrc = kNone_GeometrySrcType; 306} 307 308void GrDrawTarget::resetIndexSource() { 309 this->releasePreviousIndexSource(); 310 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 311 geoSrc.fIndexSrc = kNone_GeometrySrcType; 312} 313 314void GrDrawTarget::pushGeometrySource() { 315 this->geometrySourceWillPush(); 316 GeometrySrcState& newState = fGeoSrcStateStack.push_back(); 317 newState.fIndexSrc = kNone_GeometrySrcType; 318 newState.fVertexSrc = kNone_GeometrySrcType; 319#if GR_DEBUG 320 newState.fVertexCount = ~0; 321 newState.fVertexBuffer = (GrVertexBuffer*)~0; 322 newState.fIndexCount = ~0; 323 newState.fIndexBuffer = (GrIndexBuffer*)~0; 324#endif 325} 326 327void GrDrawTarget::popGeometrySource() { 328 // if popping last element then pops are unbalanced with pushes 329 GrAssert(fGeoSrcStateStack.count() > 1); 330 331 this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1)); 332 this->releasePreviousVertexSource(); 333 this->releasePreviousIndexSource(); 334 fGeoSrcStateStack.pop_back(); 335} 336 337//////////////////////////////////////////////////////////////////////////////// 338 339bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex, 340 int startIndex, int vertexCount, 341 int indexCount) const { 342 const GrDrawState& drawState = this->getDrawState(); 343#if GR_DEBUG 344 const GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 345 int maxVertex = startVertex + vertexCount; 346 int maxValidVertex; 347 switch (geoSrc.fVertexSrc) { 348 case kNone_GeometrySrcType: 349 GrCrash("Attempting to draw without vertex src."); 350 case kReserved_GeometrySrcType: // fallthrough 351 case kArray_GeometrySrcType: 352 maxValidVertex = geoSrc.fVertexCount; 353 break; 354 case kBuffer_GeometrySrcType: 355 maxValidVertex = geoSrc.fVertexBuffer->sizeInBytes() / geoSrc.fVertexSize; 356 break; 357 } 358 if (maxVertex > maxValidVertex) { 359 GrCrash("Drawing outside valid vertex range."); 360 } 361 if (indexCount > 0) { 362 int maxIndex = startIndex + indexCount; 363 int maxValidIndex; 364 switch (geoSrc.fIndexSrc) { 365 case kNone_GeometrySrcType: 366 GrCrash("Attempting to draw indexed geom without index src."); 367 case kReserved_GeometrySrcType: // fallthrough 368 case kArray_GeometrySrcType: 369 maxValidIndex = geoSrc.fIndexCount; 370 break; 371 case kBuffer_GeometrySrcType: 372 maxValidIndex = geoSrc.fIndexBuffer->sizeInBytes() / sizeof(uint16_t); 373 break; 374 } 375 if (maxIndex > maxValidIndex) { 376 GrCrash("Index reads outside valid index range."); 377 } 378 } 379 380 GrAssert(NULL != drawState.getRenderTarget()); 381 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 382 if (drawState.isStageEnabled(s)) { 383 const GrEffectRef& effect = *drawState.getStage(s).getEffect(); 384 int numTextures = effect->numTextures(); 385 for (int t = 0; t < numTextures; ++t) { 386 GrTexture* texture = effect->texture(t); 387 GrAssert(texture->asRenderTarget() != drawState.getRenderTarget()); 388 } 389 } 390 } 391#endif 392 if (NULL == drawState.getRenderTarget()) { 393 return false; 394 } 395 return true; 396} 397 398void GrDrawTarget::drawIndexed(GrPrimitiveType type, 399 int startVertex, 400 int startIndex, 401 int vertexCount, 402 int indexCount, 403 const SkRect* devBounds) { 404 if (indexCount > 0 && this->checkDraw(type, startVertex, startIndex, vertexCount, indexCount)) { 405 DrawInfo info; 406 info.fPrimitiveType = type; 407 info.fStartVertex = startVertex; 408 info.fStartIndex = startIndex; 409 info.fVertexCount = vertexCount; 410 info.fIndexCount = indexCount; 411 412 info.fInstanceCount = 0; 413 info.fVerticesPerInstance = 0; 414 info.fIndicesPerInstance = 0; 415 416 if (NULL != devBounds) { 417 info.setDevBounds(*devBounds); 418 } 419 this->onDraw(info); 420 } 421} 422 423void GrDrawTarget::drawNonIndexed(GrPrimitiveType type, 424 int startVertex, 425 int vertexCount, 426 const SkRect* devBounds) { 427 if (vertexCount > 0 && this->checkDraw(type, startVertex, -1, vertexCount, -1)) { 428 DrawInfo info; 429 info.fPrimitiveType = type; 430 info.fStartVertex = startVertex; 431 info.fStartIndex = 0; 432 info.fVertexCount = vertexCount; 433 info.fIndexCount = 0; 434 435 info.fInstanceCount = 0; 436 info.fVerticesPerInstance = 0; 437 info.fIndicesPerInstance = 0; 438 439 if (NULL != devBounds) { 440 info.setDevBounds(*devBounds); 441 } 442 this->onDraw(info); 443 } 444} 445 446void GrDrawTarget::stencilPath(const GrPath* path, const SkStrokeRec& stroke, SkPath::FillType fill) { 447 // TODO: extract portions of checkDraw that are relevant to path stenciling. 448 GrAssert(NULL != path); 449 GrAssert(fCaps.pathStencilingSupport()); 450 GrAssert(!stroke.isHairlineStyle()); 451 GrAssert(!SkPath::IsInverseFillType(fill)); 452 this->onStencilPath(path, stroke, fill); 453} 454 455//////////////////////////////////////////////////////////////////////////////// 456 457bool GrDrawTarget::willUseHWAALines() const { 458 // There is a conflict between using smooth lines and our use of premultiplied alpha. Smooth 459 // lines tweak the incoming alpha value but not in a premul-alpha way. So we only use them when 460 // our alpha is 0xff and tweaking the color for partial coverage is OK 461 if (!fCaps.hwAALineSupport() || 462 !this->getDrawState().isHWAntialiasState()) { 463 return false; 464 } 465 GrDrawState::BlendOptFlags opts = this->getDrawState().getBlendOpts(); 466 return (GrDrawState::kDisableBlend_BlendOptFlag & opts) && 467 (GrDrawState::kCoverageAsAlpha_BlendOptFlag & opts); 468} 469 470bool GrDrawTarget::canApplyCoverage() const { 471 // we can correctly apply coverage if a) we have dual source blending 472 // or b) one of our blend optimizations applies. 473 return this->getCaps().dualSourceBlendingSupport() || 474 GrDrawState::kNone_BlendOpt != this->getDrawState().getBlendOpts(true); 475} 476 477//////////////////////////////////////////////////////////////////////////////// 478 479void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type, 480 int instanceCount, 481 int verticesPerInstance, 482 int indicesPerInstance, 483 const SkRect* devBounds) { 484 if (!verticesPerInstance || !indicesPerInstance) { 485 return; 486 } 487 488 int maxInstancesPerDraw = this->indexCountInCurrentSource() / indicesPerInstance; 489 if (!maxInstancesPerDraw) { 490 return; 491 } 492 493 DrawInfo info; 494 info.fPrimitiveType = type; 495 info.fStartIndex = 0; 496 info.fStartVertex = 0; 497 info.fIndicesPerInstance = indicesPerInstance; 498 info.fVerticesPerInstance = verticesPerInstance; 499 500 // Set the same bounds for all the draws. 501 if (NULL != devBounds) { 502 info.setDevBounds(*devBounds); 503 } 504 505 while (instanceCount) { 506 info.fInstanceCount = GrMin(instanceCount, maxInstancesPerDraw); 507 info.fVertexCount = info.fInstanceCount * verticesPerInstance; 508 info.fIndexCount = info.fInstanceCount * indicesPerInstance; 509 510 if (this->checkDraw(type, 511 info.fStartVertex, 512 info.fStartIndex, 513 info.fVertexCount, 514 info.fIndexCount)) { 515 this->onDraw(info); 516 } 517 info.fStartVertex += info.fVertexCount; 518 instanceCount -= info.fInstanceCount; 519 } 520} 521 522//////////////////////////////////////////////////////////////////////////////// 523 524void GrDrawTarget::drawRect(const GrRect& rect, 525 const SkMatrix* matrix, 526 const GrRect* srcRects[], 527 const SkMatrix* srcMatrices[]) { 528 GrVertexLayout layout = 0; 529 uint32_t explicitCoordMask = 0; 530 531 if (NULL != srcRects) { 532 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 533 int numTC = 0; 534 if (NULL != srcRects[s]) { 535 layout |= GrDrawState::StageTexCoordVertexLayoutBit(s, numTC); 536 explicitCoordMask |= (1 << s); 537 ++numTC; 538 } 539 } 540 } 541 542 GrDrawState::AutoViewMatrixRestore avmr; 543 if (NULL != matrix) { 544 avmr.set(this->drawState(), *matrix, explicitCoordMask); 545 } 546 547 this->drawState()->setVertexLayout(layout); 548 AutoReleaseGeometry geo(this, 4, 0); 549 if (!geo.succeeded()) { 550 GrPrintf("Failed to get space for vertices!\n"); 551 return; 552 } 553 554 int stageOffsets[GrDrawState::kNumStages]; 555 int vsize = GrDrawState::VertexSizeAndOffsetsByStage(layout, stageOffsets, NULL, NULL, NULL); 556 geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize); 557 558 for (int i = 0; i < GrDrawState::kNumStages; ++i) { 559 if (explicitCoordMask & (1 << i)) { 560 GrAssert(0 != stageOffsets[i]); 561 GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) + 562 stageOffsets[i]); 563 coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop, 564 srcRects[i]->fRight, srcRects[i]->fBottom, 565 vsize); 566 if (NULL != srcMatrices && NULL != srcMatrices[i]) { 567 srcMatrices[i]->mapPointsWithStride(coords, vsize, 4); 568 } 569 } else { 570 GrAssert(0 == stageOffsets[i]); 571 } 572 } 573 574 this->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4); 575} 576 577void GrDrawTarget::clipWillBeSet(const GrClipData* clipData) { 578} 579 580//////////////////////////////////////////////////////////////////////////////// 581 582GrDrawTarget::AutoStateRestore::AutoStateRestore() { 583 fDrawTarget = NULL; 584} 585 586GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target, 587 ASRInit init) { 588 fDrawTarget = NULL; 589 this->set(target, init); 590} 591 592GrDrawTarget::AutoStateRestore::~AutoStateRestore() { 593 if (NULL != fDrawTarget) { 594 fDrawTarget->setDrawState(fSavedState); 595 fSavedState->unref(); 596 } 597} 598 599void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target, ASRInit init) { 600 GrAssert(NULL == fDrawTarget); 601 fDrawTarget = target; 602 fSavedState = target->drawState(); 603 GrAssert(fSavedState); 604 fSavedState->ref(); 605 if (kReset_ASRInit == init) { 606 // calls the default cons 607 fTempState.init(); 608 } else { 609 GrAssert(kPreserve_ASRInit == init); 610 // calls the copy cons 611 fTempState.set(*fSavedState); 612 } 613 target->setDrawState(fTempState.get()); 614} 615 616//////////////////////////////////////////////////////////////////////////////// 617 618GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry( 619 GrDrawTarget* target, 620 int vertexCount, 621 int indexCount) { 622 fTarget = NULL; 623 this->set(target, vertexCount, indexCount); 624} 625 626GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() { 627 fTarget = NULL; 628} 629 630GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() { 631 this->reset(); 632} 633 634bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget* target, 635 int vertexCount, 636 int indexCount) { 637 this->reset(); 638 fTarget = target; 639 bool success = true; 640 if (NULL != fTarget) { 641 fTarget = target; 642 success = target->reserveVertexAndIndexSpace(vertexCount, 643 indexCount, 644 &fVertices, 645 &fIndices); 646 if (!success) { 647 fTarget = NULL; 648 this->reset(); 649 } 650 } 651 GrAssert(success == (NULL != fTarget)); 652 return success; 653} 654 655void GrDrawTarget::AutoReleaseGeometry::reset() { 656 if (NULL != fTarget) { 657 if (NULL != fVertices) { 658 fTarget->resetVertexSource(); 659 } 660 if (NULL != fIndices) { 661 fTarget->resetIndexSource(); 662 } 663 fTarget = NULL; 664 } 665 fVertices = NULL; 666 fIndices = NULL; 667} 668 669GrDrawTarget::AutoClipRestore::AutoClipRestore(GrDrawTarget* target, const SkIRect& newClip) { 670 fTarget = target; 671 fClip = fTarget->getClip(); 672 fStack.init(); 673 fStack.get()->clipDevRect(newClip, SkRegion::kReplace_Op); 674 fReplacementClip.fClipStack = fStack.get(); 675 target->setClip(&fReplacementClip); 676} 677 678void GrDrawTarget::Caps::print() const { 679 static const char* gNY[] = {"NO", "YES"}; 680 GrPrintf("8 Bit Palette Support : %s\n", gNY[fInternals.f8BitPaletteSupport]); 681 GrPrintf("NPOT Texture Tile Support : %s\n", gNY[fInternals.fNPOTTextureTileSupport]); 682 GrPrintf("Two Sided Stencil Support : %s\n", gNY[fInternals.fTwoSidedStencilSupport]); 683 GrPrintf("Stencil Wrap Ops Support : %s\n", gNY[fInternals.fStencilWrapOpsSupport]); 684 GrPrintf("HW AA Lines Support : %s\n", gNY[fInternals.fHWAALineSupport]); 685 GrPrintf("Shader Derivative Support : %s\n", gNY[fInternals.fShaderDerivativeSupport]); 686 GrPrintf("Geometry Shader Support : %s\n", gNY[fInternals.fGeometryShaderSupport]); 687 GrPrintf("FSAA Support : %s\n", gNY[fInternals.fFSAASupport]); 688 GrPrintf("Dual Source Blending Support: %s\n", gNY[fInternals.fDualSourceBlendingSupport]); 689 GrPrintf("Buffer Lock Support : %s\n", gNY[fInternals.fBufferLockSupport]); 690 GrPrintf("Path Stenciling Support : %s\n", gNY[fInternals.fPathStencilingSupport]); 691 GrPrintf("Max Texture Size : %d\n", fInternals.fMaxTextureSize); 692 GrPrintf("Max Render Target Size : %d\n", fInternals.fMaxRenderTargetSize); 693} 694