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
This commit is contained in:
bsalomon@google.com 2012-06-29 14:01:53 +00:00
parent e9c0469a49
commit 05a718c9d2
3 changed files with 34 additions and 37 deletions

View 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)) {

View 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()) {

View 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])
};
GL_CALL(MatrixMode(GR_GL_MODELVIEW));
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,
GrScalarToFloat(m[GrMatrix::kMTransX]),
GrScalarToFloat(m[GrMatrix::kMTransY]),
0.0f,
GrScalarToFloat(m[GrMatrix::kMPersp2])
};
GL_CALL(MatrixMode(GR_GL_PROJECTION));
GL_CALL(LoadMatrixf(p));
GL_CALL(LoadMatrixf(mv));
fHWPathMatrixState.fViewMatrix = vm;
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,