Chromium Code Reviews

Side by Side Diff: src/gpu/GrDrawTarget.cpp

Issue 13314002: Add support for reading the dst pixel value in an effect. Use in a new effect for the kDarken xfer … (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
OLDNEW
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...)
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...)
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...)
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 }
OLDNEW

Powered by Google App Engine