aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar vollick@chromium.org <vollick@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-11-19 21:02:06 +0000
committerGravatar vollick@chromium.org <vollick@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-11-19 21:02:06 +0000
commitf11cf9ff885c81e29f55283174ca34ce2fc5fd23 (patch)
treeabc3cbbe3f4ed4e97b40e0fb2836d92c229b5345
parent8a1cdaece7e1d009befb84f21bb82370025bf4d6 (diff)
Add SkMatrix44::setColMajord, etc.
We have accessors for efficiently getting the matirx data, and it would be nice if we had similar methods for setting the matrix entries. Review URL: https://codereview.appspot.com/6851063 git-svn-id: http://skia.googlecode.com/svn/trunk@6494 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--include/utils/SkMatrix44.h15
-rw-r--r--src/utils/SkMatrix44.cpp46
-rw-r--r--tests/Matrix44Test.cpp107
3 files changed, 126 insertions, 42 deletions
diff --git a/include/utils/SkMatrix44.h b/include/utils/SkMatrix44.h
index a046a079df..e1de7c72a2 100644
--- a/include/utils/SkMatrix44.h
+++ b/include/utils/SkMatrix44.h
@@ -126,11 +126,26 @@ public:
this->set(row, col, SkDoubleToMScalar(value));
}
+ /** These methods allow one to efficiently read matrix entries into an
+ * array. The given array must have room for exactly 16 entries. Whenever
+ * possible, they will try to use memcpy rather than an entry-by-entry
+ * copy.
+ */
void asColMajorf(float[]) const;
void asColMajord(double[]) const;
void asRowMajorf(float[]) const;
void asRowMajord(double[]) const;
+ /** These methods allow one to efficiently set all matrix entries from an
+ * array. The given array must have room for exactly 16 entries. Whenever
+ * possible, they will try to use memcpy rather than an entry-by-entry
+ * copy.
+ */
+ void setColMajorf(const float[]);
+ void setColMajord(const double[]);
+ void setRowMajorf(const float[]);
+ void setRowMajord(const double[]);
+
bool isIdentity() const;
void setIdentity();
void reset() { this->setIdentity();}
diff --git a/src/utils/SkMatrix44.cpp b/src/utils/SkMatrix44.cpp
index 0e7ad167c2..42c38f7b4f 100644
--- a/src/utils/SkMatrix44.cpp
+++ b/src/utils/SkMatrix44.cpp
@@ -82,6 +82,52 @@ void SkMatrix44::asRowMajord(double dst[]) const {
}
}
+void SkMatrix44::setColMajorf(const float src[]) {
+ SkMScalar* dst = &fMat[0][0];
+#ifdef SK_MSCALAR_IS_DOUBLE
+ for (int i = 0; i < 16; ++i) {
+ dst[i] = SkMScalarToFloat(src[i]);
+ }
+#elif defined SK_MSCALAR_IS_FLOAT
+ memcpy(dst, src, 16 * sizeof(float));
+#endif
+}
+
+void SkMatrix44::setColMajord(const double src[]) {
+ SkMScalar* dst = &fMat[0][0];
+#ifdef SK_MSCALAR_IS_DOUBLE
+ memcpy(dst, src, 16 * sizeof(double));
+#elif defined SK_MSCALAR_IS_FLOAT
+ for (int i = 0; i < 16; ++i) {
+ dst[i] = SkMScalarToDouble(src[i]);
+ }
+#endif
+}
+
+void SkMatrix44::setRowMajorf(const float src[]) {
+ SkMScalar* dst = &fMat[0][0];
+ for (int i = 0; i < 4; ++i) {
+ dst[0] = SkMScalarToFloat(src[0]);
+ dst[4] = SkMScalarToFloat(src[1]);
+ dst[8] = SkMScalarToFloat(src[2]);
+ dst[12] = SkMScalarToFloat(src[3]);
+ src += 4;
+ dst += 1;
+ }
+}
+
+void SkMatrix44::setRowMajord(const double src[]) {
+ SkMScalar* dst = &fMat[0][0];
+ for (int i = 0; i < 4; ++i) {
+ dst[0] = SkMScalarToDouble(src[0]);
+ dst[4] = SkMScalarToDouble(src[1]);
+ dst[8] = SkMScalarToDouble(src[2]);
+ dst[12] = SkMScalarToDouble(src[3]);
+ src += 4;
+ dst += 1;
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////
bool SkMatrix44::isIdentity() const {
diff --git a/tests/Matrix44Test.cpp b/tests/Matrix44Test.cpp
index 782b51e0bf..ea6a56f436 100644
--- a/tests/Matrix44Test.cpp
+++ b/tests/Matrix44Test.cpp
@@ -123,57 +123,80 @@ static void test_concat(skiatest::Reporter* reporter) {
}
static void test_determinant(skiatest::Reporter* reporter) {
- SkMatrix44 a;
- REPORTER_ASSERT(reporter, nearly_equal_double(1, a.determinant()));
- a.set(1, 1, SkFloatToMScalar(2));
- REPORTER_ASSERT(reporter, nearly_equal_double(2, a.determinant()));
- SkMatrix44 b;
- REPORTER_ASSERT(reporter, a.invert(&b));
- REPORTER_ASSERT(reporter, nearly_equal_double(0.5, b.determinant()));
- SkMatrix44 c = b = a;
- c.set(0, 1, SkFloatToMScalar(4));
- b.set(1, 0, SkFloatToMScalar(4));
- REPORTER_ASSERT(reporter,
- nearly_equal_double(a.determinant(),
- b.determinant()));
- SkMatrix44 d = a;
- d.set(0, 0, SkFloatToMScalar(8));
- REPORTER_ASSERT(reporter, nearly_equal_double(16, d.determinant()));
-
- SkMatrix44 e = a;
- e.postConcat(d);
- REPORTER_ASSERT(reporter, nearly_equal_double(32, e.determinant()));
- e.set(0, 0, SkFloatToMScalar(0));
- REPORTER_ASSERT(reporter, nearly_equal_double(0, e.determinant()));
+ SkMatrix44 a;
+ REPORTER_ASSERT(reporter, nearly_equal_double(1, a.determinant()));
+ a.set(1, 1, SkFloatToMScalar(2));
+ REPORTER_ASSERT(reporter, nearly_equal_double(2, a.determinant()));
+ SkMatrix44 b;
+ REPORTER_ASSERT(reporter, a.invert(&b));
+ REPORTER_ASSERT(reporter, nearly_equal_double(0.5, b.determinant()));
+ SkMatrix44 c = b = a;
+ c.set(0, 1, SkFloatToMScalar(4));
+ b.set(1, 0, SkFloatToMScalar(4));
+ REPORTER_ASSERT(reporter,
+ nearly_equal_double(a.determinant(),
+ b.determinant()));
+ SkMatrix44 d = a;
+ d.set(0, 0, SkFloatToMScalar(8));
+ REPORTER_ASSERT(reporter, nearly_equal_double(16, d.determinant()));
+
+ SkMatrix44 e = a;
+ e.postConcat(d);
+ REPORTER_ASSERT(reporter, nearly_equal_double(32, e.determinant()));
+ e.set(0, 0, SkFloatToMScalar(0));
+ REPORTER_ASSERT(reporter, nearly_equal_double(0, e.determinant()));
}
static void test_transpose(skiatest::Reporter* reporter) {
- SkMatrix44 a;
- SkMatrix44 b;
-
- int i = 0;
- for (int row = 0; row < 4; ++row) {
- for (int col = 0; col < 4; ++col) {
- a.setDouble(row, col, i);
- b.setDouble(col, row, i++);
+ SkMatrix44 a;
+ SkMatrix44 b;
+
+ int i = 0;
+ for (int row = 0; row < 4; ++row) {
+ for (int col = 0; col < 4; ++col) {
+ a.setDouble(row, col, i);
+ b.setDouble(col, row, i++);
+ }
}
- }
- a.transpose();
- REPORTER_ASSERT(reporter, nearly_equal(a, b));
+ a.transpose();
+ REPORTER_ASSERT(reporter, nearly_equal(a, b));
}
static void test_get_set_double(skiatest::Reporter* reporter) {
- SkMatrix44 a;
- for (int row = 0; row < 4; ++row) {
- for (int col = 0; col < 4; ++col) {
- a.setDouble(row, col, 3.141592653589793);
- REPORTER_ASSERT(reporter, nearly_equal_double(3.141592653589793,
- a.getDouble(row, col)));
- a.setDouble(row, col, 0);
- REPORTER_ASSERT(reporter, nearly_equal_double(0, a.getDouble(row, col)));
+ SkMatrix44 a;
+ for (int row = 0; row < 4; ++row) {
+ for (int col = 0; col < 4; ++col) {
+ a.setDouble(row, col, 3.141592653589793);
+ REPORTER_ASSERT(reporter,
+ nearly_equal_double(3.141592653589793,
+ a.getDouble(row, col)));
+ a.setDouble(row, col, 0);
+ REPORTER_ASSERT(reporter,
+ nearly_equal_double(0, a.getDouble(row, col)));
+ }
}
- }
+}
+
+static void test_set_row_col_major(skiatest::Reporter* reporter) {
+ SkMatrix44 a, b, c, d;
+ for (int row = 0; row < 4; ++row)
+ for (int col = 0; col < 4; ++col)
+ a.setDouble(row, col, row * 4 + col);
+ double bufferd[16];
+ float bufferf[16];
+ a.asColMajord(bufferd);
+ b.setColMajord(bufferd);
+ REPORTER_ASSERT(reporter, nearly_equal(a, b));
+ b.setRowMajord(bufferd);
+ b.transpose();
+ REPORTER_ASSERT(reporter, nearly_equal(a, b));
+ a.asColMajorf(bufferf);
+ b.setColMajorf(bufferf);
+ REPORTER_ASSERT(reporter, nearly_equal(a, b));
+ b.setRowMajorf(bufferf);
+ b.transpose();
+ REPORTER_ASSERT(reporter, nearly_equal(a, b));
}
static void TestMatrix44(skiatest::Reporter* reporter) {