Remove GrDrawTarget::AutoRenderTargetRestore.

Pass GrRenderTarget in GrGpuG clear\bind methods.

BUG=skia:2889
R=egdaniel@google.com

Author: bsalomon@google.com

Review URL: https://codereview.chromium.org/533883004
This commit is contained in:
bsalomon 2014-09-03 07:19:50 -07:00 committed by Commit bot
parent eddb113ec6
commit b0bd4f64a6
8 changed files with 59 additions and 104 deletions

View File

@ -739,7 +739,7 @@ bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID,
SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil buffers"); SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil buffers");
clipBit = (1 << (clipBit-1)); clipBit = (1 << (clipBit-1));
fGpu->clearStencilClip(stencilSpaceIBounds, kAllIn_InitialState == initialState); fGpu->clearStencilClip(rt, stencilSpaceIBounds, kAllIn_InitialState == initialState);
// walk through each clip element and perform its set op // walk through each clip element and perform its set op
// with the existing clip. // with the existing clip.

View File

@ -380,40 +380,6 @@ public:
*/ */
void setRenderTarget(GrRenderTarget* target) { fRenderTarget.reset(SkSafeRef(target)); } void setRenderTarget(GrRenderTarget* target) { fRenderTarget.reset(SkSafeRef(target)); }
class AutoRenderTargetRestore : public ::SkNoncopyable {
public:
AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
fDrawState = NULL;
fSavedTarget = NULL;
this->set(ds, newTarget);
}
~AutoRenderTargetRestore() { this->restore(); }
void restore() {
if (NULL != fDrawState) {
fDrawState->setRenderTarget(fSavedTarget);
fDrawState = NULL;
}
SkSafeSetNull(fSavedTarget);
}
void set(GrDrawState* ds, GrRenderTarget* newTarget) {
this->restore();
if (NULL != ds) {
SkASSERT(NULL == fSavedTarget);
fSavedTarget = ds->getRenderTarget();
SkSafeRef(fSavedTarget);
ds->setRenderTarget(newTarget);
fDrawState = ds;
}
}
private:
GrDrawState* fDrawState;
GrRenderTarget* fSavedTarget;
};
/// @} /// @}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////

View File

@ -125,8 +125,7 @@ bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
// We used to clear down in the GL subclass using a special purpose // We used to clear down in the GL subclass using a special purpose
// FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported // FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported
// FBO status. // FBO status.
GrDrawState::AutoRenderTargetRestore artr(this->drawState(), rt); this->clearStencil(rt);
this->clearStencil();
return true; return true;
} else { } else {
return false; return false;
@ -180,16 +179,15 @@ void GrGpu::clear(const SkIRect* rect,
GrColor color, GrColor color,
bool canIgnoreRect, bool canIgnoreRect,
GrRenderTarget* renderTarget) { GrRenderTarget* renderTarget) {
GrDrawState::AutoRenderTargetRestore art; if (NULL == renderTarget) {
if (NULL != renderTarget) { renderTarget = this->getDrawState().getRenderTarget();
art.set(this->drawState(), renderTarget);
} }
if (NULL == this->getDrawState().getRenderTarget()) { if (NULL == renderTarget) {
SkASSERT(0); SkASSERT(0);
return; return;
} }
this->handleDirtyContext(); this->handleDirtyContext();
this->onClear(rect, color, canIgnoreRect); this->onClear(renderTarget, rect, color, canIgnoreRect);
} }
bool GrGpu::readPixels(GrRenderTarget* target, bool GrGpu::readPixels(GrRenderTarget* target,

View File

@ -315,7 +315,7 @@ public:
// GrGpu subclass sets clip bit in the stencil buffer. The subclass is // GrGpu subclass sets clip bit in the stencil buffer. The subclass is
// free to clear the remaining bits to zero if masked clears are more // free to clear the remaining bits to zero if masked clears are more
// expensive than clearing all bits. // expensive than clearing all bits.
virtual void clearStencilClip(const SkIRect& rect, bool insideClip) = 0; virtual void clearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) = 0;
enum PrivateDrawStateStateBits { enum PrivateDrawStateStateBits {
kFirstBit = (GrDrawState::kLastPublicStateBit << 1), kFirstBit = (GrDrawState::kLastPublicStateBit << 1),
@ -435,7 +435,8 @@ private:
// overridden by backend-specific derived class to perform the clear and // overridden by backend-specific derived class to perform the clear and
// clearRect. NULL rect means clear whole target. If canIgnoreRect is // clearRect. NULL rect means clear whole target. If canIgnoreRect is
// true, it is okay to perform a full clear instead of a partial clear // true, it is okay to perform a full clear instead of a partial clear
virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) = 0; virtual void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
bool canIgnoreRect) = 0;
// overridden by backend-specific derived class to perform the draw call. // overridden by backend-specific derived class to perform the draw call.
virtual void onGpuDraw(const DrawInfo&) = 0; virtual void onGpuDraw(const DrawInfo&) = 0;
@ -470,8 +471,8 @@ private:
// returns false if current state is unsupported. // returns false if current state is unsupported.
virtual bool flushGraphicsState(DrawType, const GrDeviceCoordTexture* dstCopy) = 0; virtual bool flushGraphicsState(DrawType, const GrDeviceCoordTexture* dstCopy) = 0;
// clears the entire stencil buffer to 0 // clears target's entire stencil buffer to 0
virtual void clearStencil() = 0; virtual void clearStencil(GrRenderTarget* target) = 0;
// Given a rt, find or create a stencil buffer and attach it // Given a rt, find or create a stencil buffer and attach it
bool attachStencilBufferToRenderTarget(GrRenderTarget* target); bool attachStencilBufferToRenderTarget(GrRenderTarget* target);

View File

@ -238,8 +238,7 @@ public:
* *
* @return The currently set render target. * @return The currently set render target.
*/ */
const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); } GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); }
/// @} /// @}

