diff options
author | robertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-08-20 17:24:16 +0000 |
---|---|---|
committer | robertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-08-20 17:24:16 +0000 |
commit | 17bb458fe897411218d8c9781770948d4398b723 (patch) | |
tree | d2396f5677b678aaac5d344d68bd4916677f3e05 | |
parent | b00a85b7f30c9c3dc549524205631b9f2f429cf8 (diff) |
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
-rw-r--r-- | bench/PathBench.cpp | 55 | ||||
-rw-r--r-- | src/core/SkPath.cpp | 10 |
2 files changed, 65 insertions, 0 deletions
diff --git a/bench/PathBench.cpp b/bench/PathBench.cpp index a8b31e2777..61014e832e 100644 --- a/bench/PathBench.cpp +++ b/bench/PathBench.cpp @@ -617,6 +617,57 @@ private: 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 gRegAddMatrix(FactAddMatrix); 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 674ba980f6..8184345a5b 100644 --- a/src/core/SkPath.cpp +++ b/src/core/SkPath.cpp @@ -933,6 +933,16 @@ void SkPath::addCircle(SkScalar x, SkScalar y, SkScalar r, Direction dir) { 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); |