Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(368)

Unified Diff: src/utils/SkMatrix44.cpp

Issue 23296006: Improve performance of matrix inversion. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/utils/SkMatrix44.cpp
===================================================================
--- src/utils/SkMatrix44.cpp (revision 10801)
+++ src/utils/SkMatrix44.cpp (working copy)
@@ -482,13 +482,17 @@
if (inverse) {
sk_bzero(inverse->fMat, sizeof(inverse->fMat));
- inverse->fMat[3][0] = -fMat[3][0] / fMat[0][0];
- inverse->fMat[3][1] = -fMat[3][1] / fMat[1][1];
- inverse->fMat[3][2] = -fMat[3][2] / fMat[2][2];
+ double invXScale = 1 / fMat[0][0];
+ double invYScale = 1 / fMat[1][1];
+ double invZScale = 1 / fMat[2][2];
- inverse->fMat[0][0] = 1 / fMat[0][0];
- inverse->fMat[1][1] = 1 / fMat[1][1];
- inverse->fMat[2][2] = 1 / fMat[2][2];
+ inverse->fMat[3][0] = -fMat[3][0] * invXScale;
+ inverse->fMat[3][1] = -fMat[3][1] * invYScale;
+ inverse->fMat[3][2] = -fMat[3][2] * invZScale;
+
+ inverse->fMat[0][0] = invXScale;
+ inverse->fMat[1][1] = invYScale;
+ inverse->fMat[2][2] = invZScale;
inverse->fMat[3][3] = 1;
inverse->setTypeMask(this->getType());
@@ -513,6 +517,70 @@
double a32 = fMat[3][2];
double a33 = fMat[3][3];
+ if (!(this->getType() & kPerspective_Mask)) {
reed1 2013/08/20 15:14:13 At some point we should consider breaking each of
+ // If we know the matrix has no perspective,
+ // then its bottom row is (0, 0, 0, 1).
jvanverth1 2013/08/20 14:16:54 Assuming our indexing is (row, column) this should
+ // We can use this information to save a lot
+ // of arithmetic that would be used to compute
+ // the inverse of a general matrix.
+
+ SkASSERT(a03 == 0);
+ SkASSERT(a13 == 0);
+ SkASSERT(a23 == 0);
+ SkASSERT(a33 == 1);
+
+ double b00 = a00 * a11 - a01 * a10;
+ double b01 = a00 * a12 - a02 * a10;
+ double b03 = a01 * a12 - a02 * a11;
+ double b06 = a20 * a31 - a21 * a30;
+ double b07 = a20 * a32 - a22 * a30;
+ double b08 = a20;
+ double b09 = a21 * a32 - a22 * a31;
+ double b10 = a21;
+ double b11 = a22;
+
+ // Calculate the determinant
+ double det = b00 * b11 - b01 * b10 + b03 * b08;
+
+ if (dabs(det) < TOO_SMALL_FOR_DETERMINANT) {
+ return false;
+ }
+ if (NULL == inverse) {
+ return true;
+ }
+ double invdet = 1.0 / det;
+
+ b00 *= invdet;
+ b01 *= invdet;
+ b03 *= invdet;
+ b06 *= invdet;
+ b07 *= invdet;
+ b08 *= invdet;
+ b09 *= invdet;
+ b10 *= invdet;
+ b11 *= invdet;
+
+ inverse->fMat[0][0] = SkDoubleToMScalar(a11 * b11 - a12 * b10);
+ inverse->fMat[0][1] = SkDoubleToMScalar(a02 * b10 - a01 * b11);
+ inverse->fMat[0][2] = SkDoubleToMScalar(b03);
+ inverse->fMat[0][3] = 0;
+ inverse->fMat[1][0] = SkDoubleToMScalar(a12 * b08 - a10 * b11);
+ inverse->fMat[1][1] = SkDoubleToMScalar(a00 * b11 - a02 * b08);
+ inverse->fMat[1][2] = SkDoubleToMScalar(-b01);
+ inverse->fMat[1][3] = 0;
+ inverse->fMat[2][0] = SkDoubleToMScalar(a10 * b10 - a11 * b08);
+ inverse->fMat[2][1] = SkDoubleToMScalar(a01 * b08 - a00 * b10);
+ inverse->fMat[2][2] = SkDoubleToMScalar(b00);
+ inverse->fMat[2][3] = 0;
+ inverse->fMat[3][0] = SkDoubleToMScalar(a11 * b07 - a10 * b09 - a12 * b06);
+ inverse->fMat[3][1] = SkDoubleToMScalar(a00 * b09 - a01 * b07 + a02 * b06);
+ inverse->fMat[3][2] = SkDoubleToMScalar(a31 * b01 - a30 * b03 - a32 * b00);
+ inverse->fMat[3][3] = 1;
+
+ inverse->setTypeMask(this->getType());
+ return true;
+ }
+
double b00 = a00 * a11 - a01 * a10;
double b01 = a00 * a12 - a02 * a10;
double b02 = a00 * a13 - a03 * a10;
@@ -566,9 +634,8 @@
inverse->fMat[3][1] = SkDoubleToMScalar(a00 * b09 - a01 * b07 + a02 * b06);
inverse->fMat[3][2] = SkDoubleToMScalar(a31 * b01 - a30 * b03 - a32 * b00);
inverse->fMat[3][3] = SkDoubleToMScalar(a20 * b03 - a21 * b01 + a22 * b00);
+
inverse->dirtyTypeMask();
-
- inverse->dirtyTypeMask();
return true;
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698