Add geometry-based rotated AA rect drawing path
authorrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 2 May 2013 17:13:13 +0000 (17:13 +0000)
committerrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 2 May 2013 17:13:13 +0000 (17:13 +0000)
https://codereview.chromium.org/14854005/

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

include/gpu/GrAARectRenderer.h
src/gpu/GrAARectRenderer.cpp
src/gpu/GrContext.cpp
src/gpu/SkGpuDevice.cpp

index b544294..fe9e612 100644 (file)
@@ -54,6 +54,7 @@ public:
         }
 #else
         this->geometryFillAARect(gpu, target,
+                                 rect, combinedMatrix,
                                  devRect, useVertexCoverage);
 #endif
     }
@@ -77,6 +78,8 @@ private:
     // since we now have a coverage vertex attribute
     void geometryFillAARect(GrGpu* gpu,
                             GrDrawTarget* target,
+                            const GrRect& rect,
+                            const SkMatrix& combinedMatrix,
                             const GrRect& devRect,
                             bool useVertexCoverage);
 
index 5acb406..57766d9 100644 (file)
@@ -361,6 +361,8 @@ GrIndexBuffer* GrAARectRenderer::aaStrokeRectIndexBuffer(GrGpu* gpu) {
 
 void GrAARectRenderer::geometryFillAARect(GrGpu* gpu,
                                           GrDrawTarget* target,
+                                          const GrRect& rect,
+                                          const SkMatrix& combinedMatrix,
                                           const GrRect& devRect,
                                           bool useVertexCoverage) {
     GrDrawState* drawState = target->drawState();
@@ -386,8 +388,42 @@ void GrAARectRenderer::geometryFillAARect(GrGpu* gpu,
     GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts);
     GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize);
 
-    set_inset_fan(fan0Pos, vsize, devRect, -SK_ScalarHalf, -SK_ScalarHalf);
-    set_inset_fan(fan1Pos, vsize, devRect,  SK_ScalarHalf,  SK_ScalarHalf);
+    if (combinedMatrix.rectStaysRect()) {
+        set_inset_fan(fan0Pos, vsize, devRect, -SK_ScalarHalf, -SK_ScalarHalf);
+        set_inset_fan(fan1Pos, vsize, devRect,  SK_ScalarHalf,  SK_ScalarHalf);
+    } else {
+        // compute transformed (1, 0) and (0, 1) vectors
+        SkVector vec[2] = {
+          { combinedMatrix[SkMatrix::kMScaleX], combinedMatrix[SkMatrix::kMSkewY] },
+          { combinedMatrix[SkMatrix::kMSkewX],  combinedMatrix[SkMatrix::kMScaleY] }
+        };
+
+        vec[0].normalize();
+        vec[0].scale(SK_ScalarHalf);
+        vec[1].normalize();
+        vec[1].scale(SK_ScalarHalf);
+
+        fan0Pos->setRectFan(rect.fLeft, rect.fTop,
+                            rect.fRight, rect.fBottom, vsize);
+        combinedMatrix.mapPointsWithStride(fan0Pos, vsize, 4);
+
+        // TL
+        *((SkPoint*)((intptr_t)fan1Pos + 0 * vsize)) = 
+            *((SkPoint*)((intptr_t)fan0Pos + 0 * vsize)) + vec[0] + vec[1];
+        *((SkPoint*)((intptr_t)fan0Pos + 0 * vsize)) -= vec[0] + vec[1];
+        // BL
+        *((SkPoint*)((intptr_t)fan1Pos + 1 * vsize)) = 
+            *((SkPoint*)((intptr_t)fan0Pos + 1 * vsize)) + vec[0] - vec[1];
+        *((SkPoint*)((intptr_t)fan0Pos + 1 * vsize)) -= vec[0] - vec[1];
+        // BR
+        *((SkPoint*)((intptr_t)fan1Pos + 2 * vsize)) = 
+            *((SkPoint*)((intptr_t)fan0Pos + 2 * vsize)) - vec[0] - vec[1];
+        *((SkPoint*)((intptr_t)fan0Pos + 2 * vsize)) += vec[0] + vec[1];
+        // TR
+        *((SkPoint*)((intptr_t)fan1Pos + 3 * vsize)) = 
+            *((SkPoint*)((intptr_t)fan0Pos + 3 * vsize)) - vec[0] + vec[1];
+        *((SkPoint*)((intptr_t)fan0Pos + 3 * vsize)) += vec[0] - vec[1];
+    }
 
     verts += sizeof(GrPoint);
     for (int i = 0; i < 4; ++i) {
@@ -395,7 +431,7 @@ void GrAARectRenderer::geometryFillAARect(GrGpu* gpu,
     }
 
     GrColor innerColor;
-    if (useVertexCoverage) {
+    if (useVertexCoverage) { 
         innerColor = 0xffffffff;
     } else {
         innerColor = target->getDrawState().getColor();
index d23dd54..320f8f6 100644 (file)
@@ -723,7 +723,7 @@ static bool apply_aa_to_rect(GrDrawTarget* target,
         return false;
     }
 
-#ifdef SHADER_AA_FILL_RECT
+#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
     if (strokeWidth >= 0) {
 #endif
         if (!drawState.getViewMatrix().preservesAxisAlignment()) {
@@ -733,7 +733,7 @@ static bool apply_aa_to_rect(GrDrawTarget* target,
         if (NULL != matrix && !matrix->preservesAxisAlignment()) {
             return false;
         }
-#ifdef SHADER_AA_FILL_RECT
+#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
     } else {
         if (!drawState.getViewMatrix().preservesAxisAlignment() &&
             !drawState.getViewMatrix().preservesRightAngles()) {
@@ -751,11 +751,11 @@ static bool apply_aa_to_rect(GrDrawTarget* target,
         combinedMatrix->preConcat(*matrix);
 
 #if GR_DEBUG
-#ifdef SHADER_AA_FILL_RECT
+#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
         if (strokeWidth >= 0) {
 #endif
             GrAssert(combinedMatrix->preservesAxisAlignment());
-#ifdef SHADER_AA_FILL_RECT
+#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
         } else {
             GrAssert(combinedMatrix->preservesRightAngles());
         }
@@ -765,7 +765,11 @@ static bool apply_aa_to_rect(GrDrawTarget* target,
 
     combinedMatrix->mapRect(devRect, rect);
 
-    if (strokeWidth < 0) {
+    if (strokeWidth < 0 
+#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
+        && drawState.getViewMatrix().preservesAxisAlignment()
+#endif
+        ) {
         return !isIRect(*devRect);
     } else {
         return true;
index a790cf2..837ff8c 100644 (file)
@@ -671,11 +671,11 @@ void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect,
         usePath = true;
     }
     if (!usePath && paint.isAntiAlias() && !fContext->getMatrix().rectStaysRect()) {
-#ifdef SHADER_AA_FILL_RECT
+#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
         if (doStroke) {
 #endif
             usePath = true;
-#ifdef SHADER_AA_FILL_RECT
+#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
         } else {
             usePath = !fContext->getMatrix().preservesRightAngles();
         }