diff options
author | reed <reed@chromium.org> | 2015-03-29 11:58:48 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-03-29 11:58:48 -0700 |
commit | 7da19014fda527a52381d85cc50b951031fa4754 (patch) | |
tree | df709d983ce2d44a9c355157164b5d9d75e269ae | |
parent | a8e2d5b558a9623d2755dfcc65cba871f010e047 (diff) |
use Sk4f for matrix math
Need to land SK_SUPPORT_LEGACY_SCALAR_MAPPOINTS in chrome to suppress Affine
version which causes slight differences (which will need to be rebaselined)
BUG=skia:
Review URL: https://codereview.chromium.org/1045493002
-rw-r--r-- | bench/MatrixBench.cpp | 25 | ||||
-rw-r--r-- | include/core/SkMatrix.h | 14 | ||||
-rw-r--r-- | src/core/SkMatrix.cpp | 186 | ||||
-rw-r--r-- | tests/MatrixTest.cpp | 44 |
4 files changed, 74 insertions, 195 deletions
diff --git a/bench/MatrixBench.cpp b/bench/MatrixBench.cpp index 68195e70e4..e3e5c703e8 100644 --- a/bench/MatrixBench.cpp +++ b/bench/MatrixBench.cpp @@ -278,10 +278,9 @@ protected: N = 32 }; SkPoint fSrc[N], fDst[N]; - const bool fNewWay; public: - MapPointsMatrixBench(const char name[], const SkMatrix& m, bool newWay) - : MatrixBench(name), fM(m), fNewWay(newWay) + MapPointsMatrixBench(const char name[], const SkMatrix& m) + : MatrixBench(name), fM(m) { SkRandom rand; for (int i = 0; i < N; ++i) { @@ -290,21 +289,13 @@ public: } void performTest() override { - if (fNewWay) { - for (int i = 0; i < 1000000; ++i) { - fM.mapPts(fDst, fSrc, N); - } - } else { - for (int i = 0; i < 1000000; ++i) { - fM.mapPoints(fDst, fSrc, N); - } + for (int i = 0; i < 1000000; ++i) { + fM.mapPoints(fDst, fSrc, N); } } }; -DEF_BENCH( return new MapPointsMatrixBench("mappts_trans0", make_trans(), false); ) -DEF_BENCH( return new MapPointsMatrixBench("mappts_trans1", make_trans(), true); ) -DEF_BENCH( return new MapPointsMatrixBench("mappts_scale0", make_scale(), false); ) -DEF_BENCH( return new MapPointsMatrixBench("mappts_scale1", make_scale(), true); ) -DEF_BENCH( return new MapPointsMatrixBench("mappts_afine0", make_afine(), false); ) -DEF_BENCH( return new MapPointsMatrixBench("mappts_afine1", make_afine(), true); ) +DEF_BENCH( return new MapPointsMatrixBench("mappoints_identity", SkMatrix::I()); ) +DEF_BENCH( return new MapPointsMatrixBench("mappoints_trans", make_trans()); ) +DEF_BENCH( return new MapPointsMatrixBench("mappoints_scale", make_scale()); ) +DEF_BENCH( return new MapPointsMatrixBench("mappoints_affine", make_afine()); ) diff --git a/include/core/SkMatrix.h b/include/core/SkMatrix.h index 0408634ead..1c79d22121 100644 --- a/include/core/SkMatrix.h +++ b/include/core/SkMatrix.h @@ -413,7 +413,12 @@ public: @param count The number of points in src to read, and then transform into dst. */ - void mapPoints(SkPoint dst[], const SkPoint src[], int count) const; + void mapPoints(SkPoint dst[], const SkPoint src[], int count) const { + SkASSERT((dst && src && count > 0) || 0 == count); + // no partial overlap + SkASSERT(src == dst || &dst[count] <= &src[0] || &src[count] <= &dst[0]); + this->getMapPtsProc()(*this, dst, src, count); + } /** Apply this matrix to the array of points, overwriting it with the transformed values. @@ -426,10 +431,6 @@ public: this->mapPoints(pts, pts, count); } - void mapPts(SkPoint dst[], const SkPoint src[], int count) const { - gMapVPtsProcs[this->getType() & 0xF](*this, dst, src, count); - } - /** Like mapPoints but with custom byte stride between the points. Stride * should be a multiple of sizeof(SkScalar). */ @@ -801,12 +802,9 @@ private: int count); static void Persp_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int); - static void Trans_vpts(const SkMatrix&, SkPoint dst[], const SkPoint[], int); - static void Scale_vpts(const SkMatrix&, SkPoint dst[], const SkPoint[], int); static void Affine_vpts(const SkMatrix&, SkPoint dst[], const SkPoint[], int); static const MapPtsProc gMapPtsProcs[]; - static const MapPtsProc gMapVPtsProcs[]; friend class SkPerspIter; }; diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp index a43e00f3af..0f56b724f5 100644 --- a/src/core/SkMatrix.cpp +++ b/src/core/SkMatrix.cpp @@ -8,6 +8,7 @@ #include "SkMatrix.h" #include "SkFloatBits.h" #include "SkString.h" +#include "Sk4x.h" #include <stddef.h> @@ -867,61 +868,72 @@ bool SkMatrix::invertNonIdentity(SkMatrix* inv) const { /////////////////////////////////////////////////////////////////////////////// -void SkMatrix::Identity_pts(const SkMatrix& m, SkPoint dst[], - const SkPoint src[], int count) { +void SkMatrix::Identity_pts(const SkMatrix& m, SkPoint dst[], const SkPoint src[], int count) { SkASSERT(m.getType() == 0); - if (dst != src && count > 0) + if (dst != src && count > 0) { memcpy(dst, src, count * sizeof(SkPoint)); -} - -void SkMatrix::Trans_pts(const SkMatrix& m, SkPoint dst[], - const SkPoint src[], int count) { - SkASSERT(m.getType() == kTranslate_Mask); - - if (count > 0) { - SkScalar tx = m.fMat[kMTransX]; - SkScalar ty = m.fMat[kMTransY]; - do { - dst->fY = src->fY + ty; - dst->fX = src->fX + tx; - src += 1; - dst += 1; - } while (--count); } } -void SkMatrix::Scale_pts(const SkMatrix& m, SkPoint dst[], - const SkPoint src[], int count) { - SkASSERT(m.getType() == kScale_Mask); - +void SkMatrix::Trans_pts(const SkMatrix& m, SkPoint dst[], const SkPoint src[], int count) { + SkASSERT(m.getType() <= kTranslate_Mask); + if (count > 0) { - SkScalar mx = m.fMat[kMScaleX]; - SkScalar my = m.fMat[kMScaleY]; - do { - dst->fY = src->fY * my; - dst->fX = src->fX * mx; + SkScalar tx = m.getTranslateX(); + SkScalar ty = m.getTranslateY(); + if (count & 1) { + dst->fX = src->fX + tx; + dst->fY = src->fY + ty; src += 1; dst += 1; - } while (--count); + } + Sk4f trans4(tx, ty, tx, ty); + count >>= 1; + if (count & 1) { + (Sk4f::Load(&src->fX) + trans4).store(&dst->fX); + src += 2; + dst += 2; + } + count >>= 1; + for (int i = 0; i < count; ++i) { + (Sk4f::Load(&src[0].fX) + trans4).store(&dst[0].fX); + (Sk4f::Load(&src[2].fX) + trans4).store(&dst[2].fX); + src += 4; + dst += 4; + } } } -void SkMatrix::ScaleTrans_pts(const SkMatrix& m, SkPoint dst[], - const SkPoint src[], int count) { - SkASSERT(m.getType() == (kScale_Mask | kTranslate_Mask)); - +void SkMatrix::Scale_pts(const SkMatrix& m, SkPoint dst[], const SkPoint src[], int count) { + SkASSERT(m.getType() <= (kScale_Mask | kTranslate_Mask)); + if (count > 0) { - SkScalar mx = m.fMat[kMScaleX]; - SkScalar my = m.fMat[kMScaleY]; - SkScalar tx = m.fMat[kMTransX]; - SkScalar ty = m.fMat[kMTransY]; - do { - dst->fY = src->fY * my + ty; - dst->fX = src->fX * mx + tx; + SkScalar tx = m.getTranslateX(); + SkScalar ty = m.getTranslateY(); + SkScalar sx = m.getScaleX(); + SkScalar sy = m.getScaleY(); + if (count & 1) { + dst->fX = src->fX * sx + tx; + dst->fY = src->fY * sy + ty; src += 1; dst += 1; - } while (--count); + } + Sk4f trans4(tx, ty, tx, ty); + Sk4f scale4(sx, sy, sx, sy); + count >>= 1; + if (count & 1) { + (Sk4f::Load(&src->fX) * scale4 + trans4).store(&dst->fX); + src += 2; + dst += 2; + } + count >>= 1; + for (int i = 0; i < count; ++i) { + (Sk4f::Load(&src[0].fX) * scale4 + trans4).store(&dst[0].fX); + (Sk4f::Load(&src[2].fX) * scale4 + trans4).store(&dst[2].fX); + src += 4; + dst += 4; + } } } @@ -1000,89 +1012,6 @@ void SkMatrix::Persp_pts(const SkMatrix& m, SkPoint dst[], } } -const SkMatrix::MapPtsProc SkMatrix::gMapPtsProcs[] = { - SkMatrix::Identity_pts, SkMatrix::Trans_pts, - SkMatrix::Scale_pts, SkMatrix::ScaleTrans_pts, - SkMatrix::Rot_pts, SkMatrix::RotTrans_pts, - SkMatrix::Rot_pts, SkMatrix::RotTrans_pts, - // repeat the persp proc 8 times - SkMatrix::Persp_pts, SkMatrix::Persp_pts, - SkMatrix::Persp_pts, SkMatrix::Persp_pts, - SkMatrix::Persp_pts, SkMatrix::Persp_pts, - SkMatrix::Persp_pts, SkMatrix::Persp_pts -}; - -void SkMatrix::mapPoints(SkPoint dst[], const SkPoint src[], int count) const { - SkASSERT((dst && src && count > 0) || 0 == count); - // no partial overlap - SkASSERT(src == dst || &dst[count] <= &src[0] || &src[count] <= &dst[0]); - - this->getMapPtsProc()(*this, dst, src, count); -} - -#include "Sk4x.h" - -void SkMatrix::Trans_vpts(const SkMatrix& m, SkPoint dst[], const SkPoint src[], int count) { - SkASSERT(m.getType() <= kTranslate_Mask); - - if (count > 0) { - SkScalar tx = m.getTranslateX(); - SkScalar ty = m.getTranslateY(); - if (count & 1) { - dst->fX = src->fX + tx; - dst->fY = src->fY + ty; - src += 1; - dst += 1; - } - Sk4f trans4(tx, ty, tx, ty); - count >>= 1; - if (count & 1) { - (Sk4f::Load(&src->fX) + trans4).store(&dst->fX); - src += 2; - dst += 2; - } - count >>= 1; - for (int i = 0; i < count; ++i) { - (Sk4f::Load(&src[0].fX) + trans4).store(&dst[0].fX); - (Sk4f::Load(&src[2].fX) + trans4).store(&dst[2].fX); - src += 4; - dst += 4; - } - } -} - -void SkMatrix::Scale_vpts(const SkMatrix& m, SkPoint dst[], const SkPoint src[], int count) { - SkASSERT(m.getType() <= (kScale_Mask | kTranslate_Mask)); - - if (count > 0) { - SkScalar tx = m.getTranslateX(); - SkScalar ty = m.getTranslateY(); - SkScalar sx = m.getScaleX(); - SkScalar sy = m.getScaleY(); - if (count & 1) { - dst->fX = src->fX * sx + tx; - dst->fY = src->fY * sy + ty; - src += 1; - dst += 1; - } - Sk4f trans4(tx, ty, tx, ty); - Sk4f scale4(sx, sy, sx, sy); - count >>= 1; - if (count & 1) { - (Sk4f::Load(&src->fX) * scale4 + trans4).store(&dst->fX); - src += 2; - dst += 2; - } - count >>= 1; - for (int i = 0; i < count; ++i) { - (Sk4f::Load(&src[0].fX) * scale4 + trans4).store(&dst[0].fX); - (Sk4f::Load(&src[2].fX) * scale4 + trans4).store(&dst[2].fX); - src += 4; - dst += 4; - } - } -} - void SkMatrix::Affine_vpts(const SkMatrix& m, SkPoint dst[], const SkPoint src[], int count) { SkASSERT(m.getType() != kPerspective_Mask); @@ -1113,11 +1042,16 @@ void SkMatrix::Affine_vpts(const SkMatrix& m, SkPoint dst[], const SkPoint src[] } } -const SkMatrix::MapPtsProc SkMatrix::gMapVPtsProcs[] = { - SkMatrix::Identity_pts, SkMatrix::Trans_vpts, - SkMatrix::Scale_vpts, SkMatrix::Scale_vpts, +const SkMatrix::MapPtsProc SkMatrix::gMapPtsProcs[] = { + SkMatrix::Identity_pts, SkMatrix::Trans_pts, + SkMatrix::Scale_pts, SkMatrix::Scale_pts, +#ifdef SK_SUPPORT_LEGACY_SCALAR_MAPPOINTS + SkMatrix::Rot_pts, SkMatrix::RotTrans_pts, + SkMatrix::Rot_pts, SkMatrix::RotTrans_pts, +#else SkMatrix::Affine_vpts, SkMatrix::Affine_vpts, SkMatrix::Affine_vpts, SkMatrix::Affine_vpts, +#endif // repeat the persp proc 8 times SkMatrix::Persp_pts, SkMatrix::Persp_pts, SkMatrix::Persp_pts, SkMatrix::Persp_pts, diff --git a/tests/MatrixTest.cpp b/tests/MatrixTest.cpp index 35306b3275..95d33acabd 100644 --- a/tests/MatrixTest.cpp +++ b/tests/MatrixTest.cpp @@ -799,48 +799,6 @@ static void test_decompScale(skiatest::Reporter* reporter) { REPORTER_ASSERT(reporter, !check_decompScale(m)); } -static void test_mappts(skiatest::Reporter* reporter, const SkMatrix& m, const char type[], int n) { - const int MAX = 100; - SkPoint src[MAX]; - SkPoint dst0[MAX], dst1[MAX]; - SkASSERT(n <= MAX); - - SkRandom rand; - for (int i = 0; i < n; ++i) { - src[i].fX = rand.nextSScalar1() * 100; - src[i].fY = rand.nextSScalar1() * 100; - } - - m.mapPoints(dst0, src, n); - m.mapPts( dst1, src, n); - for (int i = 0; i < n; ++i) { - bool eq = SkScalarNearlyEqual(dst0[i].fX, dst1[i].fX) && - SkScalarNearlyEqual(dst0[i].fY, dst1[i].fY); - if (!eq) { - SkDebugf("%s [%d] points (%g %g) pts (%g %g)\n", type, i, dst0[i].fX, dst0[i].fY, dst1[i].fX, dst1[i].fY); - REPORTER_ASSERT(reporter, eq); - } - } -} - -static void test_mappts(skiatest::Reporter* reporter) { - const int counts[] = { 0, 1, 2, 3, 4, 100 }; - for (size_t i = 0; i < SK_ARRAY_COUNT(counts); ++i) { - const int n = counts[i]; - SkMatrix m; - m.reset(); - test_mappts(reporter, m, "ident", n); - m.setTranslate(2, 3); - test_mappts(reporter, m, "trans", n); - m.postScale(2, 0.5f); - test_mappts(reporter, m, "scale", n); - m.postRotate(35); - test_mappts(reporter, m, "affine", n); - m.setPerspX(0.1f); - test_mappts(reporter, m, "persp", n); - } -} - DEF_TEST(Matrix, reporter) { SkMatrix mat, inverse, iden1, iden2; @@ -961,8 +919,6 @@ DEF_TEST(Matrix, reporter) { test_set9(reporter); test_decompScale(reporter); - - test_mappts(reporter); } DEF_TEST(Matrix_Concat, r) { |