View File

@ -1349,27 +1349,18 @@ GrIndexBuffer* GrGpuGL::onCreateIndexBuffer(size_t size, bool dynamic) {
} }
} }
void GrGpuGL::flushScissor() { void GrGpuGL::flushScissor(const GrGLIRect& rtViewport, GrSurfaceOrigin rtOrigin) {
if (fScissorState.fEnabled) { if (fScissorState.fEnabled) {
// Only access the RT if scissoring is being enabled. We can call this before performing
// a glBitframebuffer for a surface->surface copy, which requires no RT to be bound to the
// GrDrawState.
const GrDrawState& drawState = this->getDrawState();
const GrGLRenderTarget* rt =
static_cast<const GrGLRenderTarget*>(drawState.getRenderTarget());
SkASSERT(NULL != rt);
const GrGLIRect& vp = rt->getViewport();
GrGLIRect scissor; GrGLIRect scissor;
scissor.setRelativeTo(vp, scissor.setRelativeTo(rtViewport,
fScissorState.fRect.fLeft, fScissorState.fRect.fLeft,
fScissorState.fRect.fTop, fScissorState.fRect.fTop,
fScissorState.fRect.width(), fScissorState.fRect.width(),
fScissorState.fRect.height(), fScissorState.fRect.height(),
rt->origin()); rtOrigin);
// if the scissor fully contains the viewport then we fall through and // if the scissor fully contains the viewport then we fall through and
// disable the scissor test. // disable the scissor test.
if (!scissor.contains(vp)) { if (!scissor.contains(rtViewport)) {
if (fHWScissorSettings.fRect != scissor) { if (fHWScissorSettings.fRect != scissor) {
scissor.pushToGLScissor(this->glInterface()); scissor.pushToGLScissor(this->glInterface());
fHWScissorSettings.fRect = scissor; fHWScissorSettings.fRect = scissor;
@ -1388,11 +1379,11 @@ void GrGpuGL::flushScissor() {
} }
} }
void GrGpuGL::onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) { void GrGpuGL::onClear(GrRenderTarget* target, const SkIRect* rect, GrColor color,
const GrDrawState& drawState = this->getDrawState(); bool canIgnoreRect) {
const GrRenderTarget* rt = drawState.getRenderTarget();
// parent class should never let us get here with no RT // parent class should never let us get here with no RT
SkASSERT(NULL != rt); SkASSERT(NULL != target);
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
if (canIgnoreRect && this->glCaps().fullClearIsFree()) { if (canIgnoreRect && this->glCaps().fullClearIsFree()) {
rect = NULL; rect = NULL;
@ -1402,7 +1393,7 @@ void GrGpuGL::onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) {
if (NULL != rect) { if (NULL != rect) {
// flushScissor expects rect to be clipped to the target. // flushScissor expects rect to be clipped to the target.
clippedRect = *rect; clippedRect = *rect;
SkIRect rtRect = SkIRect::MakeWH(rt->width(), rt->height()); SkIRect rtRect = SkIRect::MakeWH(target->width(), target->height());
if (clippedRect.intersect(rtRect)) { if (clippedRect.intersect(rtRect)) {
rect = &clippedRect; rect = &clippedRect;
} else { } else {
@ -1410,13 +1401,13 @@ void GrGpuGL::onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) {
} }
} }
this->flushRenderTarget(rect); this->flushRenderTarget(glRT, rect);
GrAutoTRestore<ScissorState> asr(&fScissorState); GrAutoTRestore<ScissorState> asr(&fScissorState);
fScissorState.fEnabled = (NULL != rect); fScissorState.fEnabled = (NULL != rect);
if (fScissorState.fEnabled) { if (fScissorState.fEnabled) {
fScissorState.fRect = *rect; fScissorState.fRect = *rect;
} }
this->flushScissor(); this->flushScissor(glRT->getViewport(), glRT->origin());
GrGLfloat r, g, b, a; GrGLfloat r, g, b, a;
static const GrGLfloat scale255 = 1.f / 255.f; static const GrGLfloat scale255 = 1.f / 255.f;
@ -1486,16 +1477,16 @@ void GrGpuGL::discard(GrRenderTarget* renderTarget) {
} }
void GrGpuGL::clearStencil() { void GrGpuGL::clearStencil(GrRenderTarget* target) {
if (NULL == this->getDrawState().getRenderTarget()) { if (NULL == target) {
return; return;
} }
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
this->flushRenderTarget(&SkIRect::EmptyIRect()); this->flushRenderTarget(glRT, &SkIRect::EmptyIRect());
GrAutoTRestore<ScissorState> asr(&fScissorState); GrAutoTRestore<ScissorState> asr(&fScissorState);
fScissorState.fEnabled = false; fScissorState.fEnabled = false;
this->flushScissor(); this->flushScissor(glRT->getViewport(), glRT->origin());
GL_CALL(StencilMask(0xffffffff)); GL_CALL(StencilMask(0xffffffff));
GL_CALL(ClearStencil(0)); GL_CALL(ClearStencil(0));
@ -1503,15 +1494,13 @@ void GrGpuGL::clearStencil() {
fHWStencilSettings.invalidate(); fHWStencilSettings.invalidate();
} }
void GrGpuGL::clearStencilClip(const SkIRect& rect, bool insideClip) { void GrGpuGL::clearStencilClip(GrRenderTarget* target, const SkIRect& rect, bool insideClip) {
const GrDrawState& drawState = this->getDrawState(); SkASSERT(NULL != target);
const GrRenderTarget* rt = drawState.getRenderTarget();
SkASSERT(NULL != rt);
// this should only be called internally when we know we have a // this should only be called internally when we know we have a
// stencil buffer. // stencil buffer.
SkASSERT(NULL != rt->getStencilBuffer()); SkASSERT(NULL != target->getStencilBuffer());
GrGLint stencilBitCount = rt->getStencilBuffer()->bits(); GrGLint stencilBitCount = target->getStencilBuffer()->bits();
#if 0 #if 0
SkASSERT(stencilBitCount > 0); SkASSERT(stencilBitCount > 0);
GrGLint clipStencilMask = (1 << (stencilBitCount - 1)); GrGLint clipStencilMask = (1 << (stencilBitCount - 1));
@ -1529,12 +1518,13 @@ void GrGpuGL::clearStencilClip(const SkIRect& rect, bool insideClip) {
} else { } else {
value = 0; value = 0;
} }
this->flushRenderTarget(&SkIRect::EmptyIRect()); GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
this->flushRenderTarget(glRT, &SkIRect::EmptyIRect());
GrAutoTRestore<ScissorState> asr(&fScissorState); GrAutoTRestore<ScissorState> asr(&fScissorState);
fScissorState.fEnabled = true; fScissorState.fEnabled = true;
fScissorState.fRect = rect; fScissorState.fRect = rect;
this->flushScissor(); this->flushScissor(glRT->getViewport(), glRT->origin());
GL_CALL(StencilMask((uint32_t) clipStencilMask)); GL_CALL(StencilMask((uint32_t) clipStencilMask));
GL_CALL(ClearStencil(value)); GL_CALL(ClearStencil(value));
@ -1600,13 +1590,12 @@ bool GrGpuGL::onReadPixels(GrRenderTarget* target,
// resolve the render target if necessary // resolve the render target if necessary
GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(target); GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(target);
GrDrawState::AutoRenderTargetRestore artr;
switch (tgt->getResolveType()) { switch (tgt->getResolveType()) {
case GrGLRenderTarget::kCantResolve_ResolveType: case GrGLRenderTarget::kCantResolve_ResolveType:
return false; return false;
case GrGLRenderTarget::kAutoResolves_ResolveType: case GrGLRenderTarget::kAutoResolves_ResolveType:
artr.set(this->drawState(), target); this->flushRenderTarget(static_cast<GrGLRenderTarget*>(target),
this->flushRenderTarget(&SkIRect::EmptyIRect()); &SkIRect::EmptyIRect());
break; break;
case GrGLRenderTarget::kCanResolve_ResolveType: case GrGLRenderTarget::kCanResolve_ResolveType:
this->onResolveRenderTarget(tgt); this->onResolveRenderTarget(tgt);
@ -1702,15 +1691,13 @@ bool GrGpuGL::onReadPixels(GrRenderTarget* target,
return true; return true;
} }
void GrGpuGL::flushRenderTarget(const SkIRect* bound) { void GrGpuGL::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bound) {
GrGLRenderTarget* rt = SkASSERT(NULL != target);
static_cast<GrGLRenderTarget*>(this->drawState()->getRenderTarget());
SkASSERT(NULL != rt);
uint32_t rtID = rt->getUniqueID(); uint32_t rtID = target->getUniqueID();
if (fHWBoundRenderTargetUniqueID != rtID) { if (fHWBoundRenderTargetUniqueID != rtID) {
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, rt->renderFBOID())); GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, target->renderFBOID()));
#ifdef SK_DEBUG #ifdef SK_DEBUG
// don't do this check in Chromium -- this is causing // don't do this check in Chromium -- this is causing
// lots of repeated command buffer flushes when the compositor is // lots of repeated command buffer flushes when the compositor is
@ -1725,17 +1712,17 @@ void GrGpuGL::flushRenderTarget(const SkIRect* bound) {
} }
#endif #endif
fHWBoundRenderTargetUniqueID = rtID; fHWBoundRenderTargetUniqueID = rtID;
const GrGLIRect& vp = rt->getViewport(); const GrGLIRect& vp = target->getViewport();
if (fHWViewport != vp) { if (fHWViewport != vp) {
vp.pushToGLViewport(this->glInterface()); vp.pushToGLViewport(this->glInterface());
fHWViewport = vp; fHWViewport = vp;
} }
} }
if (NULL == bound || !bound->isEmpty()) { if (NULL == bound || !bound->isEmpty()) {
rt->flagAsNeedingResolve(bound); target->flagAsNeedingResolve(bound);
} }
GrTexture *texture = rt->asTexture(); GrTexture *texture = target->asTexture();
if (NULL != texture) { if (NULL != texture) {
texture->impl()->dirtyMipMaps(true); texture->impl()->dirtyMipMaps(true);
} }
@ -1829,14 +1816,14 @@ void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
asr.reset(&fScissorState); asr.reset(&fScissorState);
fScissorState.fEnabled = true; fScissorState.fEnabled = true;
fScissorState.fRect = dirtyRect; fScissorState.fRect = dirtyRect;
this->flushScissor(); this->flushScissor(rt->getViewport(), rt->origin());
GL_CALL(ResolveMultisampleFramebuffer()); GL_CALL(ResolveMultisampleFramebuffer());
} else { } else {
if (GrGLCaps::kDesktop_EXT_MSFBOType == this->glCaps().msFBOType()) { if (GrGLCaps::kDesktop_EXT_MSFBOType == this->glCaps().msFBOType()) {
// this respects the scissor during the blit, so disable it. // this respects the scissor during the blit, so disable it.
asr.reset(&fScissorState); asr.reset(&fScissorState);
fScissorState.fEnabled = false; fScissorState.fEnabled = false;
this->flushScissor(); this->flushScissor(rt->getViewport(), rt->origin());
} }
int right = r.fLeft + r.fWidth; int right = r.fLeft + r.fWidth;
int top = r.fBottom + r.fHeight; int top = r.fBottom + r.fHeight;
@ -2512,7 +2499,7 @@ bool GrGpuGL::onCopySurface(GrSurface* dst,
// The EXT version applies the scissor during the blit, so disable it. // The EXT version applies the scissor during the blit, so disable it.
asr.reset(&fScissorState); asr.reset(&fScissorState);
fScissorState.fEnabled = false; fScissorState.fEnabled = false;
this->flushScissor(); this->flushScissor(dstGLRect, dst->origin());
} }
GrGLint srcY0; GrGLint srcY0;
GrGLint srcY1; GrGLint srcY1;

View File

@ -125,7 +125,8 @@ private:
GrStencilBuffer* sb, GrStencilBuffer* sb,
GrRenderTarget* rt) SK_OVERRIDE; GrRenderTarget* rt) SK_OVERRIDE;
virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) SK_OVERRIDE; virtual void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
bool canIgnoreRect) SK_OVERRIDE;
virtual bool onReadPixels(GrRenderTarget* target, virtual bool onReadPixels(GrRenderTarget* target,
int left, int top, int left, int top,
@ -144,8 +145,8 @@ private:
virtual void onGpuDraw(const DrawInfo&) SK_OVERRIDE; virtual void onGpuDraw(const DrawInfo&) SK_OVERRIDE;
virtual void clearStencil() SK_OVERRIDE; virtual void clearStencil(GrRenderTarget*) SK_OVERRIDE;
virtual void clearStencilClip(const SkIRect& rect, virtual void clearStencilClip(GrRenderTarget*, const SkIRect& rect,
bool insideClip) SK_OVERRIDE; bool insideClip) SK_OVERRIDE;
virtual bool flushGraphicsState(DrawType, const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE; virtual bool flushGraphicsState(DrawType, const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
@ -218,7 +219,7 @@ private:
// flushes the scissor. see the note on flushBoundTextureAndParams about // flushes the scissor. see the note on flushBoundTextureAndParams about
// flushing the scissor after that function is called. // flushing the scissor after that function is called.
void flushScissor(); void flushScissor(const GrGLIRect& rtViewport, GrSurfaceOrigin rtOrigin);
void initFSAASupport(); void initFSAASupport();
@ -229,9 +230,10 @@ private:
// ensures that such operations don't negatively interact with tracking bound textures. // ensures that such operations don't negatively interact with tracking bound textures.
void setScratchTextureUnit(); void setScratchTextureUnit();
// bound is region that may be modified and therefore has to be resolved. // bounds is region that may be modified and therefore has to be resolved.
// NULL means whole target. Can be an empty rect. // NULL means whole target. Can be an empty rect.
void flushRenderTarget(const SkIRect* bound); void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds);
void flushStencil(DrawType); void flushStencil(DrawType);
void flushAAState(DrawType); void flushAAState(DrawType);

View File

@ -265,8 +265,10 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
dstCopy, dstCopy,
&fSharedGLProgramState); &fSharedGLProgramState);
} }
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(drawState.getRenderTarget());
this->flushStencil(type); this->flushStencil(type);
this->flushScissor(); this->flushScissor(glRT->getViewport(), glRT->origin());
this->flushAAState(type); this->flushAAState(type);
SkIRect* devRect = NULL; SkIRect* devRect = NULL;
@ -277,7 +279,7 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
} }
// This must come after textures are flushed because a texture may need // This must come after textures are flushed because a texture may need
// to be msaa-resolved (which will modify bound FBO state). // to be msaa-resolved (which will modify bound FBO state).
this->flushRenderTarget(devRect); this->flushRenderTarget(glRT, devRect);
return true; return true;
} }