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

Unified Diff: src/utils/SkMatrix44.cpp

Issue 23090008: Remove sk_bzero usage from SkMatrix44 for improved performance. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: even faster inversion for scale/translate matrices 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 10895)
+++ src/utils/SkMatrix44.cpp (working copy)
@@ -180,8 +180,22 @@
}
void SkMatrix44::setIdentity() {
- sk_bzero(fMat, sizeof(fMat));
- fMat[0][0] = fMat[1][1] = fMat[2][2] = fMat[3][3] = 1;
+ fMat[0][0] = 1;
+ fMat[0][1] = 0;
+ fMat[0][2] = 0;
+ fMat[0][3] = 0;
+ fMat[1][0] = 0;
+ fMat[1][1] = 1;
+ fMat[1][2] = 0;
+ fMat[1][3] = 0;
+ fMat[2][0] = 0;
+ fMat[2][1] = 0;
+ fMat[2][2] = 1;
+ fMat[2][3] = 0;
+ fMat[3][0] = 0;
+ fMat[3][1] = 0;
+ fMat[3][2] = 0;
+ fMat[3][3] = 1;
this->setTypeMask(kIdentity_Mask);
}
@@ -452,9 +466,6 @@
///////////////////////////////////////////////////////////////////////////////
-// just picked a small value. not sure how to pick the "right" one
-#define TOO_SMALL_FOR_DETERMINANT (1.e-8)
-
static inline double dabs(double x) {
if (x < 0) {
x = -x;
@@ -465,7 +476,7 @@
bool SkMatrix44::invert(SkMatrix44* inverse) const {
if (this->isIdentity()) {
if (inverse) {
- *inverse = *this;
+ inverse->setIdentity();
return true;
}
}
@@ -479,24 +490,56 @@
if (0 == fMat[0][0] * fMat[1][1] * fMat[2][2]) {
return false;
}
- if (inverse) {
- sk_bzero(inverse->fMat, sizeof(inverse->fMat));
- double invXScale = 1 / fMat[0][0];
- double invYScale = 1 / fMat[1][1];
- double invZScale = 1 / fMat[2][2];
+ double a00 = fMat[0][0];
+ double a11 = fMat[1][1];
+ double a22 = fMat[2][2];
+ double a30 = fMat[3][0];
+ double a31 = fMat[3][1];
+ double a32 = fMat[3][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;
+ double b00 = a00 * a11;
+ double b07 = -a22 * a30;
+ double b09 = -a22 * a31;
+ double b11 = a22;
- inverse->fMat[0][0] = invXScale;
- inverse->fMat[1][1] = invYScale;
- inverse->fMat[2][2] = invZScale;
- inverse->fMat[3][3] = 1;
+ // Calculate the determinant
+ double det = b00 * b11;
- inverse->setTypeMask(this->getType());
+ double invdet = 1.0 / det;
+ // If det is zero, we want to return false. However, we also want to return false
+ // if 1/det overflows to infinity (i.e. det is denormalized). Both of these are
+ // handled by checking that 1/det is finite.
+ if (!sk_float_isfinite(invdet)) {
+ return false;
}
+ if (NULL == inverse) {
+ return true;
+ }
+
+ b00 *= invdet;
+ b07 *= invdet;
+ b09 *= invdet;
+ b11 *= invdet;
+
+ inverse->fMat[0][0] = SkDoubleToMScalar(a11 * b11);
+ inverse->fMat[0][1] = 0;
+ inverse->fMat[0][2] = 0;
+ inverse->fMat[0][3] = 0;
+ inverse->fMat[1][0] = 0;
+ inverse->fMat[1][1] = SkDoubleToMScalar(a00 * b11);
+ inverse->fMat[1][2] = 0;
+ inverse->fMat[1][3] = 0;
+ inverse->fMat[2][0] = 0;
+ inverse->fMat[2][1] = 0;
+ inverse->fMat[2][2] = SkDoubleToMScalar(b00);
+ inverse->fMat[2][3] = 0;
+ inverse->fMat[3][0] = SkDoubleToMScalar(a11 * b07);
+ inverse->fMat[3][1] = SkDoubleToMScalar(a00 * b09);
+ inverse->fMat[3][2] = SkDoubleToMScalar(-a32 * b00);
+ inverse->fMat[3][3] = 1;
+
+ inverse->setTypeMask(this->getType());
return true;
}
@@ -883,14 +926,22 @@
// TODO: make this support src' perspective elements
//
static void initFromMatrix(SkMScalar dst[4][4], const SkMatrix& src) {
- sk_bzero(dst, 16 * sizeof(SkMScalar));
dst[0][0] = SkScalarToMScalar(src[SkMatrix::kMScaleX]);
dst[1][0] = SkScalarToMScalar(src[SkMatrix::kMSkewX]);
+ dst[2][0] = 0;
dst[3][0] = SkScalarToMScalar(src[SkMatrix::kMTransX]);
dst[0][1] = SkScalarToMScalar(src[SkMatrix::kMSkewY]);
dst[1][1] = SkScalarToMScalar(src[SkMatrix::kMScaleY]);
+ dst[2][1] = 0;
dst[3][1] = SkScalarToMScalar(src[SkMatrix::kMTransY]);
- dst[2][2] = dst[3][3] = 1;
+ dst[0][2] = 0;
+ dst[1][2] = 0;
+ dst[2][2] = 1;
+ dst[3][2] = 0;
+ dst[0][3] = 0;
+ dst[1][3] = 0;
+ dst[2][3] = 0;
+ dst[3][3] = 1;
}
SkMatrix44::SkMatrix44(const SkMatrix& src) {
« 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