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 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); | |
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; | |
jvanverth1
2013/03/29 18:46:22
Do we want to try to draw something here, even if
bsalomon
2013/03/29 18:59:39
We could... and probably should. I'll put a commen
| |
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 |