aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed <reed@chromium.org>2015-03-29 11:58:48 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-03-29 11:58:48 -0700
commit7da19014fda527a52381d85cc50b951031fa4754 (patch)
treedf709d983ce2d44a9c355157164b5d9d75e269ae
parenta8e2d5b558a9623d2755dfcc65cba871f010e047 (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.cpp25
-rw-r--r--include/core/SkMatrix.h14
-rw-r--r--src/core/SkMatrix.cpp186
-rw-r--r--tests/MatrixTest.cpp44
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) {