| Index: src/gpu/GrContext.cpp
|
| diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
|
| index 7bcc41d339e53d045053dba779741ab198f6c7c1..98adf1d667df87ac278de9c3225e17f53fdccfcd 100755
|
| --- a/src/gpu/GrContext.cpp
|
| +++ b/src/gpu/GrContext.cpp
|
| @@ -37,11 +37,20 @@
|
| #include "SkDashPathPriv.h"
|
| #include "SkConfig8888.h"
|
| #include "SkGr.h"
|
| +#include "SkRTConf.h"
|
| #include "SkRRect.h"
|
| #include "SkStrokeRec.h"
|
| #include "SkTLazy.h"
|
| #include "SkTLS.h"
|
| #include "SkTraceEvent.h"
|
| +
|
| +// It can be useful to set this to false to test whether a bug is caused by using the
|
| +// InOrderDrawBuffer, to compare performance of using/not using InOrderDrawBuffer, or to make
|
| +// debugging simpler.
|
| +SK_CONF_DECLARE(bool, c_Defer, "gpu.deferContext", true,
|
| + "Defers rendering in GrContext via GrInOrderDrawBuffer.");
|
| +
|
| +#define BUFFERED_DRAW (c_Defer ? kYes_BufferedDraw : kNo_BufferedDraw)
|
|
|
| #ifdef SK_DEBUG
|
| // change this to a 1 to see notifications when partial coverage fails
|
| @@ -135,6 +144,8 @@
|
|
|
| fLayerCache.reset(SkNEW_ARGS(GrLayerCache, (this)));
|
|
|
| + fLastDrawWasBuffered = kNo_BufferedDraw;
|
| +
|
| fAARectRenderer = SkNEW_ARGS(GrAARectRenderer, (fGpu));
|
| fOvalRenderer = SkNEW(GrOvalRenderer);
|
|
|
| @@ -346,27 +357,26 @@
|
|
|
| if (texture) {
|
| GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit);
|
| - GrDrawState* drawState = fDrawBuffer->drawState();
|
| + GrDrawState* drawState = fGpu->drawState();
|
| drawState->setRenderTarget(texture->asRenderTarget());
|
|
|
| // if filtering is not desired then we want to ensure all
|
| // texels in the resampled image are copies of texels from
|
| // the original.
|
| - GrTextureParams params(SkShader::kClamp_TileMode,
|
| - filter ? GrTextureParams::kBilerp_FilterMode :
|
| - GrTextureParams::kNone_FilterMode);
|
| + GrTextureParams params(SkShader::kClamp_TileMode, filter ? GrTextureParams::kBilerp_FilterMode :
|
| + GrTextureParams::kNone_FilterMode);
|
| drawState->addColorTextureProcessor(clampedTexture, SkMatrix::I(), params);
|
|
|
| drawState->setVertexAttribs<gVertexAttribs>(SK_ARRAY_COUNT(gVertexAttribs),
|
| 2 * sizeof(SkPoint));
|
|
|
| - GrDrawTarget::AutoReleaseGeometry arg(fDrawBuffer, 4, 0);
|
| + GrDrawTarget::AutoReleaseGeometry arg(fGpu, 4, 0);
|
|
|
| if (arg.succeeded()) {
|
| SkPoint* verts = (SkPoint*) arg.vertices();
|
| verts[0].setIRectFan(0, 0, texture->width(), texture->height(), 2 * sizeof(SkPoint));
|
| verts[1].setIRectFan(0, 0, 1, 1, 2 * sizeof(SkPoint));
|
| - fDrawBuffer->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4);
|
| + fGpu->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4);
|
| }
|
| } else {
|
| // TODO: Our CPU stretch doesn't filter. But we create separate
|
| @@ -579,7 +589,7 @@
|
| AutoRestoreEffects are;
|
| AutoCheckFlush acf(this);
|
| GR_CREATE_TRACE_MARKER_CONTEXT("GrContext::clear", this);
|
| - GrDrawTarget* target = this->prepareToDraw(NULL, &are, &acf);
|
| + GrDrawTarget* target = this->prepareToDraw(NULL, BUFFERED_DRAW, &are, &acf);
|
| if (NULL == target) {
|
| return;
|
| }
|
| @@ -712,7 +722,7 @@
|
|
|
| AutoRestoreEffects are;
|
| AutoCheckFlush acf(this);
|
| - GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf);
|
| + GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
|
| if (NULL == target) {
|
| return;
|
| }
|
| @@ -826,7 +836,7 @@
|
| const SkMatrix* localMatrix) {
|
| AutoRestoreEffects are;
|
| AutoCheckFlush acf(this);
|
| - GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf);
|
| + GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
|
| if (NULL == target) {
|
| return;
|
| }
|
| @@ -892,7 +902,7 @@
|
| AutoCheckFlush acf(this);
|
| GrDrawTarget::AutoReleaseGeometry geo; // must be inside AutoCheckFlush scope
|
|
|
| - GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf);
|
| + GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
|
| if (NULL == target) {
|
| return;
|
| }
|
| @@ -956,7 +966,7 @@
|
|
|
| AutoRestoreEffects are;
|
| AutoCheckFlush acf(this);
|
| - GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf);
|
| + GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
|
| if (NULL == target) {
|
| return;
|
| }
|
| @@ -983,7 +993,7 @@
|
|
|
| AutoRestoreEffects are;
|
| AutoCheckFlush acf(this);
|
| - GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf);
|
| + GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
|
|
|
| GR_CREATE_TRACE_MARKER("GrContext::drawDRRect", target);
|
|
|
| @@ -1016,7 +1026,7 @@
|
|
|
| AutoRestoreEffects are;
|
| AutoCheckFlush acf(this);
|
| - GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf);
|
| + GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
|
| if (NULL == target) {
|
| return;
|
| }
|
| @@ -1104,7 +1114,7 @@
|
| if (path.isLine(pts)) {
|
| AutoRestoreEffects are;
|
| AutoCheckFlush acf(this);
|
| - GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf);
|
| + GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
|
| if (NULL == target) {
|
| return;
|
| }
|
| @@ -1141,7 +1151,7 @@
|
| // OK.
|
| AutoRestoreEffects are;
|
| AutoCheckFlush acf(this);
|
| - GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf);
|
| + GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
|
| if (NULL == target) {
|
| return;
|
| }
|
| @@ -1364,7 +1374,7 @@
|
| // drawing a rect to the render target.
|
| // The bracket ensures we pop the stack if we wind up flushing below.
|
| {
|
| - GrDrawTarget* drawTarget = this->prepareToDraw(NULL, NULL, NULL);
|
| + GrDrawTarget* drawTarget = this->prepareToDraw(NULL, kYes_BufferedDraw, NULL, NULL);
|
| GrDrawTarget::AutoGeometryAndStatePush agasp(drawTarget, GrDrawTarget::kReset_ASRInit,
|
| &matrix);
|
| GrDrawState* drawState = drawTarget->drawState();
|
| @@ -1488,26 +1498,21 @@
|
| // We protect the existing geometry here since it may not be
|
| // clear to the caller that a draw operation (i.e., drawSimpleRect)
|
| // can be invoked in this method
|
| - {
|
| - GrDrawTarget::AutoGeometryAndStatePush agasp(fDrawBuffer,
|
| - GrDrawTarget::kReset_ASRInit);
|
| - GrDrawState* drawState = fDrawBuffer->drawState();
|
| - SkASSERT(fp);
|
| - drawState->addColorProcessor(fp);
|
| -
|
| - drawState->setRenderTarget(texture->asRenderTarget());
|
| - SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
|
| - fDrawBuffer->drawSimpleRect(rect);
|
| - // we want to read back from the scratch's origin
|
| - left = 0;
|
| - top = 0;
|
| - target = texture->asRenderTarget();
|
| - }
|
| - this->flushSurfaceWrites(target);
|
| + GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ASRInit);
|
| + GrDrawState* drawState = fGpu->drawState();
|
| + SkASSERT(fp);
|
| + drawState->addColorProcessor(fp);
|
| +
|
| + drawState->setRenderTarget(texture->asRenderTarget());
|
| + SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
|
| + fGpu->drawSimpleRect(rect);
|
| + // we want to read back from the scratch's origin
|
| + left = 0;
|
| + top = 0;
|
| + target = texture->asRenderTarget();
|
| }
|
| }
|
| }
|
| -
|
| if (!fGpu->readPixels(target,
|
| left, top, width, height,
|
| readConfig, buffer, rowBytes)) {
|
| @@ -1551,7 +1556,7 @@
|
| ASSERT_OWNED_RESOURCE(renderTarget);
|
| AutoRestoreEffects are;
|
| AutoCheckFlush acf(this);
|
| - GrDrawTarget* target = this->prepareToDraw(NULL, &are, &acf);
|
| + GrDrawTarget* target = this->prepareToDraw(NULL, BUFFERED_DRAW, &are, &acf);
|
| if (NULL == target) {
|
| return;
|
| }
|
| @@ -1569,7 +1574,7 @@
|
| // Since we're going to the draw target and not GPU, no need to check kNoFlush
|
| // here.
|
|
|
| - GrDrawTarget* target = this->prepareToDraw(NULL, NULL, NULL);
|
| + GrDrawTarget* target = this->prepareToDraw(NULL, BUFFERED_DRAW, NULL, NULL);
|
| if (NULL == target) {
|
| return;
|
| }
|
| @@ -1589,6 +1594,7 @@
|
| ////////////////////////////////////////////////////////////////////////////////
|
|
|
| GrDrawTarget* GrContext::prepareToDraw(const GrPaint* paint,
|
| + BufferedDraw buffered,
|
| AutoRestoreEffects* are,
|
| AutoCheckFlush* acf) {
|
| // All users of this draw state should be freeing up all effects when they're done.
|
| @@ -1600,6 +1606,10 @@
|
| return NULL;
|
| }
|
|
|
| + if (kNo_BufferedDraw == buffered && kYes_BufferedDraw == fLastDrawWasBuffered) {
|
| + fDrawBuffer->flush();
|
| + fLastDrawWasBuffered = kNo_BufferedDraw;
|
| + }
|
| ASSERT_OWNED_RESOURCE(fRenderTarget.get());
|
| if (paint) {
|
| SkASSERT(are);
|
| @@ -1619,11 +1629,20 @@
|
| fDrawState->reset(fViewMatrix);
|
| fDrawState->setRenderTarget(fRenderTarget.get());
|
| }
|
| + GrDrawTarget* target;
|
| + if (kYes_BufferedDraw == buffered) {
|
| + fLastDrawWasBuffered = kYes_BufferedDraw;
|
| + target = fDrawBuffer;
|
| + } else {
|
| + SkASSERT(kNo_BufferedDraw == buffered);
|
| + fLastDrawWasBuffered = kNo_BufferedDraw;
|
| + target = fGpu;
|
| + }
|
| fDrawState->setState(GrDrawState::kClip_StateBit, fClip &&
|
| !fClip->fClipStack->isWideOpen());
|
| - fDrawBuffer->setClip(fClip);
|
| - SkASSERT(fDrawState == fDrawBuffer->drawState());
|
| - return fDrawBuffer;
|
| + target->setClip(fClip);
|
| + SkASSERT(fDrawState == target->drawState());
|
| + return target;
|
| }
|
|
|
| /*
|
| @@ -1703,7 +1722,7 @@
|
| }
|
|
|
| GrDrawTarget* GrContext::getTextTarget() {
|
| - return this->prepareToDraw(NULL, NULL, NULL);
|
| + return this->prepareToDraw(NULL, BUFFERED_DRAW, NULL, NULL);
|
| }
|
|
|
| const GrIndexBuffer* GrContext::getQuadIndexBuffer() const {
|
|
|