aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar vollick@chromium.org <vollick@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-12-10 20:16:10 +0000
committerGravatar vollick@chromium.org <vollick@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-12-10 20:16:10 +0000
commit57a54e33cfe771c792b1086ba67484cb95938d5d (patch)
treecc6e2bd2a84b329244b67669f5a50bdc42c97e42
parent45a15f551b5b3c6c747d8eaf6466b7d3b76a8fae (diff)
Add SkMatrix44 constructor that allows user to control the initialization
method. Preliminary results using Chromium's cc_perftests show that we can avoid almost half of the default constructors from redundantly/unnecessarily initializing the matrix to identity. Review URL: https://codereview.appspot.com/6872056 git-svn-id: http://skia.googlecode.com/svn/trunk@6742 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--include/utils/SkMatrix44.h11
-rw-r--r--tests/Matrix44Test.cpp30
2 files changed, 41 insertions, 0 deletions
diff --git a/include/utils/SkMatrix44.h b/include/utils/SkMatrix44.h
index af61a11c68..4789e7e209 100644
--- a/include/utils/SkMatrix44.h
+++ b/include/utils/SkMatrix44.h
@@ -103,6 +103,17 @@ struct SkVector4 {
class SK_API SkMatrix44 {
public:
+
+ enum Uninitialized_Constructor {
+ kUninitialized_Constructor
+ };
+ enum Identity_Constructor {
+ kIdentity_Constructor
+ };
+
+ SkMatrix44(Uninitialized_Constructor) { }
+ SkMatrix44(Identity_Constructor) { this->setIdentity(); }
+
SkMatrix44() { this->setIdentity(); }
SkMatrix44(const SkMatrix44&);
SkMatrix44(const SkMatrix44& a, const SkMatrix44& b);
diff --git a/tests/Matrix44Test.cpp b/tests/Matrix44Test.cpp
index 9dc77c2b5d..794c935ac9 100644
--- a/tests/Matrix44Test.cpp
+++ b/tests/Matrix44Test.cpp
@@ -77,6 +77,35 @@ static bool bits_isonly(int value, int mask) {
return 0 == (value & ~mask);
}
+static void test_constructor(skiatest::Reporter* reporter) {
+ // Allocate a matrix on the heap
+ SkMatrix44* placeholderMatrix = new SkMatrix44();
+ for (int row = 0; row < 4; ++row) {
+ for (int col = 0; col < 4; ++col) {
+ placeholderMatrix->setDouble(row, col, row * col);
+ }
+ }
+
+ // Use placement-new syntax to trigger the constructor on top of the heap
+ // address we already initialized. This allows us to check that the
+ // constructor did avoid initializing the matrix contents.
+ SkMatrix44* testMatrix = new(placeholderMatrix) SkMatrix44(SkMatrix44::kUninitialized_Constructor);
+ REPORTER_ASSERT(reporter, testMatrix == placeholderMatrix);
+ REPORTER_ASSERT(reporter, !testMatrix->isIdentity());
+ for (int row = 0; row < 4; ++row) {
+ for (int col = 0; col < 4; ++col) {
+ REPORTER_ASSERT(reporter, nearly_equal_double(row * col, testMatrix->getDouble(row, col)));
+ }
+ }
+
+ // Verify that kIdentity_Constructor really does initialize to an identity matrix.
+ testMatrix = 0;
+ testMatrix = new(placeholderMatrix) SkMatrix44(SkMatrix44::kIdentity_Constructor);
+ REPORTER_ASSERT(reporter, testMatrix == placeholderMatrix);
+ REPORTER_ASSERT(reporter, testMatrix->isIdentity());
+ REPORTER_ASSERT(reporter, *testMatrix == SkMatrix44::I());
+}
+
static void test_translate(skiatest::Reporter* reporter) {
SkMatrix44 mat, inverse;
@@ -396,6 +425,7 @@ static void TestMatrix44(skiatest::Reporter* reporter) {
test_common_angles(reporter);
}
+ test_constructor(reporter);
test_gettype(reporter);
test_determinant(reporter);
test_transpose(reporter);