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 18 SK_DEFINE_INST_COUNT(GrDrawTarget) 19 20 //////////////////////////////////////////////////////////////////////////////// 21 22 GrDrawTarget::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 44 bool 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 61 void 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 69 void GrDrawTarget::DrawInfo::adjustStartVertex(int vertexOffset) { 70 fStartVertex += vertexOffset; 71 GrAssert(fStartVertex >= 0); 72 } 73 74 void 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 85 GrDrawTarget::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 100 GrDrawTarget::~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 108 void 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 118 void GrDrawTarget::setClip(const GrClipData* clip) { 119 clipWillBeSet(clip); 120 fClip = clip; 121 } 122 123 const GrClipData* GrDrawTarget::getClip() const { 124 return fClip; 125 } 126 127 void 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 139 bool GrDrawTarget::reserveVertexSpace(GrVertexLayout vertexLayout, 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(GrDrawState::VertexSize(vertexLayout), 150 vertexCount, 151 vertices); 152 } 153 if (acquired) { 154 geoSrc.fVertexSrc = kReserved_GeometrySrcType; 155 geoSrc.fVertexCount = vertexCount; 156 geoSrc.fVertexLayout = vertexLayout; 157 } else if (NULL != vertices) { 158 *vertices = NULL; 159 } 160 return acquired; 161 } 162 163 bool 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 184 bool GrDrawTarget::reserveVertexAndIndexSpace(GrVertexLayout vertexLayout, 185 int vertexCount, 186 int indexCount, 187 void** vertices, 188 void** indices) { 189 this->willReserveVertexAndIndexSpace(GrDrawState::VertexSize(vertexLayout), vertexCount, indexCount); 190 if (vertexCount) { 191 if (!this->reserveVertexSpace(vertexLayout, 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 209 bool GrDrawTarget::geometryHints(size_t vertexSize, 210 int32_t* vertexCount, 211 int32_t* indexCount) const { 212 if (NULL != vertexCount) { 213 *vertexCount = -1; 214 } 215 if (NULL != indexCount) { 216 *indexCount = -1; 217 } 218 return false; 219 } 220 221 void GrDrawTarget::releasePreviousVertexSource() { 222 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 223 switch (geoSrc.fVertexSrc) { 224 case kNone_GeometrySrcType: 225 break; 226 case kArray_GeometrySrcType: 227 this->releaseVertexArray(); 228 break; 229 case kReserved_GeometrySrcType: 230 this->releaseReservedVertexSpace(); 231 break; 232 case kBuffer_GeometrySrcType: 233 geoSrc.fVertexBuffer->unref(); 234 #if GR_DEBUG 235 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; 236 #endif 237 break; 238 default: 239 GrCrash("Unknown Vertex Source Type."); 240 break; 241 } 242 } 243 244 void GrDrawTarget::releasePreviousIndexSource() { 245 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 246 switch (geoSrc.fIndexSrc) { 247 case kNone_GeometrySrcType: // these two don't require 248 break; 249 case kArray_GeometrySrcType: 250 this->releaseIndexArray(); 251 break; 252 case kReserved_GeometrySrcType: 253 this->releaseReservedIndexSpace(); 254 break; 255 case kBuffer_GeometrySrcType: 256 geoSrc.fIndexBuffer->unref(); 257 #if GR_DEBUG 258 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; 259 #endif 260 break; 261 default: 262 GrCrash("Unknown Index Source Type."); 263 break; 264 } 265 } 266 267 void GrDrawTarget::setVertexSourceToArray(GrVertexLayout vertexLayout, 268 const void* vertexArray, 269 int vertexCount) { 270 this->releasePreviousVertexSource(); 271 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 272 geoSrc.fVertexSrc = kArray_GeometrySrcType; 273 geoSrc.fVertexLayout = vertexLayout; 274 geoSrc.fVertexCount = vertexCount; 275 this->onSetVertexSourceToArray(vertexArray, vertexCount); 276 } 277 278 void GrDrawTarget::setIndexSourceToArray(const void* indexArray, 279 int indexCount) { 280 this->releasePreviousIndexSource(); 281 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 282 geoSrc.fIndexSrc = kArray_GeometrySrcType; 283 geoSrc.fIndexCount = indexCount; 284 this->onSetIndexSourceToArray(indexArray, indexCount); 285 } 286 287 void GrDrawTarget::setVertexSourceToBuffer(GrVertexLayout vertexLayout, 288 const GrVertexBuffer* buffer) { 289 this->releasePreviousVertexSource(); 290 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 291 geoSrc.fVertexSrc = kBuffer_GeometrySrcType; 292 geoSrc.fVertexBuffer = buffer; 293 buffer->ref(); 294 geoSrc.fVertexLayout = vertexLayout; 295 } 296 297 void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) { 298 this->releasePreviousIndexSource(); 299 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 300 geoSrc.fIndexSrc = kBuffer_GeometrySrcType; 301 geoSrc.fIndexBuffer = buffer; 302 buffer->ref(); 303 } 304 305 void GrDrawTarget::resetVertexSource() { 306 this->releasePreviousVertexSource(); 307 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 308 geoSrc.fVertexSrc = kNone_GeometrySrcType; 309 } 310 311 void GrDrawTarget::resetIndexSource() { 312 this->releasePreviousIndexSource(); 313 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 314 geoSrc.fIndexSrc = kNone_GeometrySrcType; 315 } 316 317 void GrDrawTarget::pushGeometrySource() { 318 this->geometrySourceWillPush(); 319 GeometrySrcState& newState = fGeoSrcStateStack.push_back(); 320 newState.fIndexSrc = kNone_GeometrySrcType; 321 newState.fVertexSrc = kNone_GeometrySrcType; 322 #if GR_DEBUG 323 newState.fVertexCount = ~0; 324 newState.fVertexBuffer = (GrVertexBuffer*)~0; 325 newState.fIndexCount = ~0; 326 newState.fIndexBuffer = (GrIndexBuffer*)~0; 327 #endif 328 } 329 330 void GrDrawTarget::popGeometrySource() { 331 // if popping last element then pops are unbalanced with pushes 332 GrAssert(fGeoSrcStateStack.count() > 1); 333 334 this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1)); 335 this->releasePreviousVertexSource(); 336 this->releasePreviousIndexSource(); 337 fGeoSrcStateStack.pop_back(); 338 } 339 340 //////////////////////////////////////////////////////////////////////////////// 341 342 bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex, 343 int startIndex, int vertexCount, 344 int indexCount) const { 345 const GrDrawState& drawState = this->getDrawState(); 346 #if GR_DEBUG 347 const GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 348 int maxVertex = startVertex + vertexCount; 349 int maxValidVertex; 350 switch (geoSrc.fVertexSrc) { 351 case kNone_GeometrySrcType: 352 GrCrash("Attempting to draw without vertex src."); 353 case kReserved_GeometrySrcType: // fallthrough 354 case kArray_GeometrySrcType: 355 maxValidVertex = geoSrc.fVertexCount; 356 break; 357 case kBuffer_GeometrySrcType: 358 maxValidVertex = geoSrc.fVertexBuffer->sizeInBytes() / GrDrawState::VertexSize(geoSrc.fVertexLayout); 359 break; 360 } 361 if (maxVertex > maxValidVertex) { 362 GrCrash("Drawing outside valid vertex range."); 363 } 364 if (indexCount > 0) { 365 int maxIndex = startIndex + indexCount; 366 int maxValidIndex; 367 switch (geoSrc.fIndexSrc) { 368 case kNone_GeometrySrcType: 369 GrCrash("Attempting to draw indexed geom without index src."); 370 case kReserved_GeometrySrcType: // fallthrough 371 case kArray_GeometrySrcType: 372 maxValidIndex = geoSrc.fIndexCount; 373 break; 374 case kBuffer_GeometrySrcType: 375 maxValidIndex = geoSrc.fIndexBuffer->sizeInBytes() / sizeof(uint16_t); 376 break; 377 } 378 if (maxIndex > maxValidIndex) { 379 GrCrash("Index reads outside valid index range."); 380 } 381 } 382 383 GrAssert(NULL != drawState.getRenderTarget()); 384 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 385 if (drawState.isStageEnabled(s)) { 386 const GrEffectRef& effect = *drawState.getStage(s).getEffect(); 387 int numTextures = effect->numTextures(); 388 for (int t = 0; t < numTextures; ++t) { 389 GrTexture* texture = effect->texture(t); 390 GrAssert(texture->asRenderTarget() != drawState.getRenderTarget()); 391 } 392 } 393 } 394 #endif 395 if (NULL == drawState.getRenderTarget()) { 396 return false; 397 } 398 return true; 399 } 400 401 void GrDrawTarget::drawIndexed(GrPrimitiveType type, 402 int startVertex, 403 int startIndex, 404 int vertexCount, 405 int indexCount, 406 const SkRect* devBounds) { 407 if (indexCount > 0 && this->checkDraw(type, startVertex, startIndex, vertexCount, indexCount)) { 408 DrawInfo info; 409 info.fPrimitiveType = type; 410 info.fStartVertex = startVertex; 411 info.fStartIndex = startIndex; 412 info.fVertexCount = vertexCount; 413 info.fIndexCount = indexCount; 414 415 info.fInstanceCount = 0; 416 info.fVerticesPerInstance = 0; 417 info.fIndicesPerInstance = 0; 418 419 if (NULL != devBounds) { 420 info.setDevBounds(*devBounds); 421 } 422 this->onDraw(info); 423 } 424 } 425 426 void GrDrawTarget::drawNonIndexed(GrPrimitiveType type, 427 int startVertex, 428 int vertexCount, 429 const SkRect* devBounds) { 430 if (vertexCount > 0 && this->checkDraw(type, startVertex, -1, vertexCount, -1)) { 431 DrawInfo info; 432 info.fPrimitiveType = type; 433 info.fStartVertex = startVertex; 434 info.fStartIndex = 0; 435 info.fVertexCount = vertexCount; 436 info.fIndexCount = 0; 437 438 info.fInstanceCount = 0; 439 info.fVerticesPerInstance = 0; 440 info.fIndicesPerInstance = 0; 441 442 if (NULL != devBounds) { 443 info.setDevBounds(*devBounds); 444 } 445 this->onDraw(info); 446 } 447 } 448 449 void GrDrawTarget::stencilPath(const GrPath* path, const SkStrokeRec& stroke, SkPath::FillType fill) { 450 // TODO: extract portions of checkDraw that are relevant to path stenciling. 451 GrAssert(NULL != path); 452 GrAssert(fCaps.pathStencilingSupport()); 453 GrAssert(!stroke.isHairlineStyle()); 454 GrAssert(!SkPath::IsInverseFillType(fill)); 455 this->onStencilPath(path, stroke, fill); 456 } 457 458 //////////////////////////////////////////////////////////////////////////////// 459 460 // Some blend modes allow folding a partial coverage value into the color's 461 // alpha channel, while others will blend incorrectly. 462 bool GrDrawTarget::canTweakAlphaForCoverage() const { 463 /** 464 * The fractional coverage is f 465 * The src and dst coeffs are Cs and Cd 466 * The dst and src colors are S and D 467 * We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D 468 * By tweaking the source color's alpha we're replacing S with S'=fS. It's 469 * obvious that that first term will always be ok. The second term can be 470 * rearranged as [1-(1-Cd)f]D. By substituting in the various possibilities 471 * for Cd we find that only 1, ISA, and ISC produce the correct depth 472 * coefficient in terms of S' and D. 473 */ 474 GrBlendCoeff dstCoeff = this->getDrawState().getDstBlendCoeff(); 475 return kOne_GrBlendCoeff == dstCoeff || 476 kISA_GrBlendCoeff == dstCoeff || 477 kISC_GrBlendCoeff == dstCoeff || 478 this->getDrawState().isCoverageDrawing(); 479 } 480 481 namespace { 482 GrVertexLayout default_blend_opts_vertex_layout() { 483 GrVertexLayout layout = 0; 484 return layout; 485 } 486 } 487 488 GrDrawTarget::BlendOptFlags 489 GrDrawTarget::getBlendOpts(bool forceCoverage, 490 GrBlendCoeff* srcCoeff, 491 GrBlendCoeff* dstCoeff) const { 492 493 GrVertexLayout layout; 494 if (kNone_GeometrySrcType == this->getGeomSrc().fVertexSrc) { 495 layout = default_blend_opts_vertex_layout(); 496 } else { 497 layout = this->getVertexLayout(); 498 } 499 500 const GrDrawState& drawState = this->getDrawState(); 501 502 GrBlendCoeff bogusSrcCoeff, bogusDstCoeff; 503 if (NULL == srcCoeff) { 504 srcCoeff = &bogusSrcCoeff; 505 } 506 *srcCoeff = drawState.getSrcBlendCoeff(); 507 508 if (NULL == dstCoeff) { 509 dstCoeff = &bogusDstCoeff; 510 } 511 *dstCoeff = drawState.getDstBlendCoeff(); 512 513 if (drawState.isColorWriteDisabled()) { 514 *srcCoeff = kZero_GrBlendCoeff; 515 *dstCoeff = kOne_GrBlendCoeff; 516 } 517 518 bool srcAIsOne = drawState.srcAlphaWillBeOne(layout); 519 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff || 520 (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne); 521 bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff || 522 (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne); 523 524 bool covIsZero = !drawState.isCoverageDrawing() && 525 !(layout & GrDrawState::kCoverage_VertexLayoutBit) && 526 0 == drawState.getCoverage(); 527 // When coeffs are (0,1) there is no reason to draw at all, unless 528 // stenciling is enabled. Having color writes disabled is effectively 529 // (0,1). The same applies when coverage is known to be 0. 530 if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne) || covIsZero) { 531 if (drawState.getStencil().doesWrite()) { 532 return kDisableBlend_BlendOptFlag | 533 kEmitTransBlack_BlendOptFlag; 534 } else { 535 return kSkipDraw_BlendOptFlag; 536 } 537 } 538 539 // check for coverage due to constant coverage, per-vertex coverage, 540 // edge aa or coverage stage 541 bool hasCoverage = forceCoverage || 542 0xffffffff != drawState.getCoverage() || 543 (layout & GrDrawState::kCoverage_VertexLayoutBit) || 544 (layout & GrDrawState::kEdge_VertexLayoutBit); 545 for (int s = drawState.getFirstCoverageStage(); 546 !hasCoverage && s < GrDrawState::kNumStages; 547 ++s) { 548 if (drawState.isStageEnabled(s)) { 549 hasCoverage = true; 550 } 551 } 552 553 // if we don't have coverage we can check whether the dst 554 // has to read at all. If not, we'll disable blending. 555 if (!hasCoverage) { 556 if (dstCoeffIsZero) { 557 if (kOne_GrBlendCoeff == *srcCoeff) { 558 // if there is no coverage and coeffs are (1,0) then we 559 // won't need to read the dst at all, it gets replaced by src 560 return kDisableBlend_BlendOptFlag; 561 } else if (kZero_GrBlendCoeff == *srcCoeff) { 562 // if the op is "clear" then we don't need to emit a color 563 // or blend, just write transparent black into the dst. 564 *srcCoeff = kOne_GrBlendCoeff; 565 *dstCoeff = kZero_GrBlendCoeff; 566 return kDisableBlend_BlendOptFlag | kEmitTransBlack_BlendOptFlag; 567 } 568 } 569 } else if (drawState.isCoverageDrawing()) { 570 // we have coverage but we aren't distinguishing it from alpha by request. 571 return kCoverageAsAlpha_BlendOptFlag; 572 } else { 573 // check whether coverage can be safely rolled into alpha 574 // of if we can skip color computation and just emit coverage 575 if (this->canTweakAlphaForCoverage()) { 576 return kCoverageAsAlpha_BlendOptFlag; 577 } 578 if (dstCoeffIsZero) { 579 if (kZero_GrBlendCoeff == *srcCoeff) { 580 // the source color is not included in the blend 581 // the dst coeff is effectively zero so blend works out to: 582 // (c)(0)D + (1-c)D = (1-c)D. 583 *dstCoeff = kISA_GrBlendCoeff; 584 return kEmitCoverage_BlendOptFlag; 585 } else if (srcAIsOne) { 586 // the dst coeff is effectively zero so blend works out to: 587 // cS + (c)(0)D + (1-c)D = cS + (1-c)D. 588 // If Sa is 1 then we can replace Sa with c 589 // and set dst coeff to 1-Sa. 590 *dstCoeff = kISA_GrBlendCoeff; 591 return kCoverageAsAlpha_BlendOptFlag; 592 } 593 } else if (dstCoeffIsOne) { 594 // the dst coeff is effectively one so blend works out to: 595 // cS + (c)(1)D + (1-c)D = cS + D. 596 *dstCoeff = kOne_GrBlendCoeff; 597 return kCoverageAsAlpha_BlendOptFlag; 598 } 599 } 600 return kNone_BlendOpt; 601 } 602 603 bool GrDrawTarget::willUseHWAALines() const { 604 // there is a conflict between using smooth lines and our use of 605 // premultiplied alpha. Smooth lines tweak the incoming alpha value 606 // but not in a premul-alpha way. So we only use them when our alpha 607 // is 0xff and tweaking the color for partial coverage is OK 608 if (!fCaps.hwAALineSupport() || 609 !this->getDrawState().isHWAntialiasState()) { 610 return false; 611 } 612 BlendOptFlags opts = this->getBlendOpts(); 613 return (kDisableBlend_BlendOptFlag & opts) && 614 (kCoverageAsAlpha_BlendOptFlag & opts); 615 } 616 617 bool GrDrawTarget::canApplyCoverage() const { 618 // we can correctly apply coverage if a) we have dual source blending 619 // or b) one of our blend optimizations applies. 620 return this->getCaps().dualSourceBlendingSupport() || 621 kNone_BlendOpt != this->getBlendOpts(true); 622 } 623 624 //////////////////////////////////////////////////////////////////////////////// 625 626 void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type, 627 int instanceCount, 628 int verticesPerInstance, 629 int indicesPerInstance, 630 const SkRect* devBounds) { 631 if (!verticesPerInstance || !indicesPerInstance) { 632 return; 633 } 634 635 int maxInstancesPerDraw = this->indexCountInCurrentSource() / indicesPerInstance; 636 if (!maxInstancesPerDraw) { 637 return; 638 } 639 640 DrawInfo info; 641 info.fPrimitiveType = type; 642 info.fStartIndex = 0; 643 info.fStartVertex = 0; 644 info.fIndicesPerInstance = indicesPerInstance; 645 info.fVerticesPerInstance = verticesPerInstance; 646 647 // Set the same bounds for all the draws. 648 if (NULL != devBounds) { 649 info.setDevBounds(*devBounds); 650 } 651 652 while (instanceCount) { 653 info.fInstanceCount = GrMin(instanceCount, maxInstancesPerDraw); 654 info.fVertexCount = info.fInstanceCount * verticesPerInstance; 655 info.fIndexCount = info.fInstanceCount * indicesPerInstance; 656 657 if (this->checkDraw(type, 658 info.fStartVertex, 659 info.fStartIndex, 660 info.fVertexCount, 661 info.fIndexCount)) { 662 this->onDraw(info); 663 } 664 info.fStartVertex += info.fVertexCount; 665 instanceCount -= info.fInstanceCount; 666 } 667 } 668 669 //////////////////////////////////////////////////////////////////////////////// 670 671 void GrDrawTarget::drawRect(const GrRect& rect, 672 const SkMatrix* matrix, 673 const GrRect* srcRects[], 674 const SkMatrix* srcMatrices[]) { 675 GrVertexLayout layout = 0; 676 uint32_t explicitCoordMask = 0; 677 678 if (NULL != srcRects) { 679 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 680 int numTC = 0; 681 if (NULL != srcRects[s]) { 682 layout |= GrDrawState::StageTexCoordVertexLayoutBit(s, numTC); 683 explicitCoordMask |= (1 << s); 684 ++numTC; 685 } 686 } 687 } 688 689 GrDrawState::AutoViewMatrixRestore avmr; 690 if (NULL != matrix) { 691 avmr.set(this->drawState(), *matrix, explicitCoordMask); 692 } 693 694 AutoReleaseGeometry geo(this, layout, 4, 0); 695 if (!geo.succeeded()) { 696 GrPrintf("Failed to get space for vertices!\n"); 697 return; 698 } 699 700 int stageOffsets[GrDrawState::kNumStages]; 701 int vsize = GrDrawState::VertexSizeAndOffsetsByStage(layout, stageOffsets, NULL, NULL, NULL); 702 geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize); 703 704 for (int i = 0; i < GrDrawState::kNumStages; ++i) { 705 if (explicitCoordMask & (1 << i)) { 706 GrAssert(0 != stageOffsets[i]); 707 GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) + 708 stageOffsets[i]); 709 coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop, 710 srcRects[i]->fRight, srcRects[i]->fBottom, 711 vsize); 712 if (NULL != srcMatrices && NULL != srcMatrices[i]) { 713 srcMatrices[i]->mapPointsWithStride(coords, vsize, 4); 714 } 715 } else { 716 GrAssert(0 == stageOffsets[i]); 717 } 718 } 719 720 this->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4); 721 } 722 723 void GrDrawTarget::clipWillBeSet(const GrClipData* clipData) { 724 } 725 726 //////////////////////////////////////////////////////////////////////////////// 727 728 GrDrawTarget::AutoStateRestore::AutoStateRestore() { 729 fDrawTarget = NULL; 730 } 731 732 GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target, 733 ASRInit init) { 734 fDrawTarget = NULL; 735 this->set(target, init); 736 } 737 738 GrDrawTarget::AutoStateRestore::~AutoStateRestore() { 739 if (NULL != fDrawTarget) { 740 fDrawTarget->setDrawState(fSavedState); 741 fSavedState->unref(); 742 } 743 } 744 745 void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target, ASRInit init) { 746 GrAssert(NULL == fDrawTarget); 747 fDrawTarget = target; 748 fSavedState = target->drawState(); 749 GrAssert(fSavedState); 750 fSavedState->ref(); 751 if (kReset_ASRInit == init) { 752 // calls the default cons 753 fTempState.init(); 754 } else { 755 GrAssert(kPreserve_ASRInit == init); 756 // calls the copy cons 757 fTempState.set(*fSavedState); 758 } 759 target->setDrawState(fTempState.get()); 760 } 761 762 //////////////////////////////////////////////////////////////////////////////// 763 764 GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry( 765 GrDrawTarget* target, 766 GrVertexLayout vertexLayout, 767 int vertexCount, 768 int indexCount) { 769 fTarget = NULL; 770 this->set(target, vertexLayout, vertexCount, indexCount); 771 } 772 773 GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() { 774 fTarget = NULL; 775 } 776 777 GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() { 778 this->reset(); 779 } 780 781 bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget* target, 782 GrVertexLayout vertexLayout, 783 int vertexCount, 784 int indexCount) { 785 this->reset(); 786 fTarget = target; 787 bool success = true; 788 if (NULL != fTarget) { 789 fTarget = target; 790 success = target->reserveVertexAndIndexSpace(vertexLayout, 791 vertexCount, 792 indexCount, 793 &fVertices, 794 &fIndices); 795 if (!success) { 796 fTarget = NULL; 797 this->reset(); 798 } 799 } 800 GrAssert(success == (NULL != fTarget)); 801 return success; 802 } 803 804 void GrDrawTarget::AutoReleaseGeometry::reset() { 805 if (NULL != fTarget) { 806 if (NULL != fVertices) { 807 fTarget->resetVertexSource(); 808 } 809 if (NULL != fIndices) { 810 fTarget->resetIndexSource(); 811 } 812 fTarget = NULL; 813 } 814 fVertices = NULL; 815 fIndices = NULL; 816 } 817 818 GrDrawTarget::AutoClipRestore::AutoClipRestore(GrDrawTarget* target, const SkIRect& newClip) { 819 fTarget = target; 820 fClip = fTarget->getClip(); 821 fStack.init(); 822 fStack.get()->clipDevRect(newClip, SkRegion::kReplace_Op); 823 fReplacementClip.fClipStack = fStack.get(); 824 target->setClip(&fReplacementClip); 825 } 826 827 void GrDrawTarget::Caps::print() const { 828 static const char* gNY[] = {"NO", "YES"}; 829 GrPrintf("8 Bit Palette Support : %s\n", gNY[fInternals.f8BitPaletteSupport]); 830 GrPrintf("NPOT Texture Tile Support : %s\n", gNY[fInternals.fNPOTTextureTileSupport]); 831 GrPrintf("Two Sided Stencil Support : %s\n", gNY[fInternals.fTwoSidedStencilSupport]); 832 GrPrintf("Stencil Wrap Ops Support : %s\n", gNY[fInternals.fStencilWrapOpsSupport]); 833 GrPrintf("HW AA Lines Support : %s\n", gNY[fInternals.fHWAALineSupport]); 834 GrPrintf("Shader Derivative Support : %s\n", gNY[fInternals.fShaderDerivativeSupport]); 835 GrPrintf("Geometry Shader Support : %s\n", gNY[fInternals.fGeometryShaderSupport]); 836 GrPrintf("FSAA Support : %s\n", gNY[fInternals.fFSAASupport]); 837 GrPrintf("Dual Source Blending Support: %s\n", gNY[fInternals.fDualSourceBlendingSupport]); 838 GrPrintf("Buffer Lock Support : %s\n", gNY[fInternals.fBufferLockSupport]); 839 GrPrintf("Path Stenciling Support : %s\n", gNY[fInternals.fPathStencilingSupport]); 840 GrPrintf("Max Texture Size : %d\n", fInternals.fMaxTextureSize); 841 GrPrintf("Max Render Target Size : %d\n", fInternals.fMaxRenderTargetSize); 842 } 843