Scissor rect on drawinfo
authorjoshualitt <joshualitt@chromium.org>
Mon, 27 Oct 2014 21:51:01 +0000 (14:51 -0700)
committerCommit bot <commit-bot@chromium.org>
Mon, 27 Oct 2014 21:51:01 +0000 (14:51 -0700)
BUG=skia:

Review URL: https://codereview.chromium.org/678683005

src/gpu/GrClipMaskManager.cpp
src/gpu/GrClipMaskManager.h
src/gpu/GrDrawTarget.h
src/gpu/GrGpu.cpp
src/gpu/GrGpu.h
src/gpu/gl/GrGpuGL.cpp
src/gpu/gl/GrGpuGL.h
src/gpu/gl/GrGpuGL_program.cpp

index 0738108..1d193a5 100644 (file)
@@ -211,9 +211,10 @@ bool GrClipMaskManager::installClipEffects(const GrReducedClip::ElementList& ele
 // 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);
@@ -249,8 +250,7 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
     }
 
     if (ignoreClip) {
-        fGpu->disableScissor();
-        this->setDrawStateStencil(asr);
+        this->setDrawStateStencil(ars);
         return true;
     }
 
@@ -271,11 +271,9 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
             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;
         }
     }
@@ -306,8 +304,7 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
             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
@@ -334,8 +331,8 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
     // 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;
 }
 
index 8a4b45a..ca5a247 100644 (file)
@@ -11,6 +11,7 @@
 #include "GrClipMaskCache.h"
 #include "GrContext.h"
 #include "GrDrawState.h"
+#include "GrDrawTarget.h"
 #include "GrReducedClip.h"
 #include "GrStencil.h"
 #include "GrTexture.h"
@@ -51,9 +52,10 @@ public:
      * 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
index 552314b..33d5efe 100644 (file)
@@ -37,7 +37,6 @@ protected:
 public:
     SK_DECLARE_INST_COUNT(GrDrawTarget)
 
-
     typedef GrPathRendering::PathTransformType PathTransformType ;
 
     ///////////////////////////////////////////////////////////////////////////
@@ -693,6 +692,15 @@ public:
 
     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) {
index 221aaec..5325aae 100644 (file)
@@ -300,14 +300,19 @@ const GrIndexBuffer* GrGpu::getQuadIndexBuffer() const {
 
 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;
     }
 
@@ -347,7 +352,9 @@ void GrGpu::onDraw(const DrawInfo& info) {
     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);
@@ -357,7 +364,7 @@ void GrGpu::onStencilPath(const GrPath* path, SkPath::FillType fill) {
     this->handleDirtyContext();
 
     GrDrawState::AutoRestoreEffects are;
-    if (!this->setupClipAndFlushState(kStencilPath_DrawType, NULL, &are, NULL)) {
+    if (!this->setupClipAndFlushState(kStencilPath_DrawType, NULL, NULL, &are)) {
         return;
     }
 
@@ -372,7 +379,7 @@ void GrGpu::onDrawPath(const GrPath* path, SkPath::FillType fill,
     drawState()->setDefaultVertexAttribs();
 
     GrDrawState::AutoRestoreEffects are;
-    if (!this->setupClipAndFlushState(kDrawPath_DrawType, dstCopy, &are, NULL)) {
+    if (!this->setupClipAndFlushState(kDrawPath_DrawType, dstCopy, NULL, &are)) {
         return;
     }
 
@@ -388,7 +395,7 @@ void GrGpu::onDrawPaths(const GrPathRange* pathRange,
     drawState()->setDefaultVertexAttribs();
 
     GrDrawState::AutoRestoreEffects are;
-    if (!this->setupClipAndFlushState(kDrawPaths_DrawType, dstCopy, &are, NULL)) {
+    if (!this->setupClipAndFlushState(kDrawPaths_DrawType, dstCopy, NULL, &are)) {
         return;
     }
 
index cb14696..34b417c 100644 (file)
@@ -294,18 +294,6 @@ public:
         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.
@@ -357,8 +345,8 @@ protected:
     // 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.
@@ -386,12 +374,6 @@ protected:
         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();
@@ -464,7 +446,9 @@ private:
     // 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;
index 75c9b3a..7b89291 100644 (file)
@@ -1360,14 +1360,16 @@ GrIndexBuffer* GrGpuGL::onCreateIndexBuffer(size_t size, bool dynamic) {
     }
 }
 
-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.
@@ -1383,6 +1385,12 @@ void GrGpuGL::flushScissor(const GrGLIRect& rtViewport, GrSurfaceOrigin rtOrigin
             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;
@@ -1413,12 +1421,12 @@ void GrGpuGL::onClear(GrRenderTarget* target, const SkIRect* rect, GrColor color
     }
 
     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;
@@ -1496,9 +1504,7 @@ void GrGpuGL::clearStencil(GrRenderTarget* target) {
     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));
@@ -1533,10 +1539,10 @@ void GrGpuGL::clearStencilClip(GrRenderTarget* target, const SkIRect& rect, bool
     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));
@@ -1826,22 +1832,19 @@ void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
             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));
@@ -2508,11 +2511,8 @@ bool GrGpuGL::onCopySurface(GrSurface* dst,
                                     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;
index f18962c..973a568 100644 (file)
@@ -148,7 +148,9 @@ private:
     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;
@@ -220,7 +222,12 @@ private:
 
     // 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();
 
index ecfd813..bf73f00 100644 (file)
@@ -203,7 +203,9 @@ GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrOptDrawState& optState,
 
 #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));
@@ -259,7 +261,7 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
 
     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;