Fix some NV path rendering issues with perspective and inverse paths
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 29 Jun 2012 14:01:53 +0000 (14:01 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 29 Jun 2012 14:01:53 +0000 (14:01 +0000)
Review URL: http://codereview.appspot.com/6347050/

git-svn-id: http://skia.googlecode.com/svn/trunk@4403 2bbb7eff-a529-9590-31e7-b0007b416f81

src/gpu/GrStencilAndCoverPathRenderer.cpp
src/gpu/gl/GrGpuGL.cpp
src/gpu/gl/GrGpuGL_program.cpp

index 40d998b6e346bb0ba7ed56c06cec3a9b8cad9ed3..81dc1db00aa8934df79cd17227f90c032c7f4c00 100644 (file)
@@ -95,7 +95,10 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path,
         GR_STATIC_CONST_SAME_STENCIL(kInvertedStencilPass,
             kZero_StencilOp,
             kZero_StencilOp,
-            kEqual_StencilFunc,
+            // We know our rect will hit pixels outside the clip and the user bits will be 0
+            // outside the clip. So we can't just fill where the user bits are 0. We also need to
+            // check that the clip bit is set.
+            kEqualIfInClip_StencilFunc,
             0xffff,
             0x0000,
             0xffff);
@@ -106,7 +109,8 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path,
         // mapRect through persp matrix may not be correct
         if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) {
             vmi.mapRect(&bounds);
-            // theoretically could set bloat = 0, instead leave it because of matrix inversion precision.
+            // theoretically could set bloat = 0, instead leave it because of matrix inversion
+            // precision.
         } else {
             if (stageMask) {
                 if (!drawState->getViewInverse(&vmi)) {
index 48ccd5daf78c04fd55f9d30a530a68a63a1989f3..e49c6645c33b8f4bc924ff7fda894aa4fde14af9 100644 (file)
@@ -514,6 +514,11 @@ void GrGpuGL::onResetContext() {
     fHWBoundRenderTarget = NULL;
 
     fHWPathMatrixState.invalidate();
+    if (fCaps.fPathStencilingSupport) {
+        // we don't use the model view matrix.
+        GL_CALL(MatrixMode(GR_GL_MODELVIEW));
+        GL_CALL(LoadIdentity());
+    }
 
     // we assume these values
     if (this->glCaps().unpackRowLengthSupport()) {
index e33f469f9350232f0f42d366c46bef58b6ce9c93..d506c6c0294cd7a4e3c9216157eae997f2fc608d 100644 (file)
@@ -113,57 +113,45 @@ void GrGpuGL::flushViewMatrix(DrawType type) {
     const GrMatrix& vm = this->getDrawState().getViewMatrix();
 
     if (kStencilPath_DrawType == type) {
-        if (fHWPathMatrixState.fViewMatrix != vm) {
-            // We use the GL model view matrix to hold the draw state's view
-            // matrix and the GL projection matrix to convert to normalized y-up
-            // coords.
+        if (fHWPathMatrixState.fViewMatrix != vm ||
+            fHWPathMatrixState.fRTSize != viewportSize) {
+            // rescale the coords from skia's "device" coords to GL's normalized coords,
+            // and perform a y-flip.
+            GrMatrix m;
+            m.setScale(GrIntToScalar(2) / rt->width(), GrIntToScalar(-2) / rt->height());
+            m.postTranslate(-1.f , 1.f);
+            m.preConcat(vm);
+
+            // GL wants a column-major 4x4.
             GrGLfloat mv[]  = {
                 // col 0
-                GrScalarToFloat(vm[GrMatrix::kMScaleX]),
-                GrScalarToFloat(vm[GrMatrix::kMSkewY]),
+                GrScalarToFloat(m[GrMatrix::kMScaleX]),
+                GrScalarToFloat(m[GrMatrix::kMSkewY]),
                 0,
-                GrScalarToFloat(vm[GrMatrix::kMPersp0]),
+                GrScalarToFloat(m[GrMatrix::kMPersp0]),
 
                 // col 1
-                GrScalarToFloat(vm[GrMatrix::kMSkewX]),
-                GrScalarToFloat(vm[GrMatrix::kMScaleY]),
+                GrScalarToFloat(m[GrMatrix::kMSkewX]),
+                GrScalarToFloat(m[GrMatrix::kMScaleY]),
                 0,
-                GrScalarToFloat(vm[GrMatrix::kMPersp1]),
+                GrScalarToFloat(m[GrMatrix::kMPersp1]),
 
                 // col 2
                 0, 0, 0, 0,
 
                 // col3
-                GrScalarToFloat(vm[GrMatrix::kMTransX]),
-                GrScalarToFloat(vm[GrMatrix::kMTransY]),
-                0.5f,
-                GrScalarToFloat(vm[GrMatrix::kMPersp2])
+                GrScalarToFloat(m[GrMatrix::kMTransX]),
+                GrScalarToFloat(m[GrMatrix::kMTransY]),
+                0.0f,
+                GrScalarToFloat(m[GrMatrix::kMPersp2])
             };
-            GL_CALL(MatrixMode(GR_GL_MODELVIEW));
+            GL_CALL(MatrixMode(GR_GL_PROJECTION));
             GL_CALL(LoadMatrixf(mv));
             fHWPathMatrixState.fViewMatrix = vm;
-        }
-        if (fHWPathMatrixState.fRTSize != viewportSize) {
-            GrGLfloat p[] = {
-                // col 0
-                2.f / rt->width(), 0, 0, 0,
-
-                // col 1
-                0, -2.f / rt->height(), 0, 0,
-
-                // col 2
-                0, 0, 1.f, 0,
-
-                // col 3
-                -1.f, 1.f, 0, 1.f,
-            };
-            GL_CALL(MatrixMode(GR_GL_PROJECTION));
-            GL_CALL(LoadMatrixf(p));
             fHWPathMatrixState.fRTSize = viewportSize;
         }
     } else if (!fProgramData->fViewMatrix.cheapEqualTo(vm) ||
-        fProgramData->fViewportSize != viewportSize) {
-
+               fProgramData->fViewportSize != viewportSize) {
         GrMatrix m;
         m.setAll(
             GrIntToScalar(2) / viewportSize.fWidth, 0, -GR_Scalar1,