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 |