clear stencil clip on draw target
TBR=
BUG=skia:
Review URL: https://codereview.chromium.org/683673002
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index 2c3411d..743f191 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -214,7 +214,7 @@
const SkRect* devBounds,
GrDrawState::AutoRestoreEffects* are,
GrDrawState::AutoRestoreStencil* ars,
- GrDrawTarget::ScissorState* scissorState) {
+ ScissorState* scissorState) {
fCurrClipMaskType = kNone_ClipMaskType;
GrReducedClip::ElementList elements(16);
@@ -731,8 +731,9 @@
SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil buffers");
clipBit = (1 << (clipBit-1));
- fGpu->clearStencilClip(rt, stencilSpaceIBounds,
- GrReducedClip::kAllIn_InitialState == initialState);
+ fGpu->clearStencilClip(stencilSpaceIBounds,
+ GrReducedClip::kAllIn_InitialState == initialState,
+ rt);
// walk through each clip element and perform its set op
// with the existing clip.
diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h
index ca5a247..fe1ff0e 100644
--- a/src/gpu/GrClipMaskManager.h
+++ b/src/gpu/GrClipMaskManager.h
@@ -11,7 +11,6 @@
#include "GrClipMaskCache.h"
#include "GrContext.h"
#include "GrDrawState.h"
-#include "GrDrawTarget.h"
#include "GrReducedClip.h"
#include "GrStencil.h"
#include "GrTexture.h"
@@ -44,6 +43,16 @@
, fCurrClipMaskType(kNone_ClipMaskType) {
}
+ // The state of the scissor is controlled by the clip manager, no one else should set
+ // Scissor state. This should really be on Gpu itself. We should revist this when GPU
+ // and drawtarget are separate
+ struct ScissorState {
+ ScissorState() : fEnabled(false) {}
+ void set(const SkIRect& rect) { fRect = rect; fEnabled = true; }
+ bool fEnabled;
+ SkIRect fRect;
+ };
+
/**
* Creates a clip mask if necessary as a stencil buffer or alpha texture
* and sets the GrGpu's scissor and stencil state. If the return is false
@@ -55,7 +64,7 @@
const SkRect* devBounds,
GrDrawState::AutoRestoreEffects*,
GrDrawState::AutoRestoreStencil*,
- GrDrawTarget::ScissorState* scissorState);
+ ScissorState* scissorState);
/**
* Purge resources to free up memory. TODO: This class shouldn't hold any long lived refs
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 3c2341a..3efa6bf 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -9,6 +9,7 @@
#define GrDrawTarget_DEFINED
#include "GrClipData.h"
+#include "GrClipMaskManager.h"
#include "GrContext.h"
#include "GrDrawState.h"
#include "GrIndexBuffer.h"
@@ -692,15 +693,6 @@
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) {
@@ -949,4 +941,19 @@
typedef SkRefCnt INHERITED;
};
+class GrClipTarget : public GrDrawTarget {
+public:
+ GrClipTarget(GrContext* context) : INHERITED(context) {}
+ /**
+ * Clip Mask Manager(and no one else) needs to clear private stencil bits.
+ * ClipTarget 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.
+ */
+ virtual void clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* = NULL) = 0;
+
+private:
+ typedef GrDrawTarget INHERITED;
+};
+
#endif
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 7e8c4c8..e767d07 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -28,7 +28,7 @@
#define DEBUG_INVAL_START_IDX -1
GrGpu::GrGpu(GrContext* context)
- : GrDrawTarget(context)
+ : INHERITED(context)
, fResetTimestamp(kExpiredTimestamp+1)
, fResetBits(kAll_GrBackendState)
, fVertexPool(NULL)
@@ -212,6 +212,20 @@
this->onClear(renderTarget, rect, color, canIgnoreRect);
}
+void GrGpu::clearStencilClip(const SkIRect& rect,
+ bool insideClip,
+ GrRenderTarget* renderTarget) {
+ if (NULL == renderTarget) {
+ renderTarget = this->getDrawState().getRenderTarget();
+ }
+ if (NULL == renderTarget) {
+ SkASSERT(0);
+ return;
+ }
+ this->handleDirtyContext();
+ this->onClearStencilClip(renderTarget, rect, insideClip);
+}
+
bool GrGpu::readPixels(GrRenderTarget* target,
int left, int top, int width, int height,
GrPixelConfig config, void* buffer,
@@ -302,7 +316,7 @@
const GrDeviceCoordTexture* dstCopy,
const SkRect* devBounds,
GrDrawState::AutoRestoreEffects* are) {
- ScissorState scissorState;
+ GrClipMaskManager::ScissorState scissorState;
GrDrawState::AutoRestoreStencil ars;
if (!fClipMaskManager.setupClipping(this->getClip(),
devBounds,
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 6814ae9..8fa81d6 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -23,7 +23,7 @@
class GrStencilBuffer;
class GrVertexBufferAllocPool;
-class GrGpu : public GrDrawTarget {
+class GrGpu : public GrClipTarget {
public:
/**
@@ -272,6 +272,10 @@
bool canIgnoreRect,
GrRenderTarget* renderTarget = NULL) SK_OVERRIDE;
+ virtual void clearStencilClip(const SkIRect& rect,
+ bool insideClip,
+ GrRenderTarget* renderTarget = NULL) SK_OVERRIDE;
+
virtual void purgeResources() SK_OVERRIDE {
// The clip mask manager can rebuild all its clip masks so just
// get rid of them all.
@@ -295,11 +299,6 @@
return fResetTimestamp;
}
- // 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.
- virtual void clearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) = 0;
-
enum PrivateDrawStateStateBits {
kFirstBit = (GrDrawState::kLastPublicStateBit << 1),
@@ -422,6 +421,13 @@
virtual void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
bool canIgnoreRect) = 0;
+
+ // Overridden by backend specific classes to perform a clear of the stencil clip bits. This is
+ // ONLY used by the the clip target
+ virtual void onClearStencilClip(GrRenderTarget*,
+ const SkIRect& rect,
+ bool insideClip) = 0;
+
// overridden by backend-specific derived class to perform the draw call.
virtual void onGpuDraw(const DrawInfo&) = 0;
@@ -454,7 +460,7 @@
// backend-specific flush of the state.
// returns false if current state is unsupported.
virtual bool flushGraphicsState(DrawType,
- const ScissorState&,
+ const GrClipMaskManager::ScissorState&,
const GrDeviceCoordTexture* dstCopy) = 0;
// clears target's entire stencil buffer to 0
@@ -507,7 +513,7 @@
// these are mutable so they can be created on-demand
mutable GrIndexBuffer* fQuadIndexBuffer;
- typedef GrDrawTarget INHERITED;
+ typedef GrClipTarget INHERITED;
};
#endif
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index 47fff6f..dcd09dd 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -17,7 +17,7 @@
GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu,
GrVertexBufferAllocPool* vertexPool,
GrIndexBufferAllocPool* indexPool)
- : GrDrawTarget(gpu->getContext())
+ : INHERITED(gpu->getContext())
, fCmdBuffer(kCmdBufferInitialSizeInBytes)
, fLastState(NULL)
, fLastClip(NULL)
@@ -434,6 +434,19 @@
this->recordTraceMarkersIfNecessary();
}
+void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
+ bool insideClip,
+ GrRenderTarget* renderTarget) {
+ if (NULL == renderTarget) {
+ renderTarget = this->drawState()->getRenderTarget();
+ SkASSERT(renderTarget);
+ }
+ ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilClip, (renderTarget));
+ clr->fRect = rect;
+ clr->fInsideClip = insideClip;
+ this->recordTraceMarkersIfNecessary();
+}
+
void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
if (!this->caps()->discardRenderTargetSupport()) {
return;
@@ -523,7 +536,7 @@
++fDrawID;
}
-void GrInOrderDrawBuffer::Draw::execute(GrDrawTarget* gpu) {
+void GrInOrderDrawBuffer::Draw::execute(GrClipTarget* gpu) {
gpu->setVertexSourceToBuffer(this->vertexBuffer());
if (fInfo.isIndexed()) {
gpu->setIndexSourceToBuffer(this->indexBuffer());
@@ -531,30 +544,30 @@
gpu->executeDraw(fInfo);
}
-void GrInOrderDrawBuffer::StencilPath::execute(GrDrawTarget* gpu) {
+void GrInOrderDrawBuffer::StencilPath::execute(GrClipTarget* gpu) {
gpu->stencilPath(this->path(), fFill);
}
-void GrInOrderDrawBuffer::DrawPath::execute(GrDrawTarget* gpu) {
+void GrInOrderDrawBuffer::DrawPath::execute(GrClipTarget* gpu) {
gpu->executeDrawPath(this->path(), fFill, fDstCopy.texture() ? &fDstCopy : NULL);
}
-void GrInOrderDrawBuffer::DrawPaths::execute(GrDrawTarget* gpu) {
+void GrInOrderDrawBuffer::DrawPaths::execute(GrClipTarget* gpu) {
gpu->executeDrawPaths(this->pathRange(), this->indices(), fCount, this->transforms(),
fTransformsType, fFill, fDstCopy.texture() ? &fDstCopy : NULL);
}
-void GrInOrderDrawBuffer::SetState::execute(GrDrawTarget* gpu) {
+void GrInOrderDrawBuffer::SetState::execute(GrClipTarget* gpu) {
gpu->setDrawState(&fState);
}
-void GrInOrderDrawBuffer::SetClip::execute(GrDrawTarget* gpu) {
+void GrInOrderDrawBuffer::SetClip::execute(GrClipTarget* gpu) {
// Our fClipData is referenced directly, so we must remain alive for the entire
// duration of the flush (after which the gpu's previous clip is restored).
gpu->setClip(&fClipData);
}
-void GrInOrderDrawBuffer::Clear::execute(GrDrawTarget* gpu) {
+void GrInOrderDrawBuffer::Clear::execute(GrClipTarget* gpu) {
if (GrColor_ILLEGAL == fColor) {
gpu->discard(this->renderTarget());
} else {
@@ -562,7 +575,11 @@
}
}
-void GrInOrderDrawBuffer::CopySurface::execute(GrDrawTarget* gpu) {
+void GrInOrderDrawBuffer::ClearStencilClip::execute(GrClipTarget* gpu) {
+ gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget());
+}
+
+void GrInOrderDrawBuffer::CopySurface::execute(GrClipTarget* gpu) {
gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
}
diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h
index 421a4a9..7b9a926 100644
--- a/src/gpu/GrInOrderDrawBuffer.h
+++ b/src/gpu/GrInOrderDrawBuffer.h
@@ -37,7 +37,7 @@
* in the GrGpu object that the buffer is played back into. The buffer requires VB and IB pools to
* store geometry.
*/
-class GrInOrderDrawBuffer : public GrDrawTarget {
+class GrInOrderDrawBuffer : public GrClipTarget {
public:
/**
@@ -75,11 +75,16 @@
// overrides from GrDrawTarget
virtual bool geometryHints(int* vertexCount,
int* indexCount) const SK_OVERRIDE;
+
virtual void clear(const SkIRect* rect,
GrColor color,
bool canIgnoreRect,
GrRenderTarget* renderTarget) SK_OVERRIDE;
+ virtual void clearStencilClip(const SkIRect& rect,
+ bool insideClip,
+ GrRenderTarget* renderTarget) SK_OVERRIDE;
+
virtual void discard(GrRenderTarget*) SK_OVERRIDE;
virtual void initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) SK_OVERRIDE;
@@ -103,7 +108,7 @@
Cmd(uint8_t type) : fType(type) {}
virtual ~Cmd() {}
- virtual void execute(GrDrawTarget*) = 0;
+ virtual void execute(GrClipTarget*) = 0;
uint8_t fType;
};
@@ -118,7 +123,7 @@
const GrVertexBuffer* vertexBuffer() const { return fVertexBuffer.get(); }
const GrIndexBuffer* indexBuffer() const { return fIndexBuffer.get(); }
- virtual void execute(GrDrawTarget*);
+ virtual void execute(GrClipTarget*);
DrawInfo fInfo;
@@ -132,7 +137,7 @@
const GrPath* path() const { return fPath.get(); }
- virtual void execute(GrDrawTarget*);
+ virtual void execute(GrClipTarget*);
SkPath::FillType fFill;
@@ -145,7 +150,7 @@
const GrPath* path() const { return fPath.get(); }
- virtual void execute(GrDrawTarget*);
+ virtual void execute(GrClipTarget*);
SkPath::FillType fFill;
GrDeviceCoordTexture fDstCopy;
@@ -161,7 +166,7 @@
uint32_t* indices() { return reinterpret_cast<uint32_t*>(CmdBuffer::GetDataForItem(this)); }
float* transforms() { return reinterpret_cast<float*>(&this->indices()[fCount]); }
- virtual void execute(GrDrawTarget*);
+ virtual void execute(GrClipTarget*);
size_t fCount;
PathTransformType fTransformsType;
@@ -178,7 +183,7 @@
GrRenderTarget* renderTarget() const { return fRenderTarget.get(); }
- virtual void execute(GrDrawTarget*);
+ virtual void execute(GrClipTarget*);
SkIRect fRect;
GrColor fColor;
@@ -188,13 +193,28 @@
GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> fRenderTarget;
};
+ // This command is ONLY used by the clip mask manager to clear the stencil clip bits
+ struct ClearStencilClip : public Cmd {
+ ClearStencilClip(GrRenderTarget* rt) : Cmd(kClear_Cmd), fRenderTarget(rt) {}
+
+ GrRenderTarget* renderTarget() const { return fRenderTarget.get(); }
+
+ virtual void execute(GrClipTarget*);
+
+ SkIRect fRect;
+ bool fInsideClip;
+
+ private:
+ GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> fRenderTarget;
+ };
+
struct CopySurface : public Cmd {
CopySurface(GrSurface* dst, GrSurface* src) : Cmd(kCopySurface_Cmd), fDst(dst), fSrc(src) {}
GrSurface* dst() const { return fDst.get(); }
GrSurface* src() const { return fSrc.get(); }
- virtual void execute(GrDrawTarget*);
+ virtual void execute(GrClipTarget*);
SkIPoint fDstPoint;
SkIRect fSrcRect;
@@ -207,7 +227,7 @@
struct SetState : public Cmd {
SetState(const GrDrawState& state) : Cmd(kSetState_Cmd), fState(state) {}
- virtual void execute(GrDrawTarget*);
+ virtual void execute(GrClipTarget*);
GrDrawState fState;
};
@@ -220,7 +240,7 @@
fClipData.fOrigin = clipData->fOrigin;
}
- virtual void execute(GrDrawTarget*);
+ virtual void execute(GrClipTarget*);
GrClipData fClipData;
@@ -300,7 +320,7 @@
GrClipData* fLastClip;
SkTArray<GrTraceMarkerSet, false> fGpuCmdMarkers;
- GrDrawTarget* fDstGpu;
+ GrClipTarget* fDstGpu;
bool fClipSet;
enum ClipProxyState {
@@ -332,7 +352,7 @@
bool fFlushing;
uint32_t fDrawID;
- typedef GrDrawTarget INHERITED;
+ typedef GrClipTarget INHERITED;
};
#endif
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 88e7be0..f79f90e 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -1359,7 +1359,7 @@
}
}
-void GrGpuGL::flushScissor(const ScissorState& scissorState,
+void GrGpuGL::flushScissor(const GrClipMaskManager::ScissorState& scissorState,
const GrGLIRect& rtViewport,
GrSurfaceOrigin rtOrigin) {
if (scissorState.fEnabled) {
@@ -1420,7 +1420,7 @@
}
this->flushRenderTarget(glRT, rect);
- ScissorState scissorState;
+ GrClipMaskManager::ScissorState scissorState;
scissorState.fEnabled = SkToBool(rect);
if (scissorState.fEnabled) {
scissorState.fRect = *rect;
@@ -1511,7 +1511,7 @@
fHWStencilSettings.invalidate();
}
-void GrGpuGL::clearStencilClip(GrRenderTarget* target, const SkIRect& rect, bool insideClip) {
+void GrGpuGL::onClearStencilClip(GrRenderTarget* target, const SkIRect& rect, bool insideClip) {
SkASSERT(target);
// this should only be called internally when we know we have a
@@ -1538,7 +1538,7 @@
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
this->flushRenderTarget(glRT, &SkIRect::EmptyIRect());
- ScissorState scissorState;
+ GrClipMaskManager::ScissorState scissorState;
scissorState.fEnabled = true;
scissorState.fRect = rect;
this->flushScissor(scissorState, glRT->getViewport(), glRT->origin());
@@ -1833,7 +1833,7 @@
if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) {
// Apple's extension uses the scissor as the blit bounds.
- ScissorState scissorState;
+ GrClipMaskManager::ScissorState scissorState;
scissorState.fEnabled = true;
scissorState.fRect = dirtyRect;
this->flushScissor(scissorState, rt->getViewport(), rt->origin());
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index 46d9700..568ce96 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -135,6 +135,10 @@
virtual void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
bool canIgnoreRect) SK_OVERRIDE;
+ virtual void onClearStencilClip(GrRenderTarget*,
+ const SkIRect& rect,
+ bool insideClip) SK_OVERRIDE;
+
virtual bool onReadPixels(GrRenderTarget* target,
int left, int top,
int width, int height,
@@ -153,10 +157,8 @@
virtual void clearStencil(GrRenderTarget*) SK_OVERRIDE;
- virtual void clearStencilClip(GrRenderTarget*, const SkIRect& rect,
- bool insideClip) SK_OVERRIDE;
virtual bool flushGraphicsState(DrawType,
- const ScissorState&,
+ const GrClipMaskManager::ScissorState&,
const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
// GrDrawTarget overrides
@@ -227,7 +229,7 @@
// flushes the scissor. see the note on flushBoundTextureAndParams about
// flushing the scissor after that function is called.
- void flushScissor(const ScissorState&,
+ void flushScissor(const GrClipMaskManager::ScissorState&,
const GrGLIRect& rtViewport,
GrSurfaceOrigin rtOrigin);
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index 23de7a8..330f348 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -202,7 +202,7 @@
#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
bool GrGpuGL::flushGraphicsState(DrawType type,
- const ScissorState& scissorState,
+ const GrClipMaskManager::ScissorState& scissorState,
const GrDeviceCoordTexture* dstCopy) {
SkAutoTUnref<GrOptDrawState> optState(GrOptDrawState::Create(this->getDrawState(),
this,