use new faster/vector impl for chopping conics

BUG=skia:

Review URL: https://codereview.chromium.org/1035943002
This commit is contained in:
reed 2015-03-26 09:10:22 -07:00 committed by Commit bot
parent 384181c810
commit 5501103881
4 changed files with 16 additions and 83 deletions

View File

@ -806,44 +806,16 @@ private:
#include "SkGeometry.h"
class ConicBench_Chop5 : public Benchmark {
SkConic fRQ;
public:
ConicBench_Chop5() {
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:
const char* onGetName() override {
return "ratquad-chop-0.5";
}
void onDraw(const int loops, SkCanvas*) override {
SkConic dst[2];
for (int i = 0; i < loops; ++i) {
fRQ.chopAt(0.5f, dst);
}
}
typedef Benchmark INHERITED;
};
class ConicBench_ChopHalf : public Benchmark {
class ConicBench_Chop : public Benchmark {
protected:
SkConic fRQ, fDst[2];
SkString fName;
const bool fUseV2;
public:
ConicBench_ChopHalf(bool useV2) : fUseV2(useV2) {
ConicBench_Chop() : fName("conic-chop") {
fRQ.fPts[0].set(0, 0);
fRQ.fPts[1].set(100, 0);
fRQ.fPts[2].set(100, 100);
fRQ.fW = SkScalarCos(SK_ScalarPI/4);
fName.printf("conic-chop-half%d", useV2);
}
bool isSuitableFor(Backend backend) override {
@ -854,25 +826,19 @@ private:
const char* onGetName() override { return fName.c_str(); }
void onDraw(const int loops, SkCanvas*) override {
if (fUseV2) {
for (int i = 0; i < loops; ++i) {
fRQ.chop2(fDst);
}
} else {
for (int i = 0; i < loops; ++i) {
fRQ.chop(fDst);
}
for (int i = 0; i < loops; ++i) {
fRQ.chop(fDst);
}
}
typedef Benchmark INHERITED;
};
DEF_BENCH( return new ConicBench_ChopHalf(false); )
DEF_BENCH( return new ConicBench_ChopHalf(true); )
DEF_BENCH( return new ConicBench_Chop; )
class ConicBench_EvalPos : public ConicBench_ChopHalf {
class ConicBench_EvalPos : public ConicBench_Chop {
const bool fUseV2;
public:
ConicBench_EvalPos(bool useV2) : ConicBench_ChopHalf(useV2) {
ConicBench_EvalPos(bool useV2) : fUseV2(useV2) {
fName.printf("conic-eval-pos%d", useV2);
}
void onDraw(const int loops, SkCanvas*) override {
@ -894,9 +860,10 @@ public:
DEF_BENCH( return new ConicBench_EvalPos(false); )
DEF_BENCH( return new ConicBench_EvalPos(true); )
class ConicBench_EvalTan : public ConicBench_ChopHalf {
class ConicBench_EvalTan : public ConicBench_Chop {
const bool fUseV2;
public:
ConicBench_EvalTan(bool useV2) : ConicBench_ChopHalf(useV2) {
ConicBench_EvalTan(bool useV2) : fUseV2(useV2) {
fName.printf("conic-eval-tan%d", useV2);
}
void onDraw(const int loops, SkCanvas*) override {

View File

@ -1285,38 +1285,21 @@ static SkScalar subdivide_w_value(SkScalar w) {
return SkScalarSqrt(SK_ScalarHalf + w * SK_ScalarHalf);
}
void SkConic::chop(SkConic 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 = subdivide_w_value(fW);
static Sk2s twice(const Sk2s& value) {
return value + value;
}
void SkConic::chop2(SkConic * SK_RESTRICT dst) const {
Sk2s scale = Sk2s(SK_Scalar1 + fW).invert(); // approxInvert is wicked faster!!!
void SkConic::chop(SkConic * SK_RESTRICT dst) const {
Sk2s scale = Sk2s(SkScalarInvert(SK_Scalar1 + fW));
SkScalar newW = subdivide_w_value(fW);
Sk2s p0 = from_point(fPts[0]);
Sk2s p1 = from_point(fPts[1]);
Sk2s p2 = from_point(fPts[2]);
Sk2s ww(fW);
Sk2s half(0.5f);
Sk2s wp1 = ww * p1;
Sk2s m = ((p0 + wp1 + wp1 + p2) * half) * scale;
Sk2s m = (p0 + twice(wp1) + p2) * scale * Sk2s(0.5f);
dst[0].fPts[0] = fPts[0];
dst[0].fPts[1] = to_point((p0 + wp1) * scale);

View File

@ -221,7 +221,6 @@ struct SkConic {
SkPoint evalAt(SkScalar t) const;
SkVector evalTangentAt(SkScalar t) const;
void chop2(SkConic dst[2]) const;
void computeAsQuadError(SkVector* err) const;
bool asQuadTol(SkScalar tol) const;

View File

@ -83,21 +83,6 @@ static void test_conic_eval_tan(skiatest::Reporter* reporter, const SkConic& con
check_pairs(reporter, 0, t, "conic-tan", v0.fX, v0.fY, v1.fX, v1.fY);
}
static void test_conic_chop_half(skiatest::Reporter* reporter, const SkConic& conic) {
SkConic dst0[2], dst1[2];
conic.chop(dst0);
conic.chop2(dst1);
for (int i = 0; i < 2; ++i) {
REPORTER_ASSERT(reporter, dst0[i].fW == dst1[i].fW);
for (int j = 0; j < 3; ++j) {
check_pairs(reporter, j, 0.5f, "conic-chop",
dst0[i].fPts[j].fX, dst0[i].fPts[j].fY,
dst0[i].fPts[j].fX, dst1[i].fPts[j].fY);
}
}
}
static void test_conic(skiatest::Reporter* reporter) {
SkRandom rand;
for (int i = 0; i < 1000; ++i) {
@ -108,7 +93,6 @@ static void test_conic(skiatest::Reporter* reporter) {
for (int k = 0; k < 10; ++k) {
SkScalar w = rand.nextUScalar1() * 2;
SkConic conic(pts, w);
test_conic_chop_half(reporter, conic);
const SkScalar dt = SK_Scalar1 / 128;
SkScalar t = dt;