Attempt to reland r7713 with fix.
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 13 Feb 2013 16:03:51 +0000 (16:03 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 13 Feb 2013 16:03:51 +0000 (16:03 +0000)
git-svn-id: http://skia.googlecode.com/svn/trunk@7719 2bbb7eff-a529-9590-31e7-b0007b416f81

src/gpu/gl/GrGLProgram.cpp
src/gpu/gl/GrGLProgram.h
src/gpu/gl/GrGpuGL.cpp
src/gpu/gl/GrGpuGL.h
src/gpu/gl/GrGpuGL_program.cpp

index 75f9ea6ad5864e5380ce4e29f4ad7069d39119c1..a5014a6a9d3b072cf726502616b36e14ad9aaa60 100644 (file)
@@ -211,12 +211,8 @@ GrGLProgram::GrGLProgram(const GrGLContextInfo& gl,
     fFShaderID = 0;
     fProgramID = 0;
 
-    fViewMatrix = SkMatrix::InvalidMatrix();
-    fViewportSize.set(-1, -1);
-    fOrigin = (GrSurfaceOrigin) -1;
     fColor = GrColor_ILLEGAL;
     fColorFilterColor = GrColor_ILLEGAL;
-    fRTHeight = -1;
 
     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
         fEffects[s] = NULL;
@@ -1051,15 +1047,9 @@ void GrGLProgram::setData(GrGpuGL* gpu,
                           SharedGLState* sharedState) {
     const GrDrawState& drawState = gpu->getDrawState();
 
-    int rtHeight = drawState.getRenderTarget()->height();
-    if (GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fRTHeightUni &&
-        fRTHeight != rtHeight) {
-        fUniformManager.set1f(fUniformHandles.fRTHeightUni, SkIntToScalar(rtHeight));
-        fRTHeight = rtHeight;
-    }
-
     this->setColor(drawState, color, sharedState);
     this->setCoverage(drawState, coverage, sharedState);
+    this->setMatrixAndRenderTargetHeight(drawState);
 
     // Setup the SkXfermode::Mode-based colorfilter uniform if necessary
     if (GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fColorFilterUni &&
@@ -1157,3 +1147,50 @@ void GrGLProgram::setCoverage(const GrDrawState& drawState,
         }
     }
 }
+
+void GrGLProgram::setMatrixAndRenderTargetHeight(const GrDrawState& drawState) {
+    const GrRenderTarget* rt = drawState.getRenderTarget();
+    SkISize size;
+    size.set(rt->width(), rt->height());
+
+    // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
+    if (GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fRTHeightUni &&
+        fMatrixState.fRenderTargetSize.fHeight != size.fHeight) {
+        fUniformManager.set1f(fUniformHandles.fRTHeightUni, SkIntToScalar(size.fHeight));
+    }
+
+    if (fMatrixState.fRenderTargetOrigin != rt->origin() ||
+        !fMatrixState.fViewMatrix.cheapEqualTo(drawState.getViewMatrix()) ||
+        fMatrixState.fRenderTargetSize != size) {
+        SkMatrix m;
+        if (kBottomLeft_GrSurfaceOrigin == rt->origin()) {
+            m.setAll(
+                SkIntToScalar(2) / size.fWidth, 0, -SK_Scalar1,
+                0,-SkIntToScalar(2) / size.fHeight, SK_Scalar1,
+            0, 0, SkMatrix::I()[8]);
+        } else {
+            m.setAll(
+                SkIntToScalar(2) / size.fWidth, 0, -SK_Scalar1,
+                0, SkIntToScalar(2) / size.fHeight,-SK_Scalar1,
+            0, 0, SkMatrix::I()[8]);
+        }
+        m.setConcat(m, drawState.getViewMatrix());
+
+        // ES doesn't allow you to pass true to the transpose param so we do our own transpose.
+        GrGLfloat mt[]  = {
+            SkScalarToFloat(m[SkMatrix::kMScaleX]),
+            SkScalarToFloat(m[SkMatrix::kMSkewY]),
+            SkScalarToFloat(m[SkMatrix::kMPersp0]),
+            SkScalarToFloat(m[SkMatrix::kMSkewX]),
+            SkScalarToFloat(m[SkMatrix::kMScaleY]),
+            SkScalarToFloat(m[SkMatrix::kMPersp1]),
+            SkScalarToFloat(m[SkMatrix::kMTransX]),
+            SkScalarToFloat(m[SkMatrix::kMTransY]),
+            SkScalarToFloat(m[SkMatrix::kMPersp2])
+        };
+        fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, mt);
+        fMatrixState.fViewMatrix = drawState.getViewMatrix();
+        fMatrixState.fRenderTargetSize = size;
+        fMatrixState.fRenderTargetOrigin = rt->origin();
+    }
+}
index fd5e8e4b8ec61cd0bec71c9477591295d4a519ed..5d02ba2a9cef85d359e783177fd600ab9ee91293 100644 (file)
@@ -73,6 +73,11 @@ public:
 
     const Desc& getDesc() { return fDesc; }
 
+    /**
+     * Gets the GL program ID for this program.
+     */
+    GrGLuint programID() const { return fProgramID; }
+
     /**
      * Attribute indices. These should not overlap.
      */
@@ -98,6 +103,25 @@ public:
         }
     };
 
