Chromium Code Reviews| 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 } | |
|
robertphillips
2013/03/29 18:32:57
textureMatrix doesn't appear to be used
bsalomon
2013/03/29 18:59:38
Done.
| |
| 451 SkMatrix textureMatrix; | |
| 452 textureMatrix.setIDiv(rt->width(), rt->height()); | |
| 453 this->drawState()->disableState(GrDrawState::kClip_StateBit); | |
| 454 this->drawState()->setRenderTarget(ast.texture()->asRenderTarget()); | |
| 455 static const int kTextureStage = 0; | |
| 456 SkMatrix matrix; | |
| 457 matrix.setIDiv(rt->width(), rt->height()); | |
| 458 this->drawState()->createTextureEffect(kTextureStage, rt->asTexture(), matri x); | |
|
robertphillips
2013/03/29 18:32:57
I think "drawRect(dstRect, NULL, &dstRect, NULL);"
bsalomon
2013/03/29 18:59:38
Done.
| |
| 459 SkRect dstRect = SkRect::MakeWH(SkIntToScalar(desc.fWidth), | |
| 460 SkIntToScalar(desc.fHeight)); | |
| 461 SkRect srcRect = dstRect; | |
| 462 this->drawRect(dstRect, NULL, &srcRect, NULL); | |
| 463 info->fDstCopy.setTexture(ast.texture()); | |
| 464 info->fDstCopy.setOffset(0, 0); | |
| 465 return true; | |
| 466 } | |
| 467 | |
| 405 void GrDrawTarget::drawIndexed(GrPrimitiveType type, | 468 void GrDrawTarget::drawIndexed(GrPrimitiveType type, |
| 406 int startVertex, | 469 int startVertex, |
| 407 int startIndex, | 470 int startIndex, |
| 408 int vertexCount, | 471 int vertexCount, |
| 409 int indexCount, | 472 int indexCount, |
| 410 const SkRect* devBounds) { | 473 const SkRect* devBounds) { |
| 411 if (indexCount > 0 && this->checkDraw(type, startVertex, startIndex, vertexC ount, indexCount)) { | 474 if (indexCount > 0 && this->checkDraw(type, startVertex, startIndex, vertexC ount, indexCount)) { |
| 412 DrawInfo info; | 475 DrawInfo info; |
| 413 info.fPrimitiveType = type; | 476 info.fPrimitiveType = type; |
| 414 info.fStartVertex = startVertex; | 477 info.fStartVertex = startVertex; |
| 415 info.fStartIndex = startIndex; | 478 info.fStartIndex = startIndex; |
| 416 info.fVertexCount = vertexCount; | 479 info.fVertexCount = vertexCount; |
| 417 info.fIndexCount = indexCount; | 480 info.fIndexCount = indexCount; |
| 418 | 481 |
| 419 info.fInstanceCount = 0; | 482 info.fInstanceCount = 0; |
| 420 info.fVerticesPerInstance = 0; | 483 info.fVerticesPerInstance = 0; |
| 421 info.fIndicesPerInstance = 0; | 484 info.fIndicesPerInstance = 0; |
| 422 | 485 |
| 423 if (NULL != devBounds) { | 486 if (NULL != devBounds) { |
| 424 info.setDevBounds(*devBounds); | 487 info.setDevBounds(*devBounds); |
| 425 } | 488 } |
| 489 if (!this->setupDstReadIfNecessary(&info)) { | |
| 490 return; | |
| 491 } | |
| 426 this->onDraw(info); | 492 this->onDraw(info); |
| 427 } | 493 } |
| 428 } | 494 } |
| 429 | 495 |
| 430 void GrDrawTarget::drawNonIndexed(GrPrimitiveType type, | 496 void GrDrawTarget::drawNonIndexed(GrPrimitiveType type, |
| 431 int startVertex, | 497 int startVertex, |
| 432 int vertexCount, | 498 int vertexCount, |
| 433 const SkRect* devBounds) { | 499 const SkRect* devBounds) { |
| 434 if (vertexCount > 0 && this->checkDraw(type, startVertex, -1, vertexCount, - 1)) { | 500 if (vertexCount > 0 && this->checkDraw(type, startVertex, -1, vertexCount, - 1)) { |
| 435 DrawInfo info; | 501 DrawInfo info; |
| 436 info.fPrimitiveType = type; | 502 info.fPrimitiveType = type; |
| 437 info.fStartVertex = startVertex; | 503 info.fStartVertex = startVertex; |
| 438 info.fStartIndex = 0; | 504 info.fStartIndex = 0; |
| 439 info.fVertexCount = vertexCount; | 505 info.fVertexCount = vertexCount; |
| 440 info.fIndexCount = 0; | 506 info.fIndexCount = 0; |
| 441 | 507 |
| 442 info.fInstanceCount = 0; | 508 info.fInstanceCount = 0; |
| 443 info.fVerticesPerInstance = 0; | 509 info.fVerticesPerInstance = 0; |
| 444 info.fIndicesPerInstance = 0; | 510 info.fIndicesPerInstance = 0; |
| 445 | 511 |
| 446 if (NULL != devBounds) { | 512 if (NULL != devBounds) { |
| 447 info.setDevBounds(*devBounds); | 513 info.setDevBounds(*devBounds); |
| 448 } | 514 } |
| 515 if (!this->setupDstReadIfNecessary(&info)) { | |
| 516 return; | |
| 517 } | |
| 449 this->onDraw(info); | 518 this->onDraw(info); |
| 450 } | 519 } |
| 451 } | 520 } |
| 452 | 521 |
| 453 void GrDrawTarget::stencilPath(const GrPath* path, const SkStrokeRec& stroke, Sk Path::FillType fill) { | 522 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. | 523 // TODO: extract portions of checkDraw that are relevant to path stenciling. |
| 455 GrAssert(NULL != path); | 524 GrAssert(NULL != path); |
| 456 GrAssert(this->caps()->pathStencilingSupport()); | 525 GrAssert(this->caps()->pathStencilingSupport()); |
| 457 GrAssert(!stroke.isHairlineStyle()); | 526 GrAssert(!stroke.isHairlineStyle()); |
| 458 GrAssert(!SkPath::IsInverseFillType(fill)); | 527 GrAssert(!SkPath::IsInverseFillType(fill)); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 501 info.fPrimitiveType = type; | 570 info.fPrimitiveType = type; |
| 502 info.fStartIndex = 0; | 571 info.fStartIndex = 0; |
| 503 info.fStartVertex = 0; | 572 info.fStartVertex = 0; |
| 504 info.fIndicesPerInstance = indicesPerInstance; | 573 info.fIndicesPerInstance = indicesPerInstance; |
| 505 info.fVerticesPerInstance = verticesPerInstance; | 574 info.fVerticesPerInstance = verticesPerInstance; |
| 506 | 575 |
| 507 // Set the same bounds for all the draws. | 576 // Set the same bounds for all the draws. |
| 508 if (NULL != devBounds) { | 577 if (NULL != devBounds) { |
| 509 info.setDevBounds(*devBounds); | 578 info.setDevBounds(*devBounds); |
| 510 } | 579 } |
| 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 |