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 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 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 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 } 475 }
476 return true; 476 return true;
477 } 477 }
478 if (this->isScaleTranslate()) { 478 if (this->isScaleTranslate()) {
479 if (0 == fMat[0][0] * fMat[1][1] * fMat[2][2]) { 479 if (0 == fMat[0][0] * fMat[1][1] * fMat[2][2]) {
480 return false; 480 return false;
481 } 481 }
482 if (inverse) { 482 if (inverse) {
483 sk_bzero(inverse->fMat, sizeof(inverse->fMat)); 483 sk_bzero(inverse->fMat, sizeof(inverse->fMat));
484 484
485 inverse->fMat[3][0] = -fMat[3][0] / fMat[0][0]; 485 double invXScale = 1 / fMat[0][0];
486 inverse->fMat[3][1] = -fMat[3][1] / fMat[1][1]; 486 double invYScale = 1 / fMat[1][1];
487 inverse->fMat[3][2] = -fMat[3][2] / fMat[2][2]; 487 double invZScale = 1 / fMat[2][2];
488 488
489 inverse->fMat[0][0] = 1 / fMat[0][0]; 489 inverse->fMat[3][0] = -fMat[3][0] * invXScale;
490 inverse->fMat[1][1] = 1 / fMat[1][1]; 490 inverse->fMat[3][1] = -fMat[3][1] * invYScale;
491 inverse->fMat[2][2] = 1 / fMat[2][2]; 491 inverse->fMat[3][2] = -fMat[3][2] * invZScale;
492
493 inverse->fMat[0][0] = invXScale;
494 inverse->fMat[1][1] = invYScale;
495 inverse->fMat[2][2] = invZScale;
492 inverse->fMat[3][3] = 1; 496 inverse->fMat[3][3] = 1;
493 497
494 inverse->setTypeMask(this->getType()); 498 inverse->setTypeMask(this->getType());
495 } 499 }
496 return true; 500 return true;
497 } 501 }
498 502
499 double a00 = fMat[0][0]; 503 double a00 = fMat[0][0];
500 double a01 = fMat[0][1]; 504 double a01 = fMat[0][1];
501 double a02 = fMat[0][2]; 505 double a02 = fMat[0][2];
502 double a03 = fMat[0][3]; 506 double a03 = fMat[0][3];
503 double a10 = fMat[1][0]; 507 double a10 = fMat[1][0];
504 double a11 = fMat[1][1]; 508 double a11 = fMat[1][1];
505 double a12 = fMat[1][2]; 509 double a12 = fMat[1][2];
506 double a13 = fMat[1][3]; 510 double a13 = fMat[1][3];
507 double a20 = fMat[2][0]; 511 double a20 = fMat[2][0];
508 double a21 = fMat[2][1]; 512 double a21 = fMat[2][1];
509 double a22 = fMat[2][2]; 513 double a22 = fMat[2][2];
510 double a23 = fMat[2][3]; 514 double a23 = fMat[2][3];
511 double a30 = fMat[3][0]; 515 double a30 = fMat[3][0];
512 double a31 = fMat[3][1]; 516 double a31 = fMat[3][1];
513 double a32 = fMat[3][2]; 517 double a32 = fMat[3][2];
514 double a33 = fMat[3][3]; 518 double a33 = fMat[3][3];
515 519
520 if (!(this->getType() & kPerspective_Mask)) {
reed1 2013/08/20 15:14:13 At some point we should consider breaking each of
521 // If we know the matrix has no perspective,
522 // then its bottom row is (0, 0, 0, 1).
jvanverth1 2013/08/20 14:16:54 Assuming our indexing is (row, column) this should
523 // We can use this information to save a lot
524 // of arithmetic that would be used to compute
525 // the inverse of a general matrix.
526
527 SkASSERT(a03 == 0);
528 SkASSERT(a13 == 0);
529 SkASSERT(a23 == 0);
530 SkASSERT(a33 == 1);
531
532 double b00 = a00 * a11 - a01 * a10;
533 double b01 = a00 * a12 - a02 * a10;
534 double b03 = a01 * a12 - a02 * a11;
535 double b06 = a20 * a31 - a21 * a30;
536 double b07 = a20 * a32 - a22 * a30;
537 double b08 = a20;
538 double b09 = a21 * a32 - a22 * a31;
539 double b10 = a21;
540 double b11 = a22;
541
542 // Calculate the determinant
543 double det = b00 * b11 - b01 * b10 + b03 * b08;
544
545 if (dabs(det) < TOO_SMALL_FOR_DETERMINANT) {
546 return false;
547 }
548 if (NULL == inverse) {
549 return true;
550 }
551 double invdet = 1.0 / det;
552
553 b00 *= invdet;
554 b01 *= invdet;
555 b03 *= invdet;
556 b06 *= invdet;
557 b07 *= invdet;
558 b08 *= invdet;
559 b09 *= invdet;
560 b10 *= invdet;
561 b11 *= invdet;
562
563 inverse->fMat[0][0] = SkDoubleToMScalar(a11 * b11 - a12 * b10);
564 inverse->fMat[0][1] = SkDoubleToMScalar(a02 * b10 - a01 * b11);
565 inverse->fMat[0][2] = SkDoubleToMScalar(b03);
566 inverse->fMat[0][3] = 0;
567 inverse->fMat[1][0] = SkDoubleToMScalar(a12 * b08 - a10 * b11);
568 inverse->fMat[1][1] = SkDoubleToMScalar(a00 * b11 - a02 * b08);
569 inverse->fMat[1][2] = SkDoubleToMScalar(-b01);
570 inverse->fMat[1][3] = 0;
571 inverse->fMat[2][0] = SkDoubleToMScalar(a10 * b10 - a11 * b08);
572 inverse->fMat[2][1] = SkDoubleToMScalar(a01 * b08 - a00 * b10);
573 inverse->fMat[2][2] = SkDoubleToMScalar(b00);
574 inverse->fMat[2][3] = 0;
575 inverse->fMat[3][0] = SkDoubleToMScalar(a11 * b07 - a10 * b09 - a12 * b0 6);
576 inverse->fMat[3][1] = SkDoubleToMScalar(a00 * b09 - a01 * b07 + a02 * b0 6);
577 inverse->fMat[3][2] = SkDoubleToMScalar(a31 * b01 - a30 * b03 - a32 * b0 0);
578 inverse->fMat[3][3] = 1;
579
580 inverse->setTypeMask(this->getType());
581 return true;
582 }
583
516 double b00 = a00 * a11 - a01 * a10; 584 double b00 = a00 * a11 - a01 * a10;
517 double b01 = a00 * a12 - a02 * a10; 585 double b01 = a00 * a12 - a02 * a10;
518 double b02 = a00 * a13 - a03 * a10; 586 double b02 = a00 * a13 - a03 * a10;
519 double b03 = a01 * a12 - a02 * a11; 587 double b03 = a01 * a12 - a02 * a11;
520 double b04 = a01 * a13 - a03 * a11; 588 double b04 = a01 * a13 - a03 * a11;
521 double b05 = a02 * a13 - a03 * a12; 589 double b05 = a02 * a13 - a03 * a12;
522 double b06 = a20 * a31 - a21 * a30; 590 double b06 = a20 * a31 - a21 * a30;
523 double b07 = a20 * a32 - a22 * a30; 591 double b07 = a20 * a32 - a22 * a30;
524 double b08 = a20 * a33 - a23 * a30; 592 double b08 = a20 * a33 - a23 * a30;
525 double b09 = a21 * a32 - a22 * a31; 593 double b09 = a21 * a32 - a22 * a31;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 inverse->fMat[1][2] = SkDoubleToMScalar(a32 * b02 - a30 * b05 - a33 * b01); 627 inverse->fMat[1][2] = SkDoubleToMScalar(a32 * b02 - a30 * b05 - a33 * b01);
560 inverse->fMat[1][3] = SkDoubleToMScalar(a20 * b05 - a22 * b02 + a23 * b01); 628 inverse->fMat[1][3] = SkDoubleToMScalar(a20 * b05 - a22 * b02 + a23 * b01);
561 inverse->fMat[2][0] = SkDoubleToMScalar(a10 * b10 - a11 * b08 + a13 * b06); 629 inverse->fMat[2][0] = SkDoubleToMScalar(a10 * b10 - a11 * b08 + a13 * b06);
562 inverse->fMat[2][1] = SkDoubleToMScalar(a01 * b08 - a00 * b10 - a03 * b06); 630 inverse->fMat[2][1] = SkDoubleToMScalar(a01 * b08 - a00 * b10 - a03 * b06);
563 inverse->fMat[2][2] = SkDoubleToMScalar(a30 * b04 - a31 * b02 + a33 * b00); 631 inverse->fMat[2][2] = SkDoubleToMScalar(a30 * b04 - a31 * b02 + a33 * b00);
564 inverse->fMat[2][3] = SkDoubleToMScalar(a21 * b02 - a20 * b04 - a23 * b00); 632 inverse->fMat[2][3] = SkDoubleToMScalar(a21 * b02 - a20 * b04 - a23 * b00);
565 inverse->fMat[3][0] = SkDoubleToMScalar(a11 * b07 - a10 * b09 - a12 * b06); 633 inverse->fMat[3][0] = SkDoubleToMScalar(a11 * b07 - a10 * b09 - a12 * b06);
566 inverse->fMat[3][1] = SkDoubleToMScalar(a00 * b09 - a01 * b07 + a02 * b06); 634 inverse->fMat[3][1] = SkDoubleToMScalar(a00 * b09 - a01 * b07 + a02 * b06);
567 inverse->fMat[3][2] = SkDoubleToMScalar(a31 * b01 - a30 * b03 - a32 * b00); 635 inverse->fMat[3][2] = SkDoubleToMScalar(a31 * b01 - a30 * b03 - a32 * b00);
568 inverse->fMat[3][3] = SkDoubleToMScalar(a20 * b03 - a21 * b01 + a22 * b00); 636 inverse->fMat[3][3] = SkDoubleToMScalar(a20 * b03 - a21 * b01 + a22 * b00);
569 inverse->dirtyTypeMask(); 637
570
571 inverse->dirtyTypeMask(); 638 inverse->dirtyTypeMask();
572 return true; 639 return true;
573 } 640 }
574 641
575 /////////////////////////////////////////////////////////////////////////////// 642 ///////////////////////////////////////////////////////////////////////////////
576 643
577 void SkMatrix44::transpose() { 644 void SkMatrix44::transpose() {
578 SkTSwap(fMat[0][1], fMat[1][0]); 645 SkTSwap(fMat[0][1], fMat[1][0]);
579 SkTSwap(fMat[0][2], fMat[2][0]); 646 SkTSwap(fMat[0][2], fMat[2][0]);
580 SkTSwap(fMat[0][3], fMat[3][0]); 647 SkTSwap(fMat[0][3], fMat[3][0]);
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 dst[SkMatrix::kMScaleX] = SkMScalarToScalar(fMat[0][0]); 912 dst[SkMatrix::kMScaleX] = SkMScalarToScalar(fMat[0][0]);
846 dst[SkMatrix::kMSkewX] = SkMScalarToScalar(fMat[1][0]); 913 dst[SkMatrix::kMSkewX] = SkMScalarToScalar(fMat[1][0]);
847 dst[SkMatrix::kMTransX] = SkMScalarToScalar(fMat[3][0]); 914 dst[SkMatrix::kMTransX] = SkMScalarToScalar(fMat[3][0]);
848 915
849 dst[SkMatrix::kMSkewY] = SkMScalarToScalar(fMat[0][1]); 916 dst[SkMatrix::kMSkewY] = SkMScalarToScalar(fMat[0][1]);
850 dst[SkMatrix::kMScaleY] = SkMScalarToScalar(fMat[1][1]); 917 dst[SkMatrix::kMScaleY] = SkMScalarToScalar(fMat[1][1]);
851 dst[SkMatrix::kMTransY] = SkMScalarToScalar(fMat[3][1]); 918 dst[SkMatrix::kMTransY] = SkMScalarToScalar(fMat[3][1]);
852 919
853 return dst; 920 return dst;
854 } 921 }
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