+    /**
+     * The GrDrawState's view matrix along with the aspects of the render target determine the
+     * matrix sent to GL. The size of the render target affects the GL matrix because we must
+     * convert from Skia device coords to GL's normalized coords. Also the origin of the render
+     * target may require us to perform a mirror-flip.
+     */
+    struct MatrixState {
+        SkMatrix        fViewMatrix;
+        SkISize         fRenderTargetSize;
+        GrSurfaceOrigin fRenderTargetOrigin;
+
+        MatrixState() { this->invalidate(); }
+        void invalidate() {
+            fViewMatrix = SkMatrix::InvalidMatrix();
+            fRenderTargetSize.fWidth = -1; // just make the first value compared illegal.
+            fRenderTargetOrigin = (GrSurfaceOrigin) -1;
+        }
+    };
+
     /**
      * This function uploads uniforms and calls each GrGLEffect's setData. It is called before a
      * draw occurs using the program after the program has already been bound. It also uses the
@@ -174,6 +198,7 @@ public:
 
         friend class GrGLProgram;
     };
+
 private:
     GrGLProgram(const GrGLContextInfo& gl,
                 const Desc& desc,
@@ -220,6 +245,9 @@ private:
     // per-vertex coverages.
     void setCoverage(const GrDrawState&, GrColor coverage, SharedGLState*);
 
+    // Helper for setData() that sets the view matrix and loads the render target height uniform
+    void setMatrixAndRenderTargetHeight(const GrDrawState&);
+
     typedef SkSTArray<4, UniformHandle, true> SamplerUniSArray;
 
     struct UniformHandles {
@@ -247,17 +275,12 @@ private:
     GrGLuint                    fGShaderID;
     GrGLuint                    fFShaderID;
     GrGLuint                    fProgramID;
-    // The matrix sent to GL is determined by the client's matrix,
-    // the size of the viewport, and the origin of the render target.
-    SkMatrix                    fViewMatrix;
-    SkISize                     fViewportSize;
-    GrSurfaceOrigin             fOrigin;
 
     // these reflect the current values of uniforms (GL uniform values travel with program)
+    MatrixState                 fMatrixState;
     GrColor                     fColor;
     GrColor                     fCoverage;
     GrColor                     fColorFilterColor;
-    int                         fRTHeight;
 
     GrGLEffect*                 fEffects[GrDrawState::kNumStages];
 
@@ -267,8 +290,6 @@ private:
     GrGLUniformManager          fUniformManager;
     UniformHandles              fUniformHandles;
 
-    friend class GrGpuGL; // TODO: remove this by adding getters and moving functionality.
-
     typedef GrRefCnt INHERITED;
 };
 
index 56a29919fc6917cace2d752ca5607bb92ced298b..f14238cdd91ecdf7ca773ce60976d7b44fa2b3ff 100644 (file)
@@ -188,7 +188,7 @@ GrGpuGL::~GrGpuGL() {
     if (0 != fHWProgramID) {
         // detach the current program so there is no confusion on OpenGL's part
         // that we want it to be deleted
-        GrAssert(fHWProgramID == fCurrentProgram->fProgramID);
+        GrAssert(fHWProgramID == fCurrentProgram->programID());
         GL_CALL(UseProgram(0));
     }
 
@@ -453,7 +453,7 @@ void GrGpuGL::onResetContext() {
 
     fHWBoundRenderTarget = NULL;
 
-    fHWPathMatrixState.invalidate();
+    fHWPathStencilMatrixState.invalidate();
     if (fCaps.pathStencilingSupport()) {
         // we don't use the model view matrix.
         GL_CALL(MatrixMode(GR_GL_MODELVIEW));
index b911f40b7604cbe3d6a3a0288af0bf87daf226bf..505c99c37420bc7a3a16ed9b7b4554c4802e3707 100644 (file)
@@ -181,9 +181,8 @@ private:
         const GrGLContextInfo&      fGL;
     };
 
-
-    // sets the MVP matrix uniform for currently bound program
-    void flushViewMatrix(DrawType type);
+    // sets the matrix for path stenciling (uses the GL fixed pipe matrices)
+    void flushPathStencilMatrix();
 
     // flushes dithering, color-mask, and face culling stat
     void flushMiscFixedFunctionState();
@@ -305,25 +304,17 @@ private:
         }
     } fHWAAState;
 
-    struct {
-        SkMatrix            fViewMatrix;
-        SkISize             fRTSize;
-        GrSurfaceOrigin     fLastOrigin;
-        void invalidate() {
-            fViewMatrix = SkMatrix::InvalidMatrix();
-            fRTSize.fWidth = -1; // just make the first value compared illegal.
-            fLastOrigin = (GrSurfaceOrigin) -1;
-        }
-    } fHWPathMatrixState;
 
-    GrStencilSettings       fHWStencilSettings;
-    TriState                fHWStencilTestEnabled;
+    GrGLProgram::MatrixState    fHWPathStencilMatrixState;
+
+    GrStencilSettings           fHWStencilSettings;
+    TriState                    fHWStencilTestEnabled;
 
-    GrDrawState::DrawFace   fHWDrawFace;
-    TriState                fHWWriteToColor;
-    TriState                fHWDitherEnabled;
-    GrRenderTarget*         fHWBoundRenderTarget;
-    GrTexture*              fHWBoundTextures[GrDrawState::kNumStages];
+    GrDrawState::DrawFace       fHWDrawFace;
+    TriState                    fHWWriteToColor;
+    TriState                    fHWDitherEnabled;
+    GrRenderTarget*             fHWBoundRenderTarget;
+    GrTexture*                  fHWBoundTextures[GrDrawState::kNumStages];
     ///@}
 
     // we record what stencil format worked last time to hopefully exit early
index feff02e94d71a92dce43b8ef9c402b6abbffc9c8..8ebe7a2d41686aa0aa1f8fac87f82d277f90cfb2 100644 (file)
@@ -82,106 +82,68 @@ void GrGpuGL::abandonResources(){
 
 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
 
-void GrGpuGL::flushViewMatrix(DrawType type) {
-    const GrGLRenderTarget* rt = static_cast<const GrGLRenderTarget*>(this->getDrawState().getRenderTarget());
-    SkISize viewportSize;
-    const GrGLIRect& viewport = rt->getViewport();
-    viewportSize.set(viewport.fWidth, viewport.fHeight);
-
+void GrGpuGL::flushPathStencilMatrix() {
+    const SkMatrix& viewMatrix = this->getDrawState().getViewMatrix();
+    const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
+    SkISize size;
+    size.set(rt->width(), rt->height());
     const SkMatrix& vm = this->getDrawState().getViewMatrix();
 
-    if (kStencilPath_DrawType == type) {
-        if (fHWPathMatrixState.fLastOrigin != rt->origin() ||
-            fHWPathMatrixState.fViewMatrix != vm ||
-            fHWPathMatrixState.fRTSize != viewportSize) {
-            // rescale the coords from skia's "device" coords to GL's normalized coords,
-            // and perform a y-flip if required.
-            SkMatrix m;
-            if (kBottomLeft_GrSurfaceOrigin == rt->origin()) {
-                m.setScale(SkIntToScalar(2) / rt->width(), SkIntToScalar(-2) / rt->height());
-                m.postTranslate(-SK_Scalar1, SK_Scalar1);
-            } else {
-                m.setScale(SkIntToScalar(2) / rt->width(), SkIntToScalar(2) / rt->height());
-                m.postTranslate(-SK_Scalar1, -SK_Scalar1);
-            }
-            m.preConcat(vm);
-
-            // GL wants a column-major 4x4.
-            GrGLfloat mv[]  = {
-                // col 0
-                SkScalarToFloat(m[SkMatrix::kMScaleX]),
-                SkScalarToFloat(m[SkMatrix::kMSkewY]),
-                0,
-                SkScalarToFloat(m[SkMatrix::kMPersp0]),
-
-                // col 1
-                SkScalarToFloat(m[SkMatrix::kMSkewX]),
-                SkScalarToFloat(m[SkMatrix::kMScaleY]),
-                0,
-                SkScalarToFloat(m[SkMatrix::kMPersp1]),
-
-                // col 2
-                0, 0, 0, 0,
-
-                // col3
-                SkScalarToFloat(m[SkMatrix::kMTransX]),
-                SkScalarToFloat(m[SkMatrix::kMTransY]),
-                0.0f,
-                SkScalarToFloat(m[SkMatrix::kMPersp2])
-            };
-            GL_CALL(MatrixMode(GR_GL_PROJECTION));
-            GL_CALL(LoadMatrixf(mv));
-            fHWPathMatrixState.fViewMatrix = vm;
-            fHWPathMatrixState.fRTSize = viewportSize;
-            fHWPathMatrixState.fLastOrigin = rt->origin();
-        }
-    } else if (fCurrentProgram->fOrigin != rt->origin() ||
-               !fCurrentProgram->fViewMatrix.cheapEqualTo(vm) ||
-               fCurrentProgram->fViewportSize != viewportSize) {
+    if (fHWPathStencilMatrixState.fRenderTargetOrigin != rt->origin() ||
+        fHWPathStencilMatrixState.fViewMatrix.cheapEqualTo(viewMatrix) ||
+        fHWPathStencilMatrixState.fRenderTargetSize!= size) {
+        // rescale the coords from skia's "device" coords to GL's normalized coords,
+        // and perform a y-flip if required.
         SkMatrix m;
         if (kBottomLeft_GrSurfaceOrigin == rt->origin()) {
-            m.setAll(
-                SkIntToScalar(2) / viewportSize.fWidth, 0, -SK_Scalar1,
-                0,-SkIntToScalar(2) / viewportSize.fHeight, SK_Scalar1,
-            0, 0, SkMatrix::I()[8]);
+            m.setScale(SkIntToScalar(2) / rt->width(), SkIntToScalar(-2) / rt->height());
+            m.postTranslate(-SK_Scalar1, SK_Scalar1);
         } else {
-            m.setAll(
-                SkIntToScalar(2) / viewportSize.fWidth, 0, -SK_Scalar1,
-                0, SkIntToScalar(2) / viewportSize.fHeight,-SK_Scalar1,
-            0, 0, SkMatrix::I()[8]);
+            m.setScale(SkIntToScalar(2) / rt->width(), SkIntToScalar(2) / rt->height());
+            m.postTranslate(-SK_Scalar1, -SK_Scalar1);
         }
-        m.setConcat(m, vm);
+        m.preConcat(vm);
 
-        // ES doesn't allow you to pass true to the transpose param,
-        // so do our own transpose
-        GrGLfloat mt[]  = {
+        // GL wants a column-major 4x4.
+        GrGLfloat mv[]  = {
+            // col 0
             SkScalarToFloat(m[SkMatrix::kMScaleX]),
             SkScalarToFloat(m[SkMatrix::kMSkewY]),
+            0,
             SkScalarToFloat(m[SkMatrix::kMPersp0]),
+
+            // col 1
             SkScalarToFloat(m[SkMatrix::kMSkewX]),
             SkScalarToFloat(m[SkMatrix::kMScaleY]),
+            0,
             SkScalarToFloat(m[SkMatrix::kMPersp1]),
+
+            // col 2
+            0, 0, 0, 0,
+
+            // col3
             SkScalarToFloat(m[SkMatrix::kMTransX]),
             SkScalarToFloat(m[SkMatrix::kMTransY]),
+            0.0f,
             SkScalarToFloat(m[SkMatrix::kMPersp2])
         };
-        fCurrentProgram->fUniformManager.setMatrix3f(
-                                            fCurrentProgram->fUniformHandles.fViewMatrixUni,
-                                            mt);
-        fCurrentProgram->fViewMatrix = vm;
-        fCurrentProgram->fViewportSize = viewportSize;
-        fCurrentProgram->fOrigin = rt->origin();
+        GL_CALL(MatrixMode(GR_GL_PROJECTION));
+        GL_CALL(LoadMatrixf(mv));
+        fHWPathStencilMatrixState.fViewMatrix = vm;
+        fHWPathStencilMatrixState.fRenderTargetSize = size;
+        fHWPathStencilMatrixState.fRenderTargetOrigin = rt->origin();
     }
 }
 
 bool GrGpuGL::flushGraphicsState(DrawType type) {
     const GrDrawState& drawState = this->getDrawState();
 
-    // GrGpu::setupClipAndFlushState should have already checked this
-    // and bailed if not true.
+    // GrGpu::setupClipAndFlushState should have already checked this and bailed if not true.
     GrAssert(NULL != drawState.getRenderTarget());
 
-    if (kStencilPath_DrawType != type) {
+    if (kStencilPath_DrawType == type) {
+        this->flushPathStencilMatrix();
+    } else {
         this->flushMiscFixedFunctionState();
 
         GrBlendCoeff srcCoeff;
@@ -211,10 +173,12 @@ bool GrGpuGL::flushGraphicsState(DrawType type) {
         }
         fCurrentProgram.get()->ref();
 
-        if (fHWProgramID != fCurrentProgram->fProgramID) {
-            GL_CALL(UseProgram(fCurrentProgram->fProgramID));
-            fHWProgramID = fCurrentProgram->fProgramID;
+        GrGLuint programID = fCurrentProgram->programID();
+        if (fHWProgramID != programID) {
+            GL_CALL(UseProgram(programID));
+            fHWProgramID = programID;
         }
+
         fCurrentProgram->overrideBlend(&srcCoeff, &dstCoeff);
         this->flushBlend(kDrawLines_DrawType == type, srcCoeff, dstCoeff);
 
@@ -233,7 +197,6 @@ bool GrGpuGL::flushGraphicsState(DrawType type) {
         fCurrentProgram->setData(this, color, coverage, &fSharedGLProgramState);
     }
     this->flushStencil(type);
-    this->flushViewMatrix(type);
     this->flushScissor();
     this->flushAAState(type);