Disable GPU acceleration for narrow ovals.
authorjvanverth@google.com <jvanverth@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 16 Apr 2013 12:30:35 +0000 (12:30 +0000)
committerjvanverth@google.com <jvanverth@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 16 Apr 2013 12:30:35 +0000 (12:30 +0000)
GPU anti-aliasing is currently not correct for ellipses where the ratio of long
axis length to short axis length is greater than 2 (see
https://code.google.com/p/skia/issues/detail?id=1249). This disables the GPU
path for those cases.

Review URL: https://codereview.chromium.org/13925015/

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

include/gpu/GrOvalRenderer.h
src/gpu/GrOvalRenderer.cpp

index 88dd0a4..7e46dac 100644 (file)
@@ -33,7 +33,7 @@ public:
     bool drawOval(GrDrawTarget* target, const GrContext* context, const GrPaint& paint,
                   const GrRect& oval, const SkStrokeRec& stroke);
 private:
-    void drawEllipse(GrDrawTarget* target, const GrPaint& paint,
+    bool drawEllipse(GrDrawTarget* target, const GrPaint& paint,
                      const GrRect& ellipse,
                      const SkStrokeRec& stroke);
     void drawCircle(GrDrawTarget* target, const GrPaint& paint,
index 71052bc..ff468fd 100644 (file)
@@ -297,7 +297,7 @@ bool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, co
 
     // and axis-aligned ellipses only
     } else if (vm.rectStaysRect()) {
-        drawEllipse(target, paint, oval, stroke);
+        return drawEllipse(target, paint, oval, stroke);
 
     } else {
         return false;
@@ -406,7 +406,7 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target,
     target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4, &bounds);
 }
 
-void GrOvalRenderer::drawEllipse(GrDrawTarget* target,
+bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
                                  const GrPaint& paint,
                                  const GrRect& ellipse,
                                  const SkStrokeRec& stroke)
@@ -425,10 +425,15 @@ void GrOvalRenderer::drawEllipse(GrDrawTarget* target,
     vm.mapPoints(&center, 1);
     SkRect xformedRect;
     vm.mapRect(&xformedRect, ellipse);
+    SkScalar xRadius = SkScalarHalf(xformedRect.width());
+    SkScalar yRadius = SkScalarHalf(xformedRect.height());
+    if (SkScalarDiv(xRadius, yRadius) > 2 || SkScalarDiv(yRadius, xRadius) > 2) {
+        return false;
+    }
 
     GrDrawState::AutoDeviceCoordDraw adcd(drawState);
     if (!adcd.succeeded()) {
-        return;
+        return false;
     }
 
     // position + edge
@@ -443,7 +448,7 @@ void GrOvalRenderer::drawEllipse(GrDrawTarget* target,
     GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
     if (!geo.succeeded()) {
         GrPrintf("Failed to get space for vertices!\n");
-        return;
+        return false;
     }
 
     EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices());
@@ -463,8 +468,6 @@ void GrOvalRenderer::drawEllipse(GrDrawTarget* target,
     drawState->setEffect(kEdgeEffectStage, effect,
                          kEllipseCenterAttrIndex, kEllipseEdgeAttrIndex)->unref();
 
-    SkScalar xRadius = SkScalarHalf(xformedRect.width());
-    SkScalar yRadius = SkScalarHalf(xformedRect.height());
     SkScalar innerXRadius = 0.0f;
     SkScalar innerRatio = 1.0f;
 
@@ -538,4 +541,6 @@ void GrOvalRenderer::drawEllipse(GrDrawTarget* target,
     verts[3].fInnerOffset = SkPoint::Make(xRadius, innerRatio*yRadius);
 
     target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4, &bounds);
+
+    return true;
 }