Add fast path in arcTo and addArc for 0==sweep && 0|360==sweepAngle
http://codereview.appspot.com/6463071/
git-svn-id: http://skia.googlecode.com/svn/trunk@5190 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/bench/PathBench.cpp b/bench/PathBench.cpp
index a8b31e2..61014e8 100644
--- a/bench/PathBench.cpp
+++ b/bench/PathBench.cpp
@@ -617,6 +617,57 @@
typedef RandomPathBench INHERITED;
};
+
+class CirclesBench : public SkBenchmark {
+protected:
+ SkString fName;
+
+ enum {
+ N = SkBENCHLOOP(100)
+ };
+public:
+ CirclesBench(void* param) : INHERITED(param) {
+ fName.printf("circles");
+ }
+
+protected:
+ virtual const char* onGetName() SK_OVERRIDE {
+ return fName.c_str();
+ }
+
+ virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+ SkPaint paint;
+
+ paint.setColor(SK_ColorBLACK);
+ paint.setAntiAlias(true);
+
+ SkRandom rand;
+
+ SkRect r;
+
+ for (int i = 0; i < 5000; ++i) {
+ SkScalar radius = rand.nextUScalar1() * 3;
+ r.fLeft = rand.nextUScalar1() * 300;
+ r.fTop = rand.nextUScalar1() * 300;
+ r.fRight = r.fLeft + 2 * radius;
+ r.fBottom = r.fTop + 2 * radius;
+
+ SkPath temp;
+
+ // mimic how Chrome does circles
+ temp.arcTo(r, 0, 0, false);
+ temp.addOval(r, SkPath::kCCW_Direction);
+ temp.arcTo(r, 360, 0, true);
+ temp.close();
+
+ canvas->drawPath(temp, paint);
+ }
+ }
+
+private:
+ typedef SkBenchmark INHERITED;
+};
+
static SkBenchmark* FactT00(void* p) { return new TrianglePathBench(p, FLAGS00); }
static SkBenchmark* FactT01(void* p) { return new TrianglePathBench(p, FLAGS01); }
static SkBenchmark* FactT10(void* p) { return new TrianglePathBench(p, FLAGS10); }
@@ -712,3 +763,7 @@
static BenchRegistry gRegPathTo(FactPathTo);
static BenchRegistry gRegReverseAdd(FactReverseAdd);
static BenchRegistry gRegReverseTo(FactReverseTo);
+
+static SkBenchmark* CirclesTest(void* p) { return new CirclesBench(p); }
+static BenchRegistry gRegCirclesTest(CirclesTest);
+
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 674ba98..8184345 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -933,6 +933,16 @@
static int build_arc_points(const SkRect& oval, SkScalar startAngle,
SkScalar sweepAngle,
SkPoint pts[kSkBuildQuadArcStorage]) {
+
+ if (0 == sweepAngle &&
+ (0 == startAngle || SkIntToScalar(360) == startAngle)) {
+ // Chrome uses this path to move into and out of ovals. If not
+ // treated as a special case the moves can distort the oval's
+ // bounding box (and break the circle special case).
+ pts[0].set(oval.fRight, oval.centerY());
+ return 1;
+ }
+
SkVector start, stop;
start.fY = SkScalarSinCos(SkDegreesToRadians(startAngle), &start.fX);