From 05a718c9d2302b08f859adac5854b2df6ff84e43 Mon Sep 17 00:00:00 2001 From: "bsalomon@google.com" Date: Fri, 29 Jun 2012 14:01:53 +0000 Subject: [PATCH] Fix some NV path rendering issues with perspective and inverse paths 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 | 8 +++-- src/gpu/gl/GrGpuGL.cpp | 5 +++ src/gpu/gl/GrGpuGL_program.cpp | 56 ++++++++++++------------------- 3 files changed, 33 insertions(+), 36 deletions(-) diff --git a/src/gpu/GrStencilAndCoverPathRenderer.cpp b/src/gpu/GrStencilAndCoverPathRenderer.cpp index 40d998b..81dc1db 100644 --- a/src/gpu/GrStencilAndCoverPathRenderer.cpp +++ b/src/gpu/GrStencilAndCoverPathRenderer.cpp @@ -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)) { diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index 48ccd5d..e49c664 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -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()) { diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp index e33f469..d506c6c 100644 --- a/src/gpu/gl/GrGpuGL_program.cpp +++ b/src/gpu/gl/GrGpuGL_program.cpp @@ -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, -- 2.7.4