| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2010 Google Inc. | 3 * Copyright 2010 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 | 10 |
| 11 #include "GrDrawTarget.h" | 11 #include "GrDrawTarget.h" |
| 12 #include "GrContext.h" |
| 12 #include "GrDrawTargetCaps.h" | 13 #include "GrDrawTargetCaps.h" |
| 13 #include "GrRenderTarget.h" | 14 #include "GrRenderTarget.h" |
| 14 #include "GrTexture.h" | 15 #include "GrTexture.h" |
| 15 #include "GrVertexBuffer.h" | 16 #include "GrVertexBuffer.h" |
| 16 | 17 |
| 17 #include "SkStrokeRec.h" | 18 #include "SkStrokeRec.h" |
| 18 | 19 |
| 19 SK_DEFINE_INST_COUNT(GrDrawTarget) | 20 SK_DEFINE_INST_COUNT(GrDrawTarget) |
| 20 | 21 |
| 21 //////////////////////////////////////////////////////////////////////////////// | 22 //////////////////////////////////////////////////////////////////////////////// |
| 22 | 23 |
| 23 GrDrawTarget::DrawInfo& GrDrawTarget::DrawInfo::operator =(const DrawInfo& di) { | 24 GrDrawTarget::DrawInfo& GrDrawTarget::DrawInfo::operator =(const DrawInfo& di) { |
| 24 fPrimitiveType = di.fPrimitiveType; | 25 fPrimitiveType = di.fPrimitiveType; |
| 25 fStartVertex = di.fStartVertex; | 26 fStartVertex = di.fStartVertex; |
| 26 fStartIndex = di.fStartIndex; | 27 fStartIndex = di.fStartIndex; |
| 27 fVertexCount = di.fVertexCount; | 28 fVertexCount = di.fVertexCount; |
| 28 fIndexCount = di.fIndexCount; | 29 fIndexCount = di.fIndexCount; |
| 29 | 30 |
| 30 fInstanceCount = di.fInstanceCount; | 31 fInstanceCount = di.fInstanceCount; |
| 31 fVerticesPerInstance = di.fVerticesPerInstance; | 32 fVerticesPerInstance = di.fVerticesPerInstance; |
| 32 fIndicesPerInstance = di.fIndicesPerInstance; | 33 fIndicesPerInstance = di.fIndicesPerInstance; |
| 33 | 34 |
| 34 if (NULL != di.fDevBounds) { | 35 if (NULL != di.fDevBounds) { |
| 35 GrAssert(di.fDevBounds == &di.fDevBoundsStorage); | 36 GrAssert(di.fDevBounds == &di.fDevBoundsStorage); |
| 36 fDevBoundsStorage = di.fDevBoundsStorage; | 37 fDevBoundsStorage = di.fDevBoundsStorage; |
| 37 fDevBounds = &fDevBoundsStorage; | 38 fDevBounds = &fDevBoundsStorage; |
| 38 } else { | 39 } else { |
| 39 fDevBounds = NULL; | 40 fDevBounds = NULL; |
| 40 } | 41 } |
| 42 |
| 43 fDstCopy = di.fDstCopy; |
| 44 |
| 41 return *this; | 45 return *this; |
| 42 } | 46 } |
| 43 | 47 |
| 44 #if GR_DEBUG | 48 #if GR_DEBUG |
| 45 bool GrDrawTarget::DrawInfo::isInstanced() const { | 49 bool GrDrawTarget::DrawInfo::isInstanced() const { |
| 46 if (fInstanceCount > 0) { | 50 if (fInstanceCount > 0) { |
| 47 GrAssert(0 == fIndexCount % fIndicesPerInstance); | 51 GrAssert(0 == fIndexCount % fIndicesPerInstance); |
| 48 GrAssert(0 == fVertexCount % fVerticesPerInstance); | 52 GrAssert(0 == fVertexCount % fVerticesPerInstance); |
| 49 GrAssert(fIndexCount / fIndicesPerInstance == fInstanceCount); | 53 GrAssert(fIndexCount / fIndicesPerInstance == fInstanceCount); |
| 50 GrAssert(fVertexCount / fVerticesPerInstance == fInstanceCount); | 54 GrAssert(fVertexCount / fVerticesPerInstance == fInstanceCount); |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 } | 399 } |
| 396 | 400 |
| 397 GrAssert(drawState.validateVertexAttribs()); | 401 GrAssert(drawState.validateVertexAttribs()); |
| 398 #endif | 402 #endif |
| 399 if (NULL == drawState.getRenderTarget()) { | 403 if (NULL == drawState.getRenderTarget()) { |
| 400 return false; | 404 return false; |
| 401 } | 405 } |
| 402 return true; | 406 return true; |
| 403 } | 407 } |
| 404 | 408 |
| 409 bool GrDrawTarget::setupDstReadIfNecessary(DrawInfo* info) { |
| 410 bool willReadDst = false; |
| 411 for (int s = 0; s < GrDrawState::kNumStages; ++s) { |
| 412 const GrEffectRef* effect = this->drawState()->getStage(s).getEffect(); |
| 413 if (NULL != effect && (*effect)->willReadDst()) { |
| 414 willReadDst = true; |
| 415 break; |
| 416 } |
| 417 } |
| 418 if (!willReadDst) { |
| 419 return true; |
| 420 } |
| 421 GrRenderTarget* rt = this->drawState()->getRenderTarget(); |
| 422 // If the dst is not a texture then we don't currently have a way of copying
the |
| 423 // texture. TODO: make copying RT->Tex (or Surface->Surface) a GrDrawTarget
operation that can |
| 424 // be built on top of GL/D3D APIs. |
| 425 if (NULL == rt->asTexture()) { |
| 426 GrPrintf("Reading Dst of non-texture render target is not currently supp
orted.\n"); |
| 427 return false; |
| 428 } |
| 429 // TODO: Consider bounds of draw and bounds of clip |
| 430 |
| 431 GrDrawTarget::AutoGeometryAndStatePush agasp(this, kReset_ASRInit); |
| 432 |
| 433 // The draw will resolve dst if it has MSAA. Two things to consider in the f
uture: |
| 434 // 1) to make the dst values be pre-resolve we'd need to be able to copy to
MSAA |
| 435 // texture and sample it correctly in the shader. 2) If 1 isn't available th
en we |
| 436 // should just resolve and use the resolved texture directly rather than mak
ing a |
| 437 // copy of it. |
| 438 GrTextureDesc desc; |
| 439 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; |
| 440 desc.fWidth = rt->width(); |
| 441 desc.fHeight = rt->height(); |
| 442 desc.fSampleCnt = 0; |
| 443 desc.fConfig = rt->config(); |
| 444 |
| 445 GrAutoScratchTexture ast(fContext, desc, GrContext::kApprox_ScratchTexMatch)
; |
| 446 |
| 447 if (NULL == ast.texture()) { |
| 448 GrPrintf("Failed to create temporary copy of destination texture.\n"); |
| 449 return false; |
| 450 } |
| 451 this->drawState()->disableState(GrDrawState::kClip_StateBit); |
| 452 this->drawState()->setRenderTarget(ast.texture()->asRenderTarget()); |
| 453 static const int kTextureStage = 0; |
| 454 SkMatrix matrix; |
| 455 matrix.setIDiv(rt->width(), rt->height()); |
| 456 this->drawState()->createTextureEffect(kTextureStage, rt->asTexture(), matri
x); |
| 457 SkRect copyRect = SkRect::MakeWH(SkIntToScalar(desc.fWidth), |
| 458 SkIntToScalar(desc.fHeight)); |
| 459 this->drawRect(copyRect, NULL, ©Rect, NULL); |
| 460 info->fDstCopy.setTexture(ast.texture()); |
| 461 info->fDstCopy.setOffset(0, 0); |
| 462 return true; |
| 463 } |
| 464 |
| 405 void GrDrawTarget::drawIndexed(GrPrimitiveType type, | 465 void GrDrawTarget::drawIndexed(GrPrimitiveType type, |
| 406 int startVertex, | 466 int startVertex, |
| 407 int startIndex, | 467 int startIndex, |
| 408 int vertexCount, | 468 int vertexCount, |
| 409 int indexCount, | 469 int indexCount, |
| 410 const SkRect* devBounds) { | 470 const SkRect* devBounds) { |
| 411 if (indexCount > 0 && this->checkDraw(type, startVertex, startIndex, vertexC
ount, indexCount)) { | 471 if (indexCount > 0 && this->checkDraw(type, startVertex, startIndex, vertexC
ount, indexCount)) { |
| 412 DrawInfo info; | 472 DrawInfo info; |
| 413 info.fPrimitiveType = type; | 473 info.fPrimitiveType = type; |
| 414 info.fStartVertex = startVertex; | 474 info.fStartVertex = startVertex; |
| 415 info.fStartIndex = startIndex; | 475 info.fStartIndex = startIndex; |
| 416 info.fVertexCount = vertexCount; | 476 info.fVertexCount = vertexCount; |
| 417 info.fIndexCount = indexCount; | 477 info.fIndexCount = indexCount; |
| 418 | 478 |
| 419 info.fInstanceCount = 0; | 479 info.fInstanceCount = 0; |
| 420 info.fVerticesPerInstance = 0; | 480 info.fVerticesPerInstance = 0; |
| 421 info.fIndicesPerInstance = 0; | 481 info.fIndicesPerInstance = 0; |
| 422 | 482 |
| 423 if (NULL != devBounds) { | 483 if (NULL != devBounds) { |
| 424 info.setDevBounds(*devBounds); | 484 info.setDevBounds(*devBounds); |
| 425 } | 485 } |
| 486 // TODO: We should continue with incorrect blending. |
| 487 if (!this->setupDstReadIfNecessary(&info)) { |
| 488 return; |
| 489 } |
| 426 this->onDraw(info); | 490 this->onDraw(info); |
| 427 } | 491 } |
| 428 } | 492 } |
| 429 | 493 |
| 430 void GrDrawTarget::drawNonIndexed(GrPrimitiveType type, | 494 void GrDrawTarget::drawNonIndexed(GrPrimitiveType type, |
| 431 int startVertex, | 495 int startVertex, |
| 432 int vertexCount, | 496 int vertexCount, |
| 433 const SkRect* devBounds) { | 497 const SkRect* devBounds) { |
| 434 if (vertexCount > 0 && this->checkDraw(type, startVertex, -1, vertexCount, -
1)) { | 498 if (vertexCount > 0 && this->checkDraw(type, startVertex, -1, vertexCount, -
1)) { |
| 435 DrawInfo info; | 499 DrawInfo info; |
| 436 info.fPrimitiveType = type; | 500 info.fPrimitiveType = type; |
| 437 info.fStartVertex = startVertex; | 501 info.fStartVertex = startVertex; |
| 438 info.fStartIndex = 0; | 502 info.fStartIndex = 0; |
| 439 info.fVertexCount = vertexCount; | 503 info.fVertexCount = vertexCount; |
| 440 info.fIndexCount = 0; | 504 info.fIndexCount = 0; |
| 441 | 505 |
| 442 info.fInstanceCount = 0; | 506 info.fInstanceCount = 0; |
| 443 info.fVerticesPerInstance = 0; | 507 info.fVerticesPerInstance = 0; |
| 444 info.fIndicesPerInstance = 0; | 508 info.fIndicesPerInstance = 0; |
| 445 | 509 |
| 446 if (NULL != devBounds) { | 510 if (NULL != devBounds) { |
| 447 info.setDevBounds(*devBounds); | 511 info.setDevBounds(*devBounds); |
| 448 } | 512 } |
| 513 // TODO: We should continue with incorrect blending. |
| 514 if (!this->setupDstReadIfNecessary(&info)) { |
| 515 return; |
| 516 } |
| 449 this->onDraw(info); | 517 this->onDraw(info); |
| 450 } | 518 } |
| 451 } | 519 } |
| 452 | 520 |
| 453 void GrDrawTarget::stencilPath(const GrPath* path, const SkStrokeRec& stroke, Sk
Path::FillType fill) { | 521 void GrDrawTarget::stencilPath(const GrPath* path, const SkStrokeRec& stroke, Sk
Path::FillType fill) { |
| 454 // TODO: extract portions of checkDraw that are relevant to path stenciling. | 522 // TODO: extract portions of checkDraw that are relevant to path stenciling. |
| 455 GrAssert(NULL != path); | 523 GrAssert(NULL != path); |
| 456 GrAssert(this->caps()->pathStencilingSupport()); | 524 GrAssert(this->caps()->pathStencilingSupport()); |
| 457 GrAssert(!stroke.isHairlineStyle()); | 525 GrAssert(!stroke.isHairlineStyle()); |
| 458 GrAssert(!SkPath::IsInverseFillType(fill)); | 526 GrAssert(!SkPath::IsInverseFillType(fill)); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 501 info.fPrimitiveType = type; | 569 info.fPrimitiveType = type; |
| 502 info.fStartIndex = 0; | 570 info.fStartIndex = 0; |
| 503 info.fStartVertex = 0; | 571 info.fStartVertex = 0; |
| 504 info.fIndicesPerInstance = indicesPerInstance; | 572 info.fIndicesPerInstance = indicesPerInstance; |
| 505 info.fVerticesPerInstance = verticesPerInstance; | 573 info.fVerticesPerInstance = verticesPerInstance; |
| 506 | 574 |
| 507 // Set the same bounds for all the draws. | 575 // Set the same bounds for all the draws. |
| 508 if (NULL != devBounds) { | 576 if (NULL != devBounds) { |
| 509 info.setDevBounds(*devBounds); | 577 info.setDevBounds(*devBounds); |
| 510 } | 578 } |
| 579 // TODO: We should continue with incorrect blending. |
| 580 if (!this->setupDstReadIfNecessary(&info)) { |
| 581 return; |
| 582 } |
| 511 | 583 |
| 512 while (instanceCount) { | 584 while (instanceCount) { |
| 513 info.fInstanceCount = GrMin(instanceCount, maxInstancesPerDraw); | 585 info.fInstanceCount = GrMin(instanceCount, maxInstancesPerDraw); |
| 514 info.fVertexCount = info.fInstanceCount * verticesPerInstance; | 586 info.fVertexCount = info.fInstanceCount * verticesPerInstance; |
| 515 info.fIndexCount = info.fInstanceCount * indicesPerInstance; | 587 info.fIndexCount = info.fInstanceCount * indicesPerInstance; |
| 516 | 588 |
| 517 if (this->checkDraw(type, | 589 if (this->checkDraw(type, |
| 518 info.fStartVertex, | 590 info.fStartVertex, |
| 519 info.fStartIndex, | 591 info.fStartIndex, |
| 520 info.fVertexCount, | 592 info.fVertexCount, |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 727 GrPrintf("HW AA Lines Support : %s\n", gNY[fHWAALineSupport]); | 799 GrPrintf("HW AA Lines Support : %s\n", gNY[fHWAALineSupport]); |
| 728 GrPrintf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport]
); | 800 GrPrintf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport]
); |
| 729 GrPrintf("Geometry Shader Support : %s\n", gNY[fGeometryShaderSupport]); | 801 GrPrintf("Geometry Shader Support : %s\n", gNY[fGeometryShaderSupport]); |
| 730 GrPrintf("Dual Source Blending Support: %s\n", gNY[fDualSourceBlendingSuppor
t]); | 802 GrPrintf("Dual Source Blending Support: %s\n", gNY[fDualSourceBlendingSuppor
t]); |
| 731 GrPrintf("Buffer Lock Support : %s\n", gNY[fBufferLockSupport]); | 803 GrPrintf("Buffer Lock Support : %s\n", gNY[fBufferLockSupport]); |
| 732 GrPrintf("Path Stenciling Support : %s\n", gNY[fPathStencilingSupport]); | 804 GrPrintf("Path Stenciling Support : %s\n", gNY[fPathStencilingSupport]); |
| 733 GrPrintf("Max Texture Size : %d\n", fMaxTextureSize); | 805 GrPrintf("Max Texture Size : %d\n", fMaxTextureSize); |
| 734 GrPrintf("Max Render Target Size : %d\n", fMaxRenderTargetSize); | 806 GrPrintf("Max Render Target Size : %d\n", fMaxRenderTargetSize); |
| 735 GrPrintf("Max Sample Count : %d\n", fMaxSampleCount); | 807 GrPrintf("Max Sample Count : %d\n", fMaxSampleCount); |
| 736 } | 808 } |
| OLD | NEW |