GrDrawTarget.cpp revision 40d4bd8dafe9ed844f29a3de3d8965672248ee73
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 "GrContext.h" 13#include "GrDrawTargetCaps.h" 14#include "GrPath.h" 15#include "GrRenderTarget.h" 16#include "GrSurfacePriv.h" 17#include "GrTemplates.h" 18#include "GrTexture.h" 19#include "GrVertexBuffer.h" 20 21#include "SkStrokeRec.h" 22 23//////////////////////////////////////////////////////////////////////////////// 24 25GrDrawTarget::DrawInfo& GrDrawTarget::DrawInfo::operator =(const DrawInfo& di) { 26 fPrimitiveType = di.fPrimitiveType; 27 fStartVertex = di.fStartVertex; 28 fStartIndex = di.fStartIndex; 29 fVertexCount = di.fVertexCount; 30 fIndexCount = di.fIndexCount; 31 32 fInstanceCount = di.fInstanceCount; 33 fVerticesPerInstance = di.fVerticesPerInstance; 34 fIndicesPerInstance = di.fIndicesPerInstance; 35 36 if (di.fDevBounds) { 37 SkASSERT(di.fDevBounds == &di.fDevBoundsStorage); 38 fDevBoundsStorage = di.fDevBoundsStorage; 39 fDevBounds = &fDevBoundsStorage; 40 } else { 41 fDevBounds = NULL; 42 } 43 44 this->setVertexBuffer(di.vertexBuffer()); 45 this->setIndexBuffer(di.indexBuffer()); 46 47 return *this; 48} 49 50#ifdef SK_DEBUG 51bool GrDrawTarget::DrawInfo::isInstanced() const { 52 if (fInstanceCount > 0) { 53 SkASSERT(0 == fIndexCount % fIndicesPerInstance); 54 SkASSERT(0 == fVertexCount % fVerticesPerInstance); 55 SkASSERT(fIndexCount / fIndicesPerInstance == fInstanceCount); 56 SkASSERT(fVertexCount / fVerticesPerInstance == fInstanceCount); 57 // there is no way to specify a non-zero start index to drawIndexedInstances(). 58 SkASSERT(0 == fStartIndex); 59 return true; 60 } else { 61 SkASSERT(!fVerticesPerInstance); 62 SkASSERT(!fIndicesPerInstance); 63 return false; 64 } 65} 66#endif 67 68void GrDrawTarget::DrawInfo::adjustInstanceCount(int instanceOffset) { 69 SkASSERT(this->isInstanced()); 70 SkASSERT(instanceOffset + fInstanceCount >= 0); 71 fInstanceCount += instanceOffset; 72 fVertexCount = fVerticesPerInstance * fInstanceCount; 73 fIndexCount = fIndicesPerInstance * fInstanceCount; 74} 75 76void GrDrawTarget::DrawInfo::adjustStartVertex(int vertexOffset) { 77 fStartVertex += vertexOffset; 78 SkASSERT(fStartVertex >= 0); 79} 80 81void GrDrawTarget::DrawInfo::adjustStartIndex(int indexOffset) { 82 SkASSERT(this->isIndexed()); 83 fStartIndex += indexOffset; 84 SkASSERT(fStartIndex >= 0); 85} 86 87//////////////////////////////////////////////////////////////////////////////// 88 89#define DEBUG_INVAL_BUFFER 0xdeadcafe 90#define DEBUG_INVAL_START_IDX -1 91 92GrDrawTarget::GrDrawTarget(GrContext* context) 93 : fClip(NULL) 94 , fContext(context) 95 , fGpuTraceMarkerCount(0) { 96 SkASSERT(context); 97 GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back(); 98#ifdef SK_DEBUG 99 geoSrc.fVertexCount = DEBUG_INVAL_START_IDX; 100 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; 101 geoSrc.fIndexCount = DEBUG_INVAL_START_IDX; 102 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; 103#endif 104 geoSrc.fVertexSrc = kNone_GeometrySrcType; 105 geoSrc.fIndexSrc = kNone_GeometrySrcType; 106} 107 108GrDrawTarget::~GrDrawTarget() { 109 SkASSERT(1 == fGeoSrcStateStack.count()); 110 SkDEBUGCODE(GeometrySrcState& geoSrc = fGeoSrcStateStack.back()); 111 SkASSERT(kNone_GeometrySrcType == geoSrc.fIndexSrc); 112 SkASSERT(kNone_GeometrySrcType == geoSrc.fVertexSrc); 113} 114 115void GrDrawTarget::releaseGeometry() { 116 int popCnt = fGeoSrcStateStack.count() - 1; 117 while (popCnt) { 118 this->popGeometrySource(); 119 --popCnt; 120 } 121 this->resetVertexSource(); 122 this->resetIndexSource(); 123} 124 125void GrDrawTarget::setClip(const GrClipData* clip) { 126 fClip = clip; 127} 128 129const GrClipData* GrDrawTarget::getClip() const { 130 return fClip; 131} 132 133bool GrDrawTarget::reserveVertexSpace(size_t vertexSize, 134 int vertexCount, 135 void** vertices) { 136 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 137 bool acquired = false; 138 if (vertexCount > 0) { 139 SkASSERT(vertices); 140 this->releasePreviousVertexSource(); 141 geoSrc.fVertexSrc = kNone_GeometrySrcType; 142 143 acquired = this->onReserveVertexSpace(vertexSize, 144 vertexCount, 145 vertices); 146 } 147 if (acquired) { 148 geoSrc.fVertexSrc = kReserved_GeometrySrcType; 149 geoSrc.fVertexCount = vertexCount; 150 geoSrc.fVertexSize = vertexSize; 151 } else if (vertices) { 152 *vertices = NULL; 153 } 154 return acquired; 155} 156 157bool GrDrawTarget::reserveIndexSpace(int indexCount, 158 void** indices) { 159 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 160 bool acquired = false; 161 if (indexCount > 0) { 162 SkASSERT(indices); 163 this->releasePreviousIndexSource(); 164 geoSrc.fIndexSrc = kNone_GeometrySrcType; 165 166 acquired = this->onReserveIndexSpace(indexCount, indices); 167 } 168 if (acquired) { 169 geoSrc.fIndexSrc = kReserved_GeometrySrcType; 170 geoSrc.fIndexCount = indexCount; 171 } else if (indices) { 172 *indices = NULL; 173 } 174 return acquired; 175 176} 177 178bool GrDrawTarget::reserveVertexAndIndexSpace(int vertexCount, 179 size_t vertexStride, 180 int indexCount, 181 void** vertices, 182 void** indices) { 183 this->willReserveVertexAndIndexSpace(vertexCount, vertexStride, indexCount); 184 if (vertexCount) { 185 if (!this->reserveVertexSpace(vertexStride, vertexCount, vertices)) { 186 if (indexCount) { 187 this->resetIndexSource(); 188 } 189 return false; 190 } 191 } 192 if (indexCount) { 193 if (!this->reserveIndexSpace(indexCount, indices)) { 194 if (vertexCount) { 195 this->resetVertexSource(); 196 } 197 return false; 198 } 199 } 200 return true; 201} 202 203bool GrDrawTarget::geometryHints(size_t vertexStride, 204 int32_t* vertexCount, 205 int32_t* indexCount) const { 206 if (vertexCount) { 207 *vertexCount = -1; 208 } 209 if (indexCount) { 210 *indexCount = -1; 211 } 212 return false; 213} 214 215void GrDrawTarget::releasePreviousVertexSource() { 216 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 217 switch (geoSrc.fVertexSrc) { 218 case kNone_GeometrySrcType: 219 break; 220 case kReserved_GeometrySrcType: 221 this->releaseReservedVertexSpace(); 222 break; 223 case kBuffer_GeometrySrcType: 224 geoSrc.fVertexBuffer->unref(); 225#ifdef SK_DEBUG 226 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; 227#endif 228 break; 229 default: 230 SkFAIL("Unknown Vertex Source Type."); 231 break; 232 } 233} 234 235void GrDrawTarget::releasePreviousIndexSource() { 236 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 237 switch (geoSrc.fIndexSrc) { 238 case kNone_GeometrySrcType: // these two don't require 239 break; 240 case kReserved_GeometrySrcType: 241 this->releaseReservedIndexSpace(); 242 break; 243 case kBuffer_GeometrySrcType: 244 geoSrc.fIndexBuffer->unref(); 245#ifdef SK_DEBUG 246 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; 247#endif 248 break; 249 default: 250 SkFAIL("Unknown Index Source Type."); 251 break; 252 } 253} 254 255void GrDrawTarget::setVertexSourceToBuffer(const GrVertexBuffer* buffer, size_t vertexStride) { 256 this->releasePreviousVertexSource(); 257 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 258 geoSrc.fVertexSrc = kBuffer_GeometrySrcType; 259 geoSrc.fVertexBuffer = buffer; 260 buffer->ref(); 261 geoSrc.fVertexSize = vertexStride; 262} 263 264void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) { 265 this->releasePreviousIndexSource(); 266 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 267 geoSrc.fIndexSrc = kBuffer_GeometrySrcType; 268 geoSrc.fIndexBuffer = buffer; 269 buffer->ref(); 270} 271 272void GrDrawTarget::resetVertexSource() { 273 this->releasePreviousVertexSource(); 274 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 275 geoSrc.fVertexSrc = kNone_GeometrySrcType; 276} 277 278void GrDrawTarget::resetIndexSource() { 279 this->releasePreviousIndexSource(); 280 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 281 geoSrc.fIndexSrc = kNone_GeometrySrcType; 282} 283 284void GrDrawTarget::pushGeometrySource() { 285 this->geometrySourceWillPush(); 286 GeometrySrcState& newState = fGeoSrcStateStack.push_back(); 287 newState.fIndexSrc = kNone_GeometrySrcType; 288 newState.fVertexSrc = kNone_GeometrySrcType; 289#ifdef SK_DEBUG 290 newState.fVertexCount = ~0; 291 newState.fVertexBuffer = (GrVertexBuffer*)~0; 292 newState.fIndexCount = ~0; 293 newState.fIndexBuffer = (GrIndexBuffer*)~0; 294#endif 295} 296 297void GrDrawTarget::popGeometrySource() { 298 // if popping last element then pops are unbalanced with pushes 299 SkASSERT(fGeoSrcStateStack.count() > 1); 300 301 this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1)); 302 this->releasePreviousVertexSource(); 303 this->releasePreviousIndexSource(); 304 fGeoSrcStateStack.pop_back(); 305} 306 307//////////////////////////////////////////////////////////////////////////////// 308 309bool GrDrawTarget::checkDraw(const GrDrawState& drawState, 310 const GrGeometryProcessor* gp, 311 GrPrimitiveType type, 312 int startVertex, 313 int startIndex, 314 int vertexCount, 315 int indexCount) const { 316#ifdef SK_DEBUG 317 const GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 318 int maxVertex = startVertex + vertexCount; 319 int maxValidVertex; 320 switch (geoSrc.fVertexSrc) { 321 case kNone_GeometrySrcType: 322 SkFAIL("Attempting to draw without vertex src."); 323 case kReserved_GeometrySrcType: // fallthrough 324 maxValidVertex = geoSrc.fVertexCount; 325 break; 326 case kBuffer_GeometrySrcType: 327 maxValidVertex = static_cast<int>(geoSrc.fVertexBuffer->gpuMemorySize() / geoSrc.fVertexSize); 328 break; 329 } 330 if (maxVertex > maxValidVertex) { 331 SkFAIL("Drawing outside valid vertex range."); 332 } 333 if (indexCount > 0) { 334 int maxIndex = startIndex + indexCount; 335 int maxValidIndex; 336 switch (geoSrc.fIndexSrc) { 337 case kNone_GeometrySrcType: 338 SkFAIL("Attempting to draw indexed geom without index src."); 339 case kReserved_GeometrySrcType: // fallthrough 340 maxValidIndex = geoSrc.fIndexCount; 341 break; 342 case kBuffer_GeometrySrcType: 343 maxValidIndex = static_cast<int>(geoSrc.fIndexBuffer->gpuMemorySize() / sizeof(uint16_t)); 344 break; 345 } 346 if (maxIndex > maxValidIndex) { 347 SkFAIL("Index reads outside valid index range."); 348 } 349 } 350 351 SkASSERT(drawState.getRenderTarget()); 352 353 if (gp) { 354 int numTextures = gp->numTextures(); 355 for (int t = 0; t < numTextures; ++t) { 356 GrTexture* texture = gp->texture(t); 357 SkASSERT(texture->asRenderTarget() != drawState.getRenderTarget()); 358 } 359 } 360 361 for (int s = 0; s < drawState.numColorStages(); ++s) { 362 const GrProcessor* effect = drawState.getColorStage(s).processor(); 363 int numTextures = effect->numTextures(); 364 for (int t = 0; t < numTextures; ++t) { 365 GrTexture* texture = effect->texture(t); 366 SkASSERT(texture->asRenderTarget() != drawState.getRenderTarget()); 367 } 368 } 369 for (int s = 0; s < drawState.numCoverageStages(); ++s) { 370 const GrProcessor* effect = drawState.getCoverageStage(s).processor(); 371 int numTextures = effect->numTextures(); 372 for (int t = 0; t < numTextures; ++t) { 373 GrTexture* texture = effect->texture(t); 374 SkASSERT(texture->asRenderTarget() != drawState.getRenderTarget()); 375 } 376 } 377 378#endif 379 if (NULL == drawState.getRenderTarget()) { 380 return false; 381 } 382 return true; 383} 384 385bool GrDrawTarget::setupDstReadIfNecessary(GrDrawState* ds, 386 const GrPrimitiveProcessor* primProc, 387 GrDeviceCoordTexture* dstCopy, 388 const SkRect* drawBounds) { 389 if (this->caps()->dstReadInShaderSupport() || !ds->willEffectReadDstColor(primProc)) { 390 return true; 391 } 392 SkIRect copyRect; 393 const GrClipData* clip = this->getClip(); 394 GrRenderTarget* rt = ds->getRenderTarget(); 395 clip->getConservativeBounds(rt, ©Rect); 396 397 if (drawBounds) { 398 SkIRect drawIBounds; 399 drawBounds->roundOut(&drawIBounds); 400 if (!copyRect.intersect(drawIBounds)) { 401#ifdef SK_DEBUG 402 SkDebugf("Missed an early reject. Bailing on draw from setupDstReadIfNecessary.\n"); 403#endif 404 return false; 405 } 406 } else { 407#ifdef SK_DEBUG 408 //SkDebugf("No dev bounds when dst copy is made.\n"); 409#endif 410 } 411 412 // MSAA consideration: When there is support for reading MSAA samples in the shader we could 413 // have per-sample dst values by making the copy multisampled. 414 GrSurfaceDesc desc; 415 this->initCopySurfaceDstDesc(rt, &desc); 416 desc.fWidth = copyRect.width(); 417 desc.fHeight = copyRect.height(); 418 419 SkAutoTUnref<GrTexture> copy( 420 fContext->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch)); 421 422 if (!copy) { 423 SkDebugf("Failed to create temporary copy of destination texture.\n"); 424 return false; 425 } 426 SkIPoint dstPoint = {0, 0}; 427 if (this->copySurface(copy, rt, copyRect, dstPoint)) { 428 dstCopy->setTexture(copy); 429 dstCopy->setOffset(copyRect.fLeft, copyRect.fTop); 430 return true; 431 } else { 432 return false; 433 } 434} 435 436void GrDrawTarget::drawIndexed(GrDrawState* ds, 437 const GrGeometryProcessor* gp, 438 GrPrimitiveType type, 439 int startVertex, 440 int startIndex, 441 int vertexCount, 442 int indexCount, 443 const SkRect* devBounds) { 444 SkASSERT(ds); 445 if (indexCount > 0 && 446 this->checkDraw(*ds, gp, type, startVertex, startIndex, vertexCount, indexCount)) { 447 448 // Setup clip 449 GrScissorState scissorState; 450 GrDrawState::AutoRestoreEffects are; 451 GrDrawState::AutoRestoreStencil ars; 452 if (!this->setupClip(devBounds, &are, &ars, ds, &scissorState)) { 453 return; 454 } 455 456 DrawInfo info; 457 info.fPrimitiveType = type; 458 info.fStartVertex = startVertex; 459 info.fStartIndex = startIndex; 460 info.fVertexCount = vertexCount; 461 info.fIndexCount = indexCount; 462 463 info.fInstanceCount = 0; 464 info.fVerticesPerInstance = 0; 465 info.fIndicesPerInstance = 0; 466 467 if (devBounds) { 468 info.setDevBounds(*devBounds); 469 } 470 471 // TODO: We should continue with incorrect blending. 472 GrDeviceCoordTexture dstCopy; 473 if (!this->setupDstReadIfNecessary(ds, gp, &dstCopy, devBounds)) { 474 return; 475 } 476 this->setDrawBuffers(&info, gp->getVertexStride()); 477 478 this->onDraw(*ds, gp, info, scissorState, dstCopy.texture() ? &dstCopy : NULL); 479 } 480} 481 482void GrDrawTarget::drawNonIndexed(GrDrawState* ds, 483 const GrGeometryProcessor* gp, 484 GrPrimitiveType type, 485 int startVertex, 486 int vertexCount, 487 const SkRect* devBounds) { 488 SkASSERT(ds); 489 if (vertexCount > 0 && this->checkDraw(*ds, gp, type, startVertex, -1, vertexCount, -1)) { 490 491 // Setup clip 492 GrScissorState scissorState; 493 GrDrawState::AutoRestoreEffects are; 494 GrDrawState::AutoRestoreStencil ars; 495 if (!this->setupClip(devBounds, &are, &ars, ds, &scissorState)) { 496 return; 497 } 498 499 DrawInfo info; 500 info.fPrimitiveType = type; 501 info.fStartVertex = startVertex; 502 info.fStartIndex = 0; 503 info.fVertexCount = vertexCount; 504 info.fIndexCount = 0; 505 506 info.fInstanceCount = 0; 507 info.fVerticesPerInstance = 0; 508 info.fIndicesPerInstance = 0; 509 510 if (devBounds) { 511 info.setDevBounds(*devBounds); 512 } 513 514 // TODO: We should continue with incorrect blending. 515 GrDeviceCoordTexture dstCopy; 516 if (!this->setupDstReadIfNecessary(ds, gp, &dstCopy, devBounds)) { 517 return; 518 } 519 520 this->setDrawBuffers(&info, gp->getVertexStride()); 521 522 this->onDraw(*ds, gp, info, scissorState, dstCopy.texture() ? &dstCopy : NULL); 523 } 524} 525 526static const GrStencilSettings& winding_path_stencil_settings() { 527 GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings, 528 kIncClamp_StencilOp, 529 kIncClamp_StencilOp, 530 kAlwaysIfInClip_StencilFunc, 531 0xFFFF, 0xFFFF, 0xFFFF); 532 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); 533} 534 535static const GrStencilSettings& even_odd_path_stencil_settings() { 536 GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings, 537 kInvert_StencilOp, 538 kInvert_StencilOp, 539 kAlwaysIfInClip_StencilFunc, 540 0xFFFF, 0xFFFF, 0xFFFF); 541 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); 542} 543 544void GrDrawTarget::getPathStencilSettingsForFilltype(GrPathRendering::FillType fill, 545 const GrStencilBuffer* sb, 546 GrStencilSettings* outStencilSettings) { 547 548 switch (fill) { 549 default: 550 SkFAIL("Unexpected path fill."); 551 case GrPathRendering::kWinding_FillType: 552 *outStencilSettings = winding_path_stencil_settings(); 553 break; 554 case GrPathRendering::kEvenOdd_FillType: 555 *outStencilSettings = even_odd_path_stencil_settings(); 556 break; 557 } 558 this->clipMaskManager()->adjustPathStencilParams(sb, outStencilSettings); 559} 560 561void GrDrawTarget::stencilPath(GrDrawState* ds, 562 const GrPathProcessor* pathProc, 563 const GrPath* path, 564 GrPathRendering::FillType fill) { 565 // TODO: extract portions of checkDraw that are relevant to path stenciling. 566 SkASSERT(path); 567 SkASSERT(this->caps()->pathRenderingSupport()); 568 SkASSERT(ds); 569 570 // Setup clip 571 GrScissorState scissorState; 572 GrDrawState::AutoRestoreEffects are; 573 GrDrawState::AutoRestoreStencil ars; 574 if (!this->setupClip(NULL, &are, &ars, ds, &scissorState)) { 575 return; 576 } 577 578 // set stencil settings for path 579 GrStencilSettings stencilSettings; 580 this->getPathStencilSettingsForFilltype(fill, 581 ds->getRenderTarget()->getStencilBuffer(), 582 &stencilSettings); 583 584 this->onStencilPath(*ds, pathProc, path, scissorState, stencilSettings); 585} 586 587void GrDrawTarget::drawPath(GrDrawState* ds, 588 const GrPathProcessor* pathProc, 589 const GrPath* path, 590 GrPathRendering::FillType fill) { 591 // TODO: extract portions of checkDraw that are relevant to path rendering. 592 SkASSERT(path); 593 SkASSERT(this->caps()->pathRenderingSupport()); 594 SkASSERT(ds); 595 596 SkRect devBounds = path->getBounds(); 597 SkMatrix viewM = ds->getViewMatrix(); 598 viewM.mapRect(&devBounds); 599 600 // Setup clip 601 GrScissorState scissorState; 602 GrDrawState::AutoRestoreEffects are; 603 GrDrawState::AutoRestoreStencil ars; 604 if (!this->setupClip(&devBounds, &are, &ars, ds, &scissorState)) { 605 return; 606 } 607 608 // set stencil settings for path 609 GrStencilSettings stencilSettings; 610 this->getPathStencilSettingsForFilltype(fill, 611 ds->getRenderTarget()->getStencilBuffer(), 612 &stencilSettings); 613 614 GrDeviceCoordTexture dstCopy; 615 if (!this->setupDstReadIfNecessary(ds, pathProc, &dstCopy, &devBounds)) { 616 return; 617 } 618 619 this->onDrawPath(*ds, pathProc, path, scissorState, stencilSettings, dstCopy.texture() ? &dstCopy : 620 NULL); 621} 622 623void GrDrawTarget::drawPaths(GrDrawState* ds, 624 const GrPathProcessor* pathProc, 625 const GrPathRange* pathRange, 626 const void* indices, 627 PathIndexType indexType, 628 const float transformValues[], 629 PathTransformType transformType, 630 int count, 631 GrPathRendering::FillType fill) { 632 SkASSERT(this->caps()->pathRenderingSupport()); 633 SkASSERT(pathRange); 634 SkASSERT(indices); 635 SkASSERT(0 == reinterpret_cast<long>(indices) % GrPathRange::PathIndexSizeInBytes(indexType)); 636 SkASSERT(transformValues); 637 SkASSERT(ds); 638 639 // Setup clip 640 GrScissorState scissorState; 641 GrDrawState::AutoRestoreEffects are; 642 GrDrawState::AutoRestoreStencil ars; 643 644 if (!this->setupClip(NULL, &are, &ars, ds, &scissorState)) { 645 return; 646 } 647 648 // set stencil settings for path 649 GrStencilSettings stencilSettings; 650 this->getPathStencilSettingsForFilltype(fill, 651 ds->getRenderTarget()->getStencilBuffer(), 652 &stencilSettings); 653 654 // Don't compute a bounding box for setupDstReadIfNecessary(), we'll opt 655 // instead for it to just copy the entire dst. Realistically this is a moot 656 // point, because any context that supports NV_path_rendering will also 657 // support NV_blend_equation_advanced. 658 GrDeviceCoordTexture dstCopy; 659 if (!this->setupDstReadIfNecessary(ds, pathProc, &dstCopy, NULL)) { 660 return; 661 } 662 663 this->onDrawPaths(*ds, pathProc, pathRange, indices, indexType, transformValues, transformType, 664 count, scissorState, stencilSettings, dstCopy.texture() ? &dstCopy : NULL); 665} 666 667void GrDrawTarget::clear(const SkIRect* rect, 668 GrColor color, 669 bool canIgnoreRect, 670 GrRenderTarget* renderTarget) { 671 if (fCaps->useDrawInsteadOfClear()) { 672 // This works around a driver bug with clear by drawing a rect instead. 673 // The driver will ignore a clear if it is the only thing rendered to a 674 // target before the target is read. 675 SkIRect rtRect = SkIRect::MakeWH(renderTarget->width(), renderTarget->height()); 676 if (NULL == rect || canIgnoreRect || rect->contains(rtRect)) { 677 rect = &rtRect; 678 // We first issue a discard() since that may help tilers. 679 this->discard(renderTarget); 680 } 681 682 GrDrawState drawState; 683 drawState.setRenderTarget(renderTarget); 684 685 this->drawSimpleRect(&drawState, color, *rect); 686 } else { 687 this->onClear(rect, color, canIgnoreRect, renderTarget); 688 } 689} 690 691typedef GrTraceMarkerSet::Iter TMIter; 692void GrDrawTarget::saveActiveTraceMarkers() { 693 if (this->caps()->gpuTracingSupport()) { 694 SkASSERT(0 == fStoredTraceMarkers.count()); 695 fStoredTraceMarkers.addSet(fActiveTraceMarkers); 696 for (TMIter iter = fStoredTraceMarkers.begin(); iter != fStoredTraceMarkers.end(); ++iter) { 697 this->removeGpuTraceMarker(&(*iter)); 698 } 699 } 700} 701 702void GrDrawTarget::restoreActiveTraceMarkers() { 703 if (this->caps()->gpuTracingSupport()) { 704 SkASSERT(0 == fActiveTraceMarkers.count()); 705 for (TMIter iter = fStoredTraceMarkers.begin(); iter != fStoredTraceMarkers.end(); ++iter) { 706 this->addGpuTraceMarker(&(*iter)); 707 } 708 for (TMIter iter = fActiveTraceMarkers.begin(); iter != fActiveTraceMarkers.end(); ++iter) { 709 this->fStoredTraceMarkers.remove(*iter); 710 } 711 } 712} 713 714void GrDrawTarget::addGpuTraceMarker(const GrGpuTraceMarker* marker) { 715 if (this->caps()->gpuTracingSupport()) { 716 SkASSERT(fGpuTraceMarkerCount >= 0); 717 this->fActiveTraceMarkers.add(*marker); 718 ++fGpuTraceMarkerCount; 719 } 720} 721 722void GrDrawTarget::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { 723 if (this->caps()->gpuTracingSupport()) { 724 SkASSERT(fGpuTraceMarkerCount >= 1); 725 this->fActiveTraceMarkers.remove(*marker); 726 --fGpuTraceMarkerCount; 727 } 728} 729 730//////////////////////////////////////////////////////////////////////////////// 731 732void GrDrawTarget::drawIndexedInstances(GrDrawState* ds, 733 const GrGeometryProcessor* gp, 734 GrPrimitiveType type, 735 int instanceCount, 736 int verticesPerInstance, 737 int indicesPerInstance, 738 const SkRect* devBounds) { 739 SkASSERT(ds); 740 741 if (!verticesPerInstance || !indicesPerInstance) { 742 return; 743 } 744 745 int maxInstancesPerDraw = this->indexCountInCurrentSource() / indicesPerInstance; 746 if (!maxInstancesPerDraw) { 747 return; 748 } 749 750 // Setup clip 751 GrScissorState scissorState; 752 GrDrawState::AutoRestoreEffects are; 753 GrDrawState::AutoRestoreStencil ars; 754 if (!this->setupClip(devBounds, &are, &ars, ds, &scissorState)) { 755 return; 756 } 757 758 DrawInfo info; 759 info.fPrimitiveType = type; 760 info.fStartIndex = 0; 761 info.fStartVertex = 0; 762 info.fIndicesPerInstance = indicesPerInstance; 763 info.fVerticesPerInstance = verticesPerInstance; 764 765 // Set the same bounds for all the draws. 766 if (devBounds) { 767 info.setDevBounds(*devBounds); 768 } 769 770 // TODO: We should continue with incorrect blending. 771 GrDeviceCoordTexture dstCopy; 772 if (!this->setupDstReadIfNecessary(ds, gp, &dstCopy,devBounds)) { 773 return; 774 } 775 776 while (instanceCount) { 777 info.fInstanceCount = SkTMin(instanceCount, maxInstancesPerDraw); 778 info.fVertexCount = info.fInstanceCount * verticesPerInstance; 779 info.fIndexCount = info.fInstanceCount * indicesPerInstance; 780 781 if (this->checkDraw(*ds, 782 gp, 783 type, 784 info.fStartVertex, 785 info.fStartIndex, 786 info.fVertexCount, 787 info.fIndexCount)) { 788 this->setDrawBuffers(&info, gp->getVertexStride()); 789 this->onDraw(*ds, gp, info, scissorState, dstCopy.texture() ? &dstCopy : NULL); 790 } 791 info.fStartVertex += info.fVertexCount; 792 instanceCount -= info.fInstanceCount; 793 } 794} 795 796//////////////////////////////////////////////////////////////////////////////// 797 798GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry( 799 GrDrawTarget* target, 800 int vertexCount, 801 size_t vertexStride, 802 int indexCount) { 803 fTarget = NULL; 804 this->set(target, vertexCount, vertexStride, indexCount); 805} 806 807GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() { 808 fTarget = NULL; 809} 810 811GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() { 812 this->reset(); 813} 814 815bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget* target, 816 int vertexCount, 817 size_t vertexStride, 818 int indexCount) { 819 this->reset(); 820 fTarget = target; 821 bool success = true; 822 if (fTarget) { 823 success = target->reserveVertexAndIndexSpace(vertexCount, 824 vertexStride, 825 indexCount, 826 &fVertices, 827 &fIndices); 828 if (!success) { 829 fTarget = NULL; 830 this->reset(); 831 } 832 } 833 SkASSERT(success == SkToBool(fTarget)); 834 return success; 835} 836 837void GrDrawTarget::AutoReleaseGeometry::reset() { 838 if (fTarget) { 839 if (fVertices) { 840 fTarget->resetVertexSource(); 841 } 842 if (fIndices) { 843 fTarget->resetIndexSource(); 844 } 845 fTarget = NULL; 846 } 847 fVertices = NULL; 848 fIndices = NULL; 849} 850 851GrDrawTarget::AutoClipRestore::AutoClipRestore(GrDrawTarget* target, const SkIRect& newClip) { 852 fTarget = target; 853 fClip = fTarget->getClip(); 854 fStack.init(); 855 fStack.get()->clipDevRect(newClip, SkRegion::kReplace_Op); 856 fReplacementClip.fClipStack = fStack.get(); 857 target->setClip(&fReplacementClip); 858} 859 860namespace { 861// returns true if the read/written rect intersects the src/dst and false if not. 862bool clip_srcrect_and_dstpoint(const GrSurface* dst, 863 const GrSurface* src, 864 const SkIRect& srcRect, 865 const SkIPoint& dstPoint, 866 SkIRect* clippedSrcRect, 867 SkIPoint* clippedDstPoint) { 868 *clippedSrcRect = srcRect; 869 *clippedDstPoint = dstPoint; 870 871 // clip the left edge to src and dst bounds, adjusting dstPoint if necessary 872 if (clippedSrcRect->fLeft < 0) { 873 clippedDstPoint->fX -= clippedSrcRect->fLeft; 874 clippedSrcRect->fLeft = 0; 875 } 876 if (clippedDstPoint->fX < 0) { 877 clippedSrcRect->fLeft -= clippedDstPoint->fX; 878 clippedDstPoint->fX = 0; 879 } 880 881 // clip the top edge to src and dst bounds, adjusting dstPoint if necessary 882 if (clippedSrcRect->fTop < 0) { 883 clippedDstPoint->fY -= clippedSrcRect->fTop; 884 clippedSrcRect->fTop = 0; 885 } 886 if (clippedDstPoint->fY < 0) { 887 clippedSrcRect->fTop -= clippedDstPoint->fY; 888 clippedDstPoint->fY = 0; 889 } 890 891 // clip the right edge to the src and dst bounds. 892 if (clippedSrcRect->fRight > src->width()) { 893 clippedSrcRect->fRight = src->width(); 894 } 895 if (clippedDstPoint->fX + clippedSrcRect->width() > dst->width()) { 896 clippedSrcRect->fRight = clippedSrcRect->fLeft + dst->width() - clippedDstPoint->fX; 897 } 898 899 // clip the bottom edge to the src and dst bounds. 900 if (clippedSrcRect->fBottom > src->height()) { 901 clippedSrcRect->fBottom = src->height(); 902 } 903 if (clippedDstPoint->fY + clippedSrcRect->height() > dst->height()) { 904 clippedSrcRect->fBottom = clippedSrcRect->fTop + dst->height() - clippedDstPoint->fY; 905 } 906 907 // The above clipping steps may have inverted the rect if it didn't intersect either the src or 908 // dst bounds. 909 return !clippedSrcRect->isEmpty(); 910} 911} 912 913bool GrDrawTarget::copySurface(GrSurface* dst, 914 GrSurface* src, 915 const SkIRect& srcRect, 916 const SkIPoint& dstPoint) { 917 SkASSERT(dst); 918 SkASSERT(src); 919 920 SkIRect clippedSrcRect; 921 SkIPoint clippedDstPoint; 922 // If the rect is outside the src or dst then we've already succeeded. 923 if (!clip_srcrect_and_dstpoint(dst, 924 src, 925 srcRect, 926 dstPoint, 927 &clippedSrcRect, 928 &clippedDstPoint)) { 929 return true; 930 } 931 932 if (this->onCopySurface(dst, src, clippedSrcRect, clippedDstPoint)) { 933 return true; 934 } 935 936 GrRenderTarget* rt = dst->asRenderTarget(); 937 GrTexture* tex = src->asTexture(); 938 939 if ((dst == src) || !rt || !tex) { 940 return false; 941 } 942 943 GrDrawState drawState; 944 drawState.setRenderTarget(rt); 945 SkMatrix matrix; 946 matrix.setTranslate(SkIntToScalar(clippedSrcRect.fLeft - clippedDstPoint.fX), 947 SkIntToScalar(clippedSrcRect.fTop - clippedDstPoint.fY)); 948 matrix.postIDiv(tex->width(), tex->height()); 949 drawState.addColorTextureProcessor(tex, matrix); 950 SkIRect dstRect = SkIRect::MakeXYWH(clippedDstPoint.fX, 951 clippedDstPoint.fY, 952 clippedSrcRect.width(), 953 clippedSrcRect.height()); 954 this->drawSimpleRect(&drawState, GrColor_WHITE, dstRect); 955 return true; 956} 957 958bool GrDrawTarget::canCopySurface(const GrSurface* dst, 959 const GrSurface* src, 960 const SkIRect& srcRect, 961 const SkIPoint& dstPoint) { 962 SkASSERT(dst); 963 SkASSERT(src); 964 965 SkIRect clippedSrcRect; 966 SkIPoint clippedDstPoint; 967 // If the rect is outside the src or dst then we're guaranteed success 968 if (!clip_srcrect_and_dstpoint(dst, 969 src, 970 srcRect, 971 dstPoint, 972 &clippedSrcRect, 973 &clippedDstPoint)) { 974 return true; 975 } 976 return this->internalCanCopySurface(dst, src, clippedSrcRect, clippedDstPoint); 977} 978 979bool GrDrawTarget::internalCanCopySurface(const GrSurface* dst, 980 const GrSurface* src, 981 const SkIRect& clippedSrcRect, 982 const SkIPoint& clippedDstPoint) { 983 // Check that the read/write rects are contained within the src/dst bounds. 984 SkASSERT(!clippedSrcRect.isEmpty()); 985 SkASSERT(SkIRect::MakeWH(src->width(), src->height()).contains(clippedSrcRect)); 986 SkASSERT(clippedDstPoint.fX >= 0 && clippedDstPoint.fY >= 0); 987 SkASSERT(clippedDstPoint.fX + clippedSrcRect.width() <= dst->width() && 988 clippedDstPoint.fY + clippedSrcRect.height() <= dst->height()); 989 990 // The base class can do it as a draw or the subclass may be able to handle it. 991 return ((dst != src) && dst->asRenderTarget() && src->asTexture()) || 992 this->onCanCopySurface(dst, src, clippedSrcRect, clippedDstPoint); 993} 994 995/////////////////////////////////////////////////////////////////////////////// 996 997void GrDrawTargetCaps::reset() { 998 fMipMapSupport = false; 999 fNPOTTextureTileSupport = false; 1000 fTwoSidedStencilSupport = false; 1001 fStencilWrapOpsSupport = false; 1002 fHWAALineSupport = false; 1003 fShaderDerivativeSupport = false; 1004 fGeometryShaderSupport = false; 1005 fDualSourceBlendingSupport = false; 1006 fPathRenderingSupport = false; 1007 fDstReadInShaderSupport = false; 1008 fDiscardRenderTargetSupport = false; 1009 fReuseScratchTextures = true; 1010 fGpuTracingSupport = false; 1011 fCompressedTexSubImageSupport = false; 1012 1013 fUseDrawInsteadOfClear = false; 1014 1015 fMapBufferFlags = kNone_MapFlags; 1016 1017 fMaxRenderTargetSize = 0; 1018 fMaxTextureSize = 0; 1019 fMaxSampleCount = 0; 1020 1021 fShaderPrecisionVaries = false; 1022 1023 memset(fConfigRenderSupport, 0, sizeof(fConfigRenderSupport)); 1024 memset(fConfigTextureSupport, 0, sizeof(fConfigTextureSupport)); 1025} 1026 1027GrDrawTargetCaps& GrDrawTargetCaps::operator=(const GrDrawTargetCaps& other) { 1028 fMipMapSupport = other.fMipMapSupport; 1029 fNPOTTextureTileSupport = other.fNPOTTextureTileSupport; 1030 fTwoSidedStencilSupport = other.fTwoSidedStencilSupport; 1031 fStencilWrapOpsSupport = other.fStencilWrapOpsSupport; 1032 fHWAALineSupport = other.fHWAALineSupport; 1033 fShaderDerivativeSupport = other.fShaderDerivativeSupport; 1034 fGeometryShaderSupport = other.fGeometryShaderSupport; 1035 fDualSourceBlendingSupport = other.fDualSourceBlendingSupport; 1036 fPathRenderingSupport = other.fPathRenderingSupport; 1037 fDstReadInShaderSupport = other.fDstReadInShaderSupport; 1038 fDiscardRenderTargetSupport = other.fDiscardRenderTargetSupport; 1039 fReuseScratchTextures = other.fReuseScratchTextures; 1040 fGpuTracingSupport = other.fGpuTracingSupport; 1041 fCompressedTexSubImageSupport = other.fCompressedTexSubImageSupport; 1042 1043 fUseDrawInsteadOfClear = other.fUseDrawInsteadOfClear; 1044 1045 fMapBufferFlags = other.fMapBufferFlags; 1046 1047 fMaxRenderTargetSize = other.fMaxRenderTargetSize; 1048 fMaxTextureSize = other.fMaxTextureSize; 1049 fMaxSampleCount = other.fMaxSampleCount; 1050 1051 memcpy(fConfigRenderSupport, other.fConfigRenderSupport, sizeof(fConfigRenderSupport)); 1052 memcpy(fConfigTextureSupport, other.fConfigTextureSupport, sizeof(fConfigTextureSupport)); 1053 1054 fShaderPrecisionVaries = other.fShaderPrecisionVaries; 1055 for (int s = 0; s < kGrShaderTypeCount; ++s) { 1056 for (int p = 0; p < kGrSLPrecisionCount; ++p) { 1057 fFloatPrecisions[s][p] = other.fFloatPrecisions[s][p]; 1058 } 1059 } 1060 return *this; 1061} 1062 1063static SkString map_flags_to_string(uint32_t flags) { 1064 SkString str; 1065 if (GrDrawTargetCaps::kNone_MapFlags == flags) { 1066 str = "none"; 1067 } else { 1068 SkASSERT(GrDrawTargetCaps::kCanMap_MapFlag & flags); 1069 SkDEBUGCODE(flags &= ~GrDrawTargetCaps::kCanMap_MapFlag); 1070 str = "can_map"; 1071 1072 if (GrDrawTargetCaps::kSubset_MapFlag & flags) { 1073 str.append(" partial"); 1074 } else { 1075 str.append(" full"); 1076 } 1077 SkDEBUGCODE(flags &= ~GrDrawTargetCaps::kSubset_MapFlag); 1078 } 1079 SkASSERT(0 == flags); // Make sure we handled all the flags. 1080 return str; 1081} 1082 1083static const char* shader_type_to_string(GrShaderType type) { 1084 switch (type) { 1085 case kVertex_GrShaderType: 1086 return "vertex"; 1087 case kGeometry_GrShaderType: 1088 return "geometry"; 1089 case kFragment_GrShaderType: 1090 return "fragment"; 1091 } 1092 return ""; 1093} 1094 1095static const char* precision_to_string(GrSLPrecision p) { 1096 switch (p) { 1097 case kLow_GrSLPrecision: 1098 return "low"; 1099 case kMedium_GrSLPrecision: 1100 return "medium"; 1101 case kHigh_GrSLPrecision: 1102 return "high"; 1103 } 1104 return ""; 1105} 1106 1107SkString GrDrawTargetCaps::dump() const { 1108 SkString r; 1109 static const char* gNY[] = {"NO", "YES"}; 1110 r.appendf("MIP Map Support : %s\n", gNY[fMipMapSupport]); 1111 r.appendf("NPOT Texture Tile Support : %s\n", gNY[fNPOTTextureTileSupport]); 1112 r.appendf("Two Sided Stencil Support : %s\n", gNY[fTwoSidedStencilSupport]); 1113 r.appendf("Stencil Wrap Ops Support : %s\n", gNY[fStencilWrapOpsSupport]); 1114 r.appendf("HW AA Lines Support : %s\n", gNY[fHWAALineSupport]); 1115 r.appendf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport]); 1116 r.appendf("Geometry Shader Support : %s\n", gNY[fGeometryShaderSupport]); 1117 r.appendf("Dual Source Blending Support : %s\n", gNY[fDualSourceBlendingSupport]); 1118 r.appendf("Path Rendering Support : %s\n", gNY[fPathRenderingSupport]); 1119 r.appendf("Dst Read In Shader Support : %s\n", gNY[fDstReadInShaderSupport]); 1120 r.appendf("Discard Render Target Support : %s\n", gNY[fDiscardRenderTargetSupport]); 1121 r.appendf("Reuse Scratch Textures : %s\n", gNY[fReuseScratchTextures]); 1122 r.appendf("Gpu Tracing Support : %s\n", gNY[fGpuTracingSupport]); 1123 r.appendf("Compressed Update Support : %s\n", gNY[fCompressedTexSubImageSupport]); 1124 1125 r.appendf("Draw Instead of Clear [workaround] : %s\n", gNY[fUseDrawInsteadOfClear]); 1126 1127 r.appendf("Max Texture Size : %d\n", fMaxTextureSize); 1128 r.appendf("Max Render Target Size : %d\n", fMaxRenderTargetSize); 1129 r.appendf("Max Sample Count : %d\n", fMaxSampleCount); 1130 1131 r.appendf("Map Buffer Support : %s\n", 1132 map_flags_to_string(fMapBufferFlags).c_str()); 1133 1134 static const char* kConfigNames[] = { 1135 "Unknown", // kUnknown_GrPixelConfig 1136 "Alpha8", // kAlpha_8_GrPixelConfig, 1137 "Index8", // kIndex_8_GrPixelConfig, 1138 "RGB565", // kRGB_565_GrPixelConfig, 1139 "RGBA444", // kRGBA_4444_GrPixelConfig, 1140 "RGBA8888", // kRGBA_8888_GrPixelConfig, 1141 "BGRA8888", // kBGRA_8888_GrPixelConfig, 1142 "SRGBA8888",// kSRGBA_8888_GrPixelConfig, 1143 "ETC1", // kETC1_GrPixelConfig, 1144 "LATC", // kLATC_GrPixelConfig, 1145 "R11EAC", // kR11_EAC_GrPixelConfig, 1146 "ASTC12x12",// kASTC_12x12_GrPixelConfig, 1147 "RGBAFloat",// kRGBA_float_GrPixelConfig 1148 "AlphaHalf",// kAlpha_half_GrPixelConfig 1149 }; 1150 GR_STATIC_ASSERT(0 == kUnknown_GrPixelConfig); 1151 GR_STATIC_ASSERT(1 == kAlpha_8_GrPixelConfig); 1152 GR_STATIC_ASSERT(2 == kIndex_8_GrPixelConfig); 1153 GR_STATIC_ASSERT(3 == kRGB_565_GrPixelConfig); 1154 GR_STATIC_ASSERT(4 == kRGBA_4444_GrPixelConfig); 1155 GR_STATIC_ASSERT(5 == kRGBA_8888_GrPixelConfig); 1156 GR_STATIC_ASSERT(6 == kBGRA_8888_GrPixelConfig); 1157 GR_STATIC_ASSERT(7 == kSRGBA_8888_GrPixelConfig); 1158 GR_STATIC_ASSERT(8 == kETC1_GrPixelConfig); 1159 GR_STATIC_ASSERT(9 == kLATC_GrPixelConfig); 1160 GR_STATIC_ASSERT(10 == kR11_EAC_GrPixelConfig); 1161 GR_STATIC_ASSERT(11 == kASTC_12x12_GrPixelConfig); 1162 GR_STATIC_ASSERT(12 == kRGBA_float_GrPixelConfig); 1163 GR_STATIC_ASSERT(13 == kAlpha_half_GrPixelConfig); 1164 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kConfigNames) == kGrPixelConfigCnt); 1165 1166 SkASSERT(!fConfigRenderSupport[kUnknown_GrPixelConfig][0]); 1167 SkASSERT(!fConfigRenderSupport[kUnknown_GrPixelConfig][1]); 1168 1169 for (size_t i = 1; i < SK_ARRAY_COUNT(kConfigNames); ++i) { 1170 r.appendf("%s is renderable: %s, with MSAA: %s\n", 1171 kConfigNames[i], 1172 gNY[fConfigRenderSupport[i][0]], 1173 gNY[fConfigRenderSupport[i][1]]); 1174 } 1175 1176 SkASSERT(!fConfigTextureSupport[kUnknown_GrPixelConfig]); 1177 1178 for (size_t i = 1; i < SK_ARRAY_COUNT(kConfigNames); ++i) { 1179 r.appendf("%s is uploadable to a texture: %s\n", 1180 kConfigNames[i], 1181 gNY[fConfigTextureSupport[i]]); 1182 } 1183 1184 r.appendf("Shader Float Precisions (varies: %s):\n", gNY[fShaderPrecisionVaries]); 1185 1186 for (int s = 0; s < kGrShaderTypeCount; ++s) { 1187 GrShaderType shaderType = static_cast<GrShaderType>(s); 1188 r.appendf("\t%s:\n", shader_type_to_string(shaderType)); 1189 for (int p = 0; p < kGrSLPrecisionCount; ++p) { 1190 if (fFloatPrecisions[s][p].supported()) { 1191 GrSLPrecision precision = static_cast<GrSLPrecision>(p); 1192 r.appendf("\t\t%s: log_low: %d log_high: %d bits: %d\n", 1193 precision_to_string(precision), 1194 fFloatPrecisions[s][p].fLogRangeLow, 1195 fFloatPrecisions[s][p].fLogRangeHigh, 1196 fFloatPrecisions[s][p].fBits); 1197 } 1198 } 1199 } 1200 1201 return r; 1202} 1203 1204uint32_t GrDrawTargetCaps::CreateUniqueID() { 1205 static int32_t gUniqueID = SK_InvalidUniqueID; 1206 uint32_t id; 1207 do { 1208 id = static_cast<uint32_t>(sk_atomic_inc(&gUniqueID) + 1); 1209 } while (id == SK_InvalidUniqueID); 1210 return id; 1211} 1212 1213/////////////////////////////////////////////////////////////////////////////////////////////////// 1214 1215bool GrClipTarget::setupClip(const SkRect* devBounds, 1216 GrDrawState::AutoRestoreEffects* are, 1217 GrDrawState::AutoRestoreStencil* ars, 1218 GrDrawState* ds, 1219 GrScissorState* scissorState) { 1220 return fClipMaskManager.setupClipping(ds, 1221 are, 1222 ars, 1223 scissorState, 1224 this->getClip(), 1225 devBounds); 1226} 1227