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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkMatrix44.h" 8 #include "SkMatrix44.h"
9 9
10 static inline bool eq4(const SkMScalar* SK_RESTRICT a, 10 static inline bool eq4(const SkMScalar* SK_RESTRICT a,
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 } 173 }
174 174
175 /////////////////////////////////////////////////////////////////////////////// 175 ///////////////////////////////////////////////////////////////////////////////
176 176
177 const SkMatrix44& SkMatrix44::I() { 177 const SkMatrix44& SkMatrix44::I() {
178 static const SkMatrix44 gIdentity44(kIdentity_Constructor); 178 static const SkMatrix44 gIdentity44(kIdentity_Constructor);
179 return gIdentity44; 179 return gIdentity44;
180 } 180 }
181 181
182 void SkMatrix44::setIdentity() { 182 void SkMatrix44::setIdentity() {
183 sk_bzero(fMat, sizeof(fMat)); 183 fMat[0][0] = 1;
184 fMat[0][0] = fMat[1][1] = fMat[2][2] = fMat[3][3] = 1; 184 fMat[0][1] = 0;
185 fMat[0][2] = 0;
186 fMat[0][3] = 0;
187 fMat[1][0] = 0;
188 fMat[1][1] = 1;
189 fMat[1][2] = 0;
190 fMat[1][3] = 0;
191 fMat[2][0] = 0;
192 fMat[2][1] = 0;
193 fMat[2][2] = 1;
194 fMat[2][3] = 0;
195 fMat[3][0] = 0;
196 fMat[3][1] = 0;
197 fMat[3][2] = 0;
198 fMat[3][3] = 1;
185 this->setTypeMask(kIdentity_Mask); 199 this->setTypeMask(kIdentity_Mask);
186 } 200 }
187 201
188 void SkMatrix44::set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02, 202 void SkMatrix44::set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02,
189 SkMScalar m10, SkMScalar m11, SkMScalar m12, 203 SkMScalar m10, SkMScalar m11, SkMScalar m12,
190 SkMScalar m20, SkMScalar m21, SkMScalar m22) { 204 SkMScalar m20, SkMScalar m21, SkMScalar m22) {
191 fMat[0][0] = m00; fMat[0][1] = m01; fMat[0][2] = m02; fMat[0][3] = 0; 205 fMat[0][0] = m00; fMat[0][1] = m01; fMat[0][2] = m02; fMat[0][3] = 0;
192 fMat[1][0] = m10; fMat[1][1] = m11; fMat[1][2] = m12; fMat[1][3] = 0; 206 fMat[1][0] = m10; fMat[1][1] = m11; fMat[1][2] = m12; fMat[1][3] = 0;
193 fMat[2][0] = m20; fMat[2][1] = m21; fMat[2][2] = m22; fMat[2][3] = 0; 207 fMat[2][0] = m20; fMat[2][1] = m21; fMat[2][2] = m22; fMat[2][3] = 0;
194 fMat[3][0] = 0; fMat[3][1] = 0; fMat[3][2] = 0; fMat[3][3] = 1; 208 fMat[3][0] = 0; fMat[3][1] = 0; fMat[3][2] = 0; fMat[3][3] = 1;
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 double b09 = a21 * a32 - a22 * a31; 459 double b09 = a21 * a32 - a22 * a31;
446 double b10 = a21 * a33 - a23 * a31; 460 double b10 = a21 * a33 - a23 * a31;
447 double b11 = a22 * a33 - a23 * a32; 461 double b11 = a22 * a33 - a23 * a32;
448 462
449 // Calculate the determinant 463 // Calculate the determinant
450 return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06 ; 464 return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06 ;
451 } 465 }
452 466
453 /////////////////////////////////////////////////////////////////////////////// 467 ///////////////////////////////////////////////////////////////////////////////
454 468
455 // just picked a small value. not sure how to pick the "right" one
456 #define TOO_SMALL_FOR_DETERMINANT (1.e-8)
457
458 static inline double dabs(double x) { 469 static inline double dabs(double x) {
459 if (x < 0) { 470 if (x < 0) {
460 x = -x; 471 x = -x;
461 } 472 }
462 return x; 473 return x;
463 } 474 }
464 475
465 bool SkMatrix44::invert(SkMatrix44* inverse) const { 476 bool SkMatrix44::invert(SkMatrix44* inverse) const {
466 if (this->isIdentity()) { 477 if (this->isIdentity()) {
467 if (inverse) { 478 if (inverse) {
468 *inverse = *this; 479 inverse->setIdentity();
469 return true; 480 return true;
470 } 481 }
471 } 482 }
472 if (this->isTranslate()) { 483 if (this->isTranslate()) {
473 if (inverse) { 484 if (inverse) {
474 inverse->setTranslate(-fMat[3][0], -fMat[3][1], -fMat[3][2]); 485 inverse->setTranslate(-fMat[3][0], -fMat[3][1], -fMat[3][2]);
475 } 486 }
476 return true; 487 return true;
477 } 488 }
478 if (this->isScaleTranslate()) { 489 if (this->isScaleTranslate()) {
479 if (0 == fMat[0][0] * fMat[1][1] * fMat[2][2]) { 490 if (0 == fMat[0][0] * fMat[1][1] * fMat[2][2]) {
480 return false; 491 return false;
481 } 492 }
482 if (inverse) {
483 sk_bzero(inverse->fMat, sizeof(inverse->fMat));
484 493
485 double invXScale = 1 / fMat[0][0]; 494 double a00 = fMat[0][0];
486 double invYScale = 1 / fMat[1][1]; 495 double a11 = fMat[1][1];
487 double invZScale = 1 / fMat[2][2]; 496 double a22 = fMat[2][2];
497 double a30 = fMat[3][0];
498 double a31 = fMat[3][1];
499 double a32 = fMat[3][2];
488 500
489 inverse->fMat[3][0] = -fMat[3][0] * invXScale; 501 double b00 = a00 * a11;
490 inverse->fMat[3][1] = -fMat[3][1] * invYScale; 502 double b07 = -a22 * a30;
491 inverse->fMat[3][2] = -fMat[3][2] * invZScale; 503 double b09 = -a22 * a31;
504 double b11 = a22;
492 505
493 inverse->fMat[0][0] = invXScale; 506 // Calculate the determinant
494 inverse->fMat[1][1] = invYScale; 507 double det = b00 * b11;
495 inverse->fMat[2][2] = invZScale;
496 inverse->fMat[3][3] = 1;
497 508
498 inverse->setTypeMask(this->getType()); 509 double invdet = 1.0 / det;
510 // If det is zero, we want to return false. However, we also want to ret urn false
511 // if 1/det overflows to infinity (i.e. det is denormalized). Both of th ese are
512 // handled by checking that 1/det is finite.
513 if (!sk_float_isfinite(invdet)) {
514 return false;
499 } 515 }
516 if (NULL == inverse) {
517 return true;
518 }
519
520 b00 *= invdet;
521 b07 *= invdet;
522 b09 *= invdet;
523 b11 *= invdet;
524
525 inverse->fMat[0][0] = SkDoubleToMScalar(a11 * b11);
526 inverse->fMat[0][1] = 0;
527 inverse->fMat[0][2] = 0;
528 inverse->fMat[0][3] = 0;
529 inverse->fMat[1][0] = 0;
530 inverse->fMat[1][1] = SkDoubleToMScalar(a00 * b11);
531 inverse->fMat[1][2] = 0;
532 inverse->fMat[1][3] = 0;
533 inverse->fMat[2][0] = 0;
534 inverse->fMat[2][1] = 0;
535 inverse->fMat[2][2] = SkDoubleToMScalar(b00);
536 inverse->fMat[2][3] = 0;
537 inverse->fMat[3][0] = SkDoubleToMScalar(a11 * b07);
538 inverse->fMat[3][1] = SkDoubleToMScalar(a00 * b09);
539 inverse->fMat[3][2] = SkDoubleToMScalar(-a32 * b00);
540 inverse->fMat[3][3] = 1;
541
542 inverse->setTypeMask(this->getType());
500 return true; 543 return true;
501 } 544 }
502 545
503 double a00 = fMat[0][0]; 546 double a00 = fMat[0][0];
504 double a01 = fMat[0][1]; 547 double a01 = fMat[0][1];
505 double a02 = fMat[0][2]; 548 double a02 = fMat[0][2];
506 double a03 = fMat[0][3]; 549 double a03 = fMat[0][3];
507 double a10 = fMat[1][0]; 550 double a10 = fMat[1][0];
508 double a11 = fMat[1][1]; 551 double a11 = fMat[1][1];
509 double a12 = fMat[1][2]; 552 double a12 = fMat[1][2];
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 fMat[2][0], fMat[2][1], fMat[2][2], fMat[2][3], 919 fMat[2][0], fMat[2][1], fMat[2][2], fMat[2][3],
877 fMat[3][0], fMat[3][1], fMat[3][2], fMat[3][3]); 920 fMat[3][0], fMat[3][1], fMat[3][2], fMat[3][3]);
878 #endif 921 #endif
879 } 922 }
880 923
881 /////////////////////////////////////////////////////////////////////////////// 924 ///////////////////////////////////////////////////////////////////////////////
882 925
883 // TODO: make this support src' perspective elements 926 // TODO: make this support src' perspective elements
884 // 927 //
885 static void initFromMatrix(SkMScalar dst[4][4], const SkMatrix& src) { 928 static void initFromMatrix(SkMScalar dst[4][4], const SkMatrix& src) {
886 sk_bzero(dst, 16 * sizeof(SkMScalar));
887 dst[0][0] = SkScalarToMScalar(src[SkMatrix::kMScaleX]); 929 dst[0][0] = SkScalarToMScalar(src[SkMatrix::kMScaleX]);
888 dst[1][0] = SkScalarToMScalar(src[SkMatrix::kMSkewX]); 930 dst[1][0] = SkScalarToMScalar(src[SkMatrix::kMSkewX]);
931 dst[2][0] = 0;
889 dst[3][0] = SkScalarToMScalar(src[SkMatrix::kMTransX]); 932 dst[3][0] = SkScalarToMScalar(src[SkMatrix::kMTransX]);
890 dst[0][1] = SkScalarToMScalar(src[SkMatrix::kMSkewY]); 933 dst[0][1] = SkScalarToMScalar(src[SkMatrix::kMSkewY]);
891 dst[1][1] = SkScalarToMScalar(src[SkMatrix::kMScaleY]); 934 dst[1][1] = SkScalarToMScalar(src[SkMatrix::kMScaleY]);
935 dst[2][1] = 0;
892 dst[3][1] = SkScalarToMScalar(src[SkMatrix::kMTransY]); 936 dst[3][1] = SkScalarToMScalar(src[SkMatrix::kMTransY]);
893 dst[2][2] = dst[3][3] = 1; 937 dst[0][2] = 0;
938 dst[1][2] = 0;
939 dst[2][2] = 1;
940 dst[3][2] = 0;
941 dst[0][3] = 0;
942 dst[1][3] = 0;
943 dst[2][3] = 0;
944 dst[3][3] = 1;
894 } 945 }
895 946
896 SkMatrix44::SkMatrix44(const SkMatrix& src) { 947 SkMatrix44::SkMatrix44(const SkMatrix& src) {
897 initFromMatrix(fMat, src); 948 initFromMatrix(fMat, src);
898 } 949 }
899 950
900 SkMatrix44& SkMatrix44::operator=(const SkMatrix& src) { 951 SkMatrix44& SkMatrix44::operator=(const SkMatrix& src) {
901 initFromMatrix(fMat, src); 952 initFromMatrix(fMat, src);
902 953
903 if (src.isIdentity()) { 954 if (src.isIdentity()) {
(...skipping 13 matching lines...) Expand all
917 dst[SkMatrix::kMScaleX] = SkMScalarToScalar(fMat[0][0]); 968 dst[SkMatrix::kMScaleX] = SkMScalarToScalar(fMat[0][0]);
918 dst[SkMatrix::kMSkewX] = SkMScalarToScalar(fMat[1][0]); 969 dst[SkMatrix::kMSkewX] = SkMScalarToScalar(fMat[1][0]);
919 dst[SkMatrix::kMTransX] = SkMScalarToScalar(fMat[3][0]); 970 dst[SkMatrix::kMTransX] = SkMScalarToScalar(fMat[3][0]);
920 971
921 dst[SkMatrix::kMSkewY] = SkMScalarToScalar(fMat[0][1]); 972 dst[SkMatrix::kMSkewY] = SkMScalarToScalar(fMat[0][1]);
922 dst[SkMatrix::kMScaleY] = SkMScalarToScalar(fMat[1][1]); 973 dst[SkMatrix::kMScaleY] = SkMScalarToScalar(fMat[1][1]);
923 dst[SkMatrix::kMTransY] = SkMScalarToScalar(fMat[3][1]); 974 dst[SkMatrix::kMTransY] = SkMScalarToScalar(fMat[3][1]);
924 975
925 return dst; 976 return dst;
926 } 977 }
OLDNEW
« 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