[gpu] Remove getMaxStretch for perspective, use mapRadius for perspective path subdiv tol, add test

Review URL: http://codereview.appspot.com/4975063/



git-svn-id: http://skia.googlecode.com/svn/trunk@2246 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrDefaultPathRenderer.cpp b/gpu/src/GrDefaultPathRenderer.cpp
index 3323c91..278c751 100644
--- a/gpu/src/GrDefaultPathRenderer.cpp
+++ b/gpu/src/GrDefaultPathRenderer.cpp
@@ -375,7 +375,7 @@
 
     GrMatrix viewM = fTarget->getViewMatrix();
     GrScalar tol = GR_Scalar1;
-    tol = GrPathUtils::scaleToleranceToSrc(tol, viewM);
+    tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, fPath->getBounds());
 
     // FIXME: It's really dumb that we recreate the verts for a new vertex
     // layout. We only do that because the GrDrawTarget API doesn't allow
diff --git a/gpu/src/GrPathUtils.cpp b/gpu/src/GrPathUtils.cpp
index b7dc4b6..0a7759d 100644
--- a/gpu/src/GrPathUtils.cpp
+++ b/gpu/src/GrPathUtils.cpp
@@ -12,16 +12,23 @@
 #include "GrPoint.h"
 
 GrScalar GrPathUtils::scaleToleranceToSrc(GrScalar devTol,
-                                          const GrMatrix& viewM) {
+                                          const GrMatrix& viewM,
+                                          const GrRect& pathBounds) {
     // In order to tesselate the path we get a bound on how much the matrix can
     // stretch when mapping to screen coordinates.
     GrScalar stretch = viewM.getMaxStretch();
     GrScalar srcTol = devTol;
 
     if (stretch < 0) {
-        // TODO: deal with perspective in some better way.
-        srcTol /= 5;
-        stretch = -stretch;
+        // take worst case mapRadius amoung four corners.
+        // (less than perfect)
+        for (int i = 0; i < 4; ++i) {
+            GrMatrix mat;
+            mat.setTranslate((i % 2) ? pathBounds.fLeft : pathBounds.fRight,
+                             (i < 2) ? pathBounds.fTop : pathBounds.fBottom);
+            mat.postConcat(viewM);
+            stretch = SkMaxScalar(stretch, mat.mapRadius(SK_Scalar1));
+        }
     }
     srcTol = GrScalarDiv(srcTol, stretch);
     return srcTol;
diff --git a/gpu/src/GrPathUtils.h b/gpu/src/GrPathUtils.h
index 8d77982..a5f80d9 100644
--- a/gpu/src/GrPathUtils.h
+++ b/gpu/src/GrPathUtils.h
@@ -20,7 +20,8 @@
  */
 namespace GrPathUtils {
     GrScalar scaleToleranceToSrc(GrScalar devTol,
-                                 const GrMatrix& viewM);
+                                 const GrMatrix& viewM,
+                                 const GrRect& pathBounds);
 
     /// Since we divide by tol if we're computing exact worst-case bounds,
     /// very small tolerances will be increased to gMinCurveTol.
diff --git a/gpu/src/GrTesselatedPathRenderer.cpp b/gpu/src/GrTesselatedPathRenderer.cpp
index dd281ed..a3da707 100644
--- a/gpu/src/GrTesselatedPathRenderer.cpp
+++ b/gpu/src/GrTesselatedPathRenderer.cpp
@@ -353,7 +353,7 @@
     GrMatrix viewM = fTarget->getViewMatrix();
 
     GrScalar tol = GR_Scalar1;
-    tol = GrPathUtils::scaleToleranceToSrc(tol, viewM);
+    tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, fPath->getBounds());
     GrScalar tolSqd = GrMul(tol, tol);
 
     int subpathCnt;