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