Add special handling of rectori case for gpu

https://codereview.chromium.org/15080010/



git-svn-id: http://skia.googlecode.com/svn/trunk@9175 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp
index c1870dd..bef5ddb 100644
--- a/src/gpu/GrAARectRenderer.cpp
+++ b/src/gpu/GrAARectRenderer.cpp
@@ -635,9 +635,16 @@
                                     const GrRect& rect,
                                     const SkMatrix& combinedMatrix,
                                     const GrRect& devRect,
-                                    const GrVec& devStrokeSize,
+                                    SkScalar width,
                                     bool useVertexCoverage) {
-    GrDrawState* drawState = target->drawState();
+    GrVec devStrokeSize;
+    if (width > 0) {
+        devStrokeSize.set(width, width);
+        combinedMatrix.mapVectors(&devStrokeSize, 1);
+        devStrokeSize.setAbs(devStrokeSize);
+    } else {
+        devStrokeSize.set(SK_Scalar1, SK_Scalar1);
+    }
 
     const SkScalar dx = devStrokeSize.fX;
     const SkScalar dy = devStrokeSize.fY;
@@ -659,13 +666,28 @@
         spare = GrMin(w, h);
     }
 
+    GrRect devOutside(devRect);
+    devOutside.outset(rx, ry);
+
     if (spare <= 0) {
-        GrRect r(devRect);
-        r.outset(rx, ry);
-        this->fillAARect(gpu, target, r, SkMatrix::I(), r, useVertexCoverage);
+        this->fillAARect(gpu, target, devOutside, SkMatrix::I(), 
+                         devOutside, useVertexCoverage);
         return;
     }
 
+    SkRect devInside(devRect);
+    devInside.inset(rx, ry);
+
+    this->geometryStrokeAARect(gpu, target, devOutside, devInside, useVertexCoverage);
+}
+
+void GrAARectRenderer::geometryStrokeAARect(GrGpu* gpu,
+                                            GrDrawTarget* target,
+                                            const SkRect& devOutside,
+                                            const SkRect& devInside,
+                                            bool useVertexCoverage) {
+    GrDrawState* drawState = target->drawState();
+
     set_aa_rect_vertex_attributes(drawState, useVertexCoverage);
 
     GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0);
@@ -691,14 +713,12 @@
     GrPoint* fan2Pos = reinterpret_cast<GrPoint*>(verts + 8 * vsize);
     GrPoint* fan3Pos = reinterpret_cast<GrPoint*>(verts + 12 * vsize);
 
-    set_inset_fan(fan0Pos, vsize, devRect,
-                  -rx - SK_ScalarHalf, -ry - SK_ScalarHalf);
-    set_inset_fan(fan1Pos, vsize, devRect,
-                  -rx + SK_ScalarHalf, -ry + SK_ScalarHalf);
-    set_inset_fan(fan2Pos, vsize, devRect,
-                  rx - SK_ScalarHalf,  ry - SK_ScalarHalf);
-    set_inset_fan(fan3Pos, vsize, devRect,
-                  rx + SK_ScalarHalf,  ry + SK_ScalarHalf);
+    // outermost
+    set_inset_fan(fan0Pos, vsize, devOutside, -SK_ScalarHalf, -SK_ScalarHalf);
+    set_inset_fan(fan1Pos, vsize, devOutside,  SK_ScalarHalf,  SK_ScalarHalf);
+    set_inset_fan(fan2Pos, vsize, devInside,  -SK_ScalarHalf, -SK_ScalarHalf);
+    // innermost
+    set_inset_fan(fan3Pos, vsize, devInside,   SK_ScalarHalf,  SK_ScalarHalf);
 
     // The outermost rect has 0 coverage
     verts += sizeof(GrPoint);
@@ -718,7 +738,7 @@
         *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor;
     }
 
-    // The innermost rect has full coverage
+    // The innermost rect has 0 coverage
     verts += 8 * vsize;
     for (int i = 0; i < 4; ++i) {
         *reinterpret_cast<GrColor*>(verts + i * vsize) = 0;
@@ -728,3 +748,24 @@
     target->drawIndexed(kTriangles_GrPrimitiveType,
                         0, 0, 16, aaStrokeRectIndexCount());
 }
+
+void GrAARectRenderer::fillAANestedRects(GrGpu* gpu,
+                                         GrDrawTarget* target,
+                                         const SkRect rects[2],
+                                         const SkMatrix& combinedMatrix,
+                                         bool useVertexCoverage) {
+    SkASSERT(combinedMatrix.rectStaysRect());
+    SkASSERT(!rects[1].isEmpty());
+
+    SkRect devOutside, devInside;
+    combinedMatrix.mapRect(&devOutside, rects[0]);
+    // can't call mapRect for devInside since it calls sort
+    combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2);
+
+    if (devInside.isEmpty()) {
+        this->fillAARect(gpu, target, devOutside, SkMatrix::I(), devOutside, useVertexCoverage);
+        return;
+    }
+
+    this->geometryStrokeAARect(gpu, target, devOutside, devInside, useVertexCoverage);
+}