| Index: src/gpu/GrDrawTarget.cpp
|
| ===================================================================
|
| --- src/gpu/GrDrawTarget.cpp (revision 8448)
|
| +++ src/gpu/GrDrawTarget.cpp (working copy)
|
| @@ -9,6 +9,7 @@
|
|
|
|
|
| #include "GrDrawTarget.h"
|
| +#include "GrContext.h"
|
| #include "GrDrawTargetCaps.h"
|
| #include "GrRenderTarget.h"
|
| #include "GrTexture.h"
|
| @@ -38,6 +39,9 @@
|
| } else {
|
| fDevBounds = NULL;
|
| }
|
| +
|
| + fDstCopy = di.fDstCopy;
|
| +
|
| return *this;
|
| }
|
|
|
| @@ -402,6 +406,62 @@
|
| return true;
|
| }
|
|
|
| +bool GrDrawTarget::setupDstReadIfNecessary(DrawInfo* info) {
|
| + bool willReadDst = false;
|
| + for (int s = 0; s < GrDrawState::kNumStages; ++s) {
|
| + const GrEffectRef* effect = this->drawState()->getStage(s).getEffect();
|
| + if (NULL != effect && (*effect)->willReadDst()) {
|
| + willReadDst = true;
|
| + break;
|
| + }
|
| + }
|
| + if (!willReadDst) {
|
| + return true;
|
| + }
|
| + GrRenderTarget* rt = this->drawState()->getRenderTarget();
|
| + // If the dst is not a texture then we don't currently have a way of copying the
|
| + // texture. TODO: make copying RT->Tex (or Surface->Surface) a GrDrawTarget operation that can
|
| + // be built on top of GL/D3D APIs.
|
| + if (NULL == rt->asTexture()) {
|
| + GrPrintf("Reading Dst of non-texture render target is not currently supported.\n");
|
| + return false;
|
| + }
|
| + // TODO: Consider bounds of draw and bounds of clip
|
| +
|
| + GrDrawTarget::AutoGeometryAndStatePush agasp(this, kReset_ASRInit);
|
| +
|
| + // The draw will resolve dst if it has MSAA. Two things to consider in the future:
|
| + // 1) to make the dst values be pre-resolve we'd need to be able to copy to MSAA
|
| + // texture and sample it correctly in the shader. 2) If 1 isn't available then we
|
| + // should just resolve and use the resolved texture directly rather than making a
|
| + // copy of it.
|
| + GrTextureDesc desc;
|
| + desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
|
| + desc.fWidth = rt->width();
|
| + desc.fHeight = rt->height();
|
| + desc.fSampleCnt = 0;
|
| + desc.fConfig = rt->config();
|
| +
|
| + GrAutoScratchTexture ast(fContext, desc, GrContext::kApprox_ScratchTexMatch);
|
| +
|
| + if (NULL == ast.texture()) {
|
| + GrPrintf("Failed to create temporary copy of destination texture.\n");
|
| + return false;
|
| + }
|
| + this->drawState()->disableState(GrDrawState::kClip_StateBit);
|
| + this->drawState()->setRenderTarget(ast.texture()->asRenderTarget());
|
| + static const int kTextureStage = 0;
|
| + SkMatrix matrix;
|
| + matrix.setIDiv(rt->width(), rt->height());
|
| + this->drawState()->createTextureEffect(kTextureStage, rt->asTexture(), matrix);
|
| + SkRect copyRect = SkRect::MakeWH(SkIntToScalar(desc.fWidth),
|
| + SkIntToScalar(desc.fHeight));
|
| + this->drawRect(copyRect, NULL, ©Rect, NULL);
|
| + info->fDstCopy.setTexture(ast.texture());
|
| + info->fDstCopy.setOffset(0, 0);
|
| + return true;
|
| +}
|
| +
|
| void GrDrawTarget::drawIndexed(GrPrimitiveType type,
|
| int startVertex,
|
| int startIndex,
|
| @@ -423,6 +483,10 @@
|
| if (NULL != devBounds) {
|
| info.setDevBounds(*devBounds);
|
| }
|
| + // TODO: We should continue with incorrect blending.
|
| + if (!this->setupDstReadIfNecessary(&info)) {
|
| + return;
|
| + }
|
| this->onDraw(info);
|
| }
|
| }
|
| @@ -446,6 +510,10 @@
|
| if (NULL != devBounds) {
|
| info.setDevBounds(*devBounds);
|
| }
|
| + // TODO: We should continue with incorrect blending.
|
| + if (!this->setupDstReadIfNecessary(&info)) {
|
| + return;
|
| + }
|
| this->onDraw(info);
|
| }
|
| }
|
| @@ -508,6 +576,10 @@
|
| if (NULL != devBounds) {
|
| info.setDevBounds(*devBounds);
|
| }
|
| + // TODO: We should continue with incorrect blending.
|
| + if (!this->setupDstReadIfNecessary(&info)) {
|
| + return;
|
| + }
|
|
|
| while (instanceCount) {
|
| info.fInstanceCount = GrMin(instanceCount, maxInstancesPerDraw);
|
|
|