// sort out what kind of clip mask needs to be created: alpha, stencil,
// scissor, or entirely software
bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
+ const SkRect* devBounds,
GrDrawState::AutoRestoreEffects* are,
- GrDrawState::AutoRestoreStencil* asr,
- const SkRect* devBounds) {
+ GrDrawState::AutoRestoreStencil* ars,
+ GrDrawTarget::ScissorState* scissorState) {
fCurrClipMaskType = kNone_ClipMaskType;
GrReducedClip::ElementList elements(16);
}
if (ignoreClip) {
- fGpu->disableScissor();
- this->setDrawStateStencil(asr);
+ this->setDrawStateStencil(ars);
return true;
}
scissorSpaceIBounds.offset(-clipDataIn->fOrigin);
if (NULL == devBounds ||
!SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) {
- fGpu->enableScissor(scissorSpaceIBounds);
- } else {
- fGpu->disableScissor();
+ scissorState->set(scissorSpaceIBounds);
}
- this->setDrawStateStencil(asr);
+ this->setDrawStateStencil(ars);
return true;
}
}
rtSpaceMaskBounds.offset(-clipDataIn->fOrigin);
are->set(fGpu->drawState());
setup_drawstate_aaclip(fGpu, result, rtSpaceMaskBounds);
- fGpu->disableScissor();
- this->setDrawStateStencil(asr);
+ this->setDrawStateStencil(ars);
return true;
}
// if alpha clip mask creation fails fall through to the non-AA code paths
// use both stencil and scissor test to the bounds for the final draw.
SkIRect scissorSpaceIBounds(clipSpaceIBounds);
scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset);
- fGpu->enableScissor(scissorSpaceIBounds);
- this->setDrawStateStencil(asr);
+ scissorState->set(scissorSpaceIBounds);
+ this->setDrawStateStencil(ars);
return true;
}
#include "GrClipMaskCache.h"
#include "GrContext.h"
#include "GrDrawState.h"
+#include "GrDrawTarget.h"
#include "GrReducedClip.h"
#include "GrStencil.h"
#include "GrTexture.h"
* clip. devBounds is optional but can help optimize clipping.
*/
bool setupClipping(const GrClipData* clipDataIn,
+ const SkRect* devBounds,
GrDrawState::AutoRestoreEffects*,
GrDrawState::AutoRestoreStencil*,
- const SkRect* devBounds);
+ GrDrawTarget::ScissorState* scissorState);
/**
* Purge resources to free up memory. TODO: This class shouldn't hold any long lived refs
public:
SK_DECLARE_INST_COUNT(GrDrawTarget)
-
typedef GrPathRendering::PathTransformType PathTransformType ;
///////////////////////////////////////////////////////////////////////////
virtual DrawToken getCurrentDrawToken() { return DrawToken(this, 0); }
+ // The state of the scissor is controlled by the clip manager, no one else should set
+ // Scissor state
+ struct ScissorState {
+ ScissorState() : fEnabled(false) {}
+ void set(const SkIRect& rect) { fRect = rect; fEnabled = true; }
+ bool fEnabled;
+ SkIRect fRect;
+ };
+
protected:
// Extend access to GrDrawState::convertToPEndeingExec to subclasses.
void convertDrawStateToPendingExec(GrDrawState* ds) {
bool GrGpu::setupClipAndFlushState(DrawType type,
const GrDeviceCoordTexture* dstCopy,
- GrDrawState::AutoRestoreEffects* are,
- const SkRect* devBounds) {
- GrDrawState::AutoRestoreStencil asr;
- if (!fClipMaskManager.setupClipping(this->getClip(), are, &asr, devBounds)) {
+ const SkRect* devBounds,
+ GrDrawState::AutoRestoreEffects* are) {
+ ScissorState scissorState;
+ GrDrawState::AutoRestoreStencil ars;
+ if (!fClipMaskManager.setupClipping(this->getClip(),
+ devBounds,
+ are,
+ &ars,
+ &scissorState)) {
return false;
}
- if (!this->flushGraphicsState(type, dstCopy)) {
+ if (!this->flushGraphicsState(type, scissorState, dstCopy)) {
return false;
}
this->handleDirtyContext();
GrDrawState::AutoRestoreEffects are;
if (!this->setupClipAndFlushState(PrimTypeToDrawType(info.primitiveType()),
- info.getDstCopy(), &are, info.getDevBounds())) {
+ info.getDstCopy(),
+ info.getDevBounds(),
+ &are)) {
return;
}
this->onGpuDraw(info);
this->handleDirtyContext();
GrDrawState::AutoRestoreEffects are;
- if (!this->setupClipAndFlushState(kStencilPath_DrawType, NULL, &are, NULL)) {
+ if (!this->setupClipAndFlushState(kStencilPath_DrawType, NULL, NULL, &are)) {
return;
}
drawState()->setDefaultVertexAttribs();
GrDrawState::AutoRestoreEffects are;
- if (!this->setupClipAndFlushState(kDrawPath_DrawType, dstCopy, &are, NULL)) {
+ if (!this->setupClipAndFlushState(kDrawPath_DrawType, dstCopy, NULL, &are)) {
return;
}
drawState()->setDefaultVertexAttribs();
GrDrawState::AutoRestoreEffects are;
- if (!this->setupClipAndFlushState(kDrawPaths_DrawType, dstCopy, &are, NULL)) {
+ if (!this->setupClipAndFlushState(kDrawPaths_DrawType, dstCopy, NULL, &are)) {
return;
}
return fResetTimestamp;
}
- /**
- * These methods are called by the clip manager's setupClipping function
- * which (called as part of GrGpu's implementation of onDraw and
- * onStencilPath member functions.) The GrGpu subclass should flush the
- * stencil state to the 3D API in its implementation of flushGraphicsState.
- */
- void enableScissor(const SkIRect& rect) {
- fScissorState.fEnabled = true;
- fScissorState.fRect = rect;
- }
- void disableScissor() { fScissorState.fEnabled = false; }
-
// 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
// expensive than clearing all bits.
// prepares clip flushes gpu state before a draw
bool setupClipAndFlushState(DrawType,
const GrDeviceCoordTexture* dstCopy,
- GrDrawState::AutoRestoreEffects*,
- const SkRect* devBounds);
+ const SkRect* devBounds,
+ GrDrawState::AutoRestoreEffects*);
// Functions used to map clip-respecting stencil tests into normal
// stencil funcs supported by GPUs.
return fGeomPoolStateStack.back();
}
- // The state of the scissor is controlled by the clip manager
- struct ScissorState {
- bool fEnabled;
- SkIRect fRect;
- } fScissorState;
-
// Helpers for setting up geometry state
void finalizeReservedVertices();
void finalizeReservedIndices();
// deltas from previous state at draw time. This function does the
// backend-specific flush of the state.
// returns false if current state is unsupported.
- virtual bool flushGraphicsState(DrawType, const GrDeviceCoordTexture* dstCopy) = 0;
+ virtual bool flushGraphicsState(DrawType,
+ const ScissorState&,
+ const GrDeviceCoordTexture* dstCopy) = 0;
// clears target's entire stencil buffer to 0
virtual void clearStencil(GrRenderTarget* target) = 0;
}
}
-void GrGpuGL::flushScissor(const GrGLIRect& rtViewport, GrSurfaceOrigin rtOrigin) {
- if (fScissorState.fEnabled) {
+void GrGpuGL::flushScissor(const ScissorState& scissorState,
+ const GrGLIRect& rtViewport,
+ GrSurfaceOrigin rtOrigin) {
+ if (scissorState.fEnabled) {
GrGLIRect scissor;
scissor.setRelativeTo(rtViewport,
- fScissorState.fRect.fLeft,
- fScissorState.fRect.fTop,
- fScissorState.fRect.width(),
- fScissorState.fRect.height(),
+ scissorState.fRect.fLeft,
+ scissorState.fRect.fTop,
+ scissorState.fRect.width(),
+ scissorState.fRect.height(),
rtOrigin);
// if the scissor fully contains the viewport then we fall through and
// disable the scissor test.
return;
}
}
+
+ // See fall through note above
+ this->disableScissor();
+}
+
+void GrGpuGL::disableScissor() {
if (kNo_TriState != fHWScissorSettings.fEnabled) {
GL_CALL(Disable(GR_GL_SCISSOR_TEST));
fHWScissorSettings.fEnabled = kNo_TriState;
}
this->flushRenderTarget(glRT, rect);
- GrAutoTRestore<ScissorState> asr(&fScissorState);
- fScissorState.fEnabled = SkToBool(rect);
- if (fScissorState.fEnabled) {
- fScissorState.fRect = *rect;
+ ScissorState scissorState;
+ scissorState.fEnabled = SkToBool(rect);
+ if (scissorState.fEnabled) {
+ scissorState.fRect = *rect;
}
- this->flushScissor(glRT->getViewport(), glRT->origin());
+ this->flushScissor(scissorState, glRT->getViewport(), glRT->origin());
GrGLfloat r, g, b, a;
static const GrGLfloat scale255 = 1.f / 255.f;
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
this->flushRenderTarget(glRT, &SkIRect::EmptyIRect());
- GrAutoTRestore<ScissorState> asr(&fScissorState);
- fScissorState.fEnabled = false;
- this->flushScissor(glRT->getViewport(), glRT->origin());
+ this->disableScissor();
GL_CALL(StencilMask(0xffffffff));
GL_CALL(ClearStencil(0));
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
this->flushRenderTarget(glRT, &SkIRect::EmptyIRect());
- GrAutoTRestore<ScissorState> asr(&fScissorState);
- fScissorState.fEnabled = true;
- fScissorState.fRect = rect;
- this->flushScissor(glRT->getViewport(), glRT->origin());
+ ScissorState scissorState;
+ scissorState.fEnabled = true;
+ scissorState.fRect = rect;
+ this->flushScissor(scissorState, glRT->getViewport(), glRT->origin());
GL_CALL(StencilMask((uint32_t) clipStencilMask));
GL_CALL(ClearStencil(value));
r.setRelativeTo(vp, dirtyRect.fLeft, dirtyRect.fTop,
dirtyRect.width(), dirtyRect.height(), target->origin());
- GrAutoTRestore<ScissorState> asr;
if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) {
// Apple's extension uses the scissor as the blit bounds.
- asr.reset(&fScissorState);
- fScissorState.fEnabled = true;
- fScissorState.fRect = dirtyRect;
- this->flushScissor(rt->getViewport(), rt->origin());
+ ScissorState scissorState;
+ scissorState.fEnabled = true;
+ scissorState.fRect = dirtyRect;
+ this->flushScissor(scissorState, rt->getViewport(), rt->origin());
GL_CALL(ResolveMultisampleFramebuffer());
} else {
int right = r.fLeft + r.fWidth;
int top = r.fBottom + r.fHeight;
// BlitFrameBuffer respects the scissor, so disable it.
- asr.reset(&fScissorState);
- fScissorState.fEnabled = false;
- this->flushScissor(rt->getViewport(), rt->origin());
+ this->disableScissor();
GL_CALL(BlitFramebuffer(r.fLeft, r.fBottom, right, top,
r.fLeft, r.fBottom, right, top,
GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
dstRect.height(),
dst->origin());
- GrAutoTRestore<ScissorState> asr;
// BlitFrameBuffer respects the scissor, so disable it.
- asr.reset(&fScissorState);
- fScissorState.fEnabled = false;
- this->flushScissor(dstGLRect, dst->origin());
+ this->disableScissor();
GrGLint srcY0;
GrGLint srcY1;
virtual void clearStencil(GrRenderTarget*) SK_OVERRIDE;
virtual void clearStencilClip(GrRenderTarget*, const SkIRect& rect,
bool insideClip) SK_OVERRIDE;
- virtual bool flushGraphicsState(DrawType, const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
+ virtual bool flushGraphicsState(DrawType,
+ const ScissorState&,
+ const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
// GrDrawTarget overrides
virtual void didAddGpuTraceMarker() SK_OVERRIDE;
// flushes the scissor. see the note on flushBoundTextureAndParams about
// flushing the scissor after that function is called.
- void flushScissor(const GrGLIRect& rtViewport, GrSurfaceOrigin rtOrigin);
+ void flushScissor(const ScissorState&,
+ const GrGLIRect& rtViewport,
+ GrSurfaceOrigin rtOrigin);
+
+ // disables the scissor
+ void disableScissor();
void initFSAASupport();
#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
-bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstCopy) {
+bool GrGpuGL::flushGraphicsState(DrawType type,
+ const ScissorState& scissorState,
+ const GrDeviceCoordTexture* dstCopy) {
SkAutoTUnref<GrOptDrawState> optState(GrOptDrawState::Create(this->getDrawState(),
*this->caps(),
type));
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(optState->getRenderTarget());
this->flushStencil(optState->getStencil(), type);
- this->flushScissor(glRT->getViewport(), glRT->origin());
+ this->flushScissor(scissorState, glRT->getViewport(), glRT->origin());
this->flushAAState(*optState.get(), type);
SkIRect* devRect = NULL;