diff --git a/bench/PathBench.cpp b/bench/PathBench.cpp index 658ee96f63..016bf4e0c5 100644 --- a/bench/PathBench.cpp +++ b/bench/PathBench.cpp @@ -864,6 +864,68 @@ private: typedef SkBenchmark INHERITED; }; +/////////////////////////////////////////////////////////////////////////////// + +#include "SkGeometry.h" + +class RationalQuadBench_Chop5 : public SkBenchmark { + enum { + N = 100000 + }; + SkRationalQuad fRQ; +public: + RationalQuadBench_Chop5(void* param) : INHERITED(param) { + fRQ.fPts[0].set(0, 0); + fRQ.fPts[1].set(100, 0); + fRQ.fPts[2].set(100, 100); + fRQ.fW = SkScalarCos(SK_ScalarPI/4); + } + +private: + virtual const char* onGetName() SK_OVERRIDE { + return "ratquad-chop-0.5"; + } + + virtual void onDraw(SkCanvas*) SK_OVERRIDE { + SkRationalQuad dst[2]; + for (int i = 0; i < N; ++i) { + fRQ.chopAt(0.5f, dst); + } + } + + typedef SkBenchmark INHERITED; +}; + +class RationalQuadBench_ChopHalf : public SkBenchmark { + enum { + N = 100000 + }; + SkRationalQuad fRQ; +public: + RationalQuadBench_ChopHalf(void* param) : INHERITED(param) { + fRQ.fPts[0].set(0, 0); + fRQ.fPts[1].set(100, 0); + fRQ.fPts[2].set(100, 100); + fRQ.fW = SkScalarCos(SK_ScalarPI/4); + } + +private: + virtual const char* onGetName() SK_OVERRIDE { + return "ratquad-chop-half"; + } + + virtual void onDraw(SkCanvas*) SK_OVERRIDE { + SkRationalQuad dst[2]; + for (int i = 0; i < N; ++i) { + fRQ.chop(dst); + } + } + + typedef SkBenchmark INHERITED; +}; + +/////////////////////////////////////////////////////////////////////////////// + const SkRect ConservativelyContainsBench::kBounds = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(100)); const SkSize ConservativelyContainsBench::kQueryMin = SkSize::Make(SkIntToScalar(1), SkIntToScalar(1)); const SkSize ConservativelyContainsBench::kQueryMax = SkSize::Make(SkIntToScalar(40), SkIntToScalar(40)); @@ -918,3 +980,6 @@ DEF_BENCH( return new ArbRoundRectBench(p, true); ) DEF_BENCH( return new ConservativelyContainsBench(p, ConservativelyContainsBench::kRect_Type); ) DEF_BENCH( return new ConservativelyContainsBench(p, ConservativelyContainsBench::kRoundRect_Type); ) DEF_BENCH( return new ConservativelyContainsBench(p, ConservativelyContainsBench::kOval_Type); ) + +DEF_BENCH( return new RationalQuadBench_Chop5(p) ) +DEF_BENCH( return new RationalQuadBench_ChopHalf(p) ) diff --git a/include/core/SkGeometry.h b/include/core/SkGeometry.h index 0d1081fb2d..8bdbbe09e0 100644 --- a/include/core/SkGeometry.h +++ b/include/core/SkGeometry.h @@ -218,6 +218,7 @@ struct SkRationalQuad { void evalAt(SkScalar t, SkPoint* pt) const; void chopAt(SkScalar t, SkRationalQuad dst[2]) const; + void chop(SkRationalQuad dst[2]) const; }; #endif diff --git a/src/core/SkGeometry.cpp b/src/core/SkGeometry.cpp index 511c34e1aa..a440d039de 100644 --- a/src/core/SkGeometry.cpp +++ b/src/core/SkGeometry.cpp @@ -1464,3 +1464,24 @@ void SkRationalQuad::chopAt(SkScalar t, SkRationalQuad dst[2]) const { dst[0].fW = tmp2[0].fZ / root; dst[1].fW = tmp2[2].fZ / root; } + +void SkRationalQuad::chop(SkRationalQuad dst[2]) const { + SkScalar scale = SkScalarInvert(SK_Scalar1 + fW); + SkScalar p1x = fW * fPts[1].fX; + SkScalar p1y = fW * fPts[1].fY; + SkScalar mx = (fPts[0].fX + 2 * p1x + fPts[2].fX) * scale * SK_ScalarHalf; + SkScalar my = (fPts[0].fY + 2 * p1y + fPts[2].fY) * scale * SK_ScalarHalf; + + dst[0].fPts[0] = fPts[0]; + dst[0].fPts[1].set((fPts[0].fX + p1x) * scale, + (fPts[0].fY + p1y) * scale); + dst[0].fPts[2].set(mx, my); + + dst[1].fPts[0].set(mx, my); + dst[1].fPts[1].set((p1x + fPts[2].fX) * scale, + (p1y + fPts[2].fY) * scale); + dst[1].fPts[2] = fPts[2]; + + dst[0].fW = dst[1].fW = SkScalarSqrt((1 + fW) * SK_ScalarHalf); +} +