specialize setConcat for scale+translate, helps drawText perf
authorreed <reed@google.com>
Tue, 30 Sep 2014 14:24:46 +0000 (07:24 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 30 Sep 2014 14:24:47 +0000 (07:24 -0700)
BUG=skia:
R=jvanverth@google.com

Author: reed@google.com

Review URL: https://codereview.chromium.org/620433002

include/core/SkMatrix.h
src/core/SkMatrix.cpp

index 9f44bed9c4da20251ccb2053d3b9e2ce7dcec2ee..b3c7378ab27dce136832b910fcaccab9ae924dcc 100644 (file)
@@ -646,6 +646,29 @@ private:
     SkScalar         fMat[9];
     mutable SkTRacy<uint32_t> fTypeMask;
 
+    void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty) {
+        fMat[kMScaleX] = sx;
+        fMat[kMSkewX]  = 0;
+        fMat[kMTransX] = tx;
+        
+        fMat[kMSkewY]  = 0;
+        fMat[kMScaleY] = sy;
+        fMat[kMTransY] = ty;
+        
+        fMat[kMPersp0] = 0;
+        fMat[kMPersp1] = 0;
+        fMat[kMPersp2] = 1;
+        
+        unsigned mask = 0;
+        if (sx != 1 || sy != 1) {
+            mask |= kScale_Mask;
+        }
+        if (tx || ty) {
+            mask |= kTranslate_Mask;
+        }
+        this->setTypeMask(mask | kRectStaysRect_Mask);
+    }
+
     uint8_t computeTypeMask() const;
     uint8_t computePerspectiveTypeMask() const;
 
index 956cf46b9fd3d02bdf167e997fdff22500b0f363..3f235d54aab19d72b806993c6ae8df9a452922f4 100644 (file)
@@ -280,16 +280,7 @@ void SkMatrix::setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) {
     if (1 == sx && 1 == sy) {
         this->reset();
     } else {
-        fMat[kMScaleX] = sx;
-        fMat[kMScaleY] = sy;
-        fMat[kMTransX] = px - sx * px;
-        fMat[kMTransY] = py - sy * py;
-        fMat[kMPersp2] = 1;
-
-        fMat[kMSkewX]  = fMat[kMSkewY] =
-        fMat[kMPersp0] = fMat[kMPersp1] = 0;
-
-        this->setTypeMask(kScale_Mask | kTranslate_Mask | kRectStaysRect_Mask);
+        this->setScaleTranslate(sx, sy, px - sx * px, py - sy * py);
     }
 }
 
@@ -390,8 +381,7 @@ bool SkMatrix::postIDiv(int divx, int divy) {
 
 ////////////////////////////////////////////////////////////////////////////////////
 
-void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV,
-                         SkScalar px, SkScalar py) {
+void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV, SkScalar px, SkScalar py) {
     const SkScalar oneMinusCosV = 1 - cosV;
 
     fMat[kMScaleX]  = cosV;
@@ -517,9 +507,7 @@ void SkMatrix::postSkew(SkScalar sx, SkScalar sy) {
 
 ///////////////////////////////////////////////////////////////////////////////
 
-bool SkMatrix::setRectToRect(const SkRect& src, const SkRect& dst,
-                             ScaleToFit align)
-{
+bool SkMatrix::setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit align) {
     if (src.isEmpty()) {
         this->reset();
         return false;
@@ -527,6 +515,7 @@ bool SkMatrix::setRectToRect(const SkRect& src, const SkRect& dst,
 
     if (dst.isEmpty()) {
         sk_bzero(fMat, 8 * sizeof(SkScalar));
+        fMat[kMPersp2] = 1;
         this->setTypeMask(kScale_Mask | kRectStaysRect_Mask);
     } else {
         SkScalar    tx, sx = dst.width() / src.width();
@@ -564,24 +553,8 @@ bool SkMatrix::setRectToRect(const SkRect& src, const SkRect& dst,
             }
         }
 
-        fMat[kMScaleX] = sx;
-        fMat[kMScaleY] = sy;
-        fMat[kMTransX] = tx;
-        fMat[kMTransY] = ty;
-        fMat[kMSkewX]  = fMat[kMSkewY] =
-        fMat[kMPersp0] = fMat[kMPersp1] = 0;
-
-        unsigned mask = kRectStaysRect_Mask;
-        if (sx != 1 || sy != 1) {
-            mask |= kScale_Mask;
-        }
-        if (tx || ty) {
-            mask |= kTranslate_Mask;
-        }
-        this->setTypeMask(mask);
+        this->setScaleTranslate(sx, sy, tx, ty);
     }
-    // shared cleanup
-    fMat[kMPersp2] = 1;
     return true;
 }
 
@@ -602,14 +575,23 @@ static void normalize_perspective(SkScalar mat[9]) {
     }
 }
 
+static bool only_scale_and_translate(unsigned mask) {
+    return 0 == (mask & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask));
+}
+
 void SkMatrix::setConcat(const SkMatrix& a, const SkMatrix& b) {
-    TypeMask aType = a.getPerspectiveTypeMaskOnly();
-    TypeMask bType = b.getPerspectiveTypeMaskOnly();
+    TypeMask aType = a.getType();
+    TypeMask bType = b.getType();
 
     if (a.isTriviallyIdentity()) {
         *this = b;
     } else if (b.isTriviallyIdentity()) {
         *this = a;
+    } else if (only_scale_and_translate(aType | bType)) {
+        this->setScaleTranslate(a.fMat[kMScaleX] * b.fMat[kMScaleX],
+                                a.fMat[kMScaleY] * b.fMat[kMScaleY],
+                                a.fMat[kMScaleX] * b.fMat[kMTransX] + a.fMat[kMTransX],
+                                a.fMat[kMScaleY] * b.fMat[kMTransY] + a.fMat[kMTransY]);
     } else {
         SkMatrix tmp;
 
@@ -626,7 +608,7 @@ void SkMatrix::setConcat(const SkMatrix& a, const SkMatrix& b) {
 
             normalize_perspective(tmp.fMat);
             tmp.setTypeMask(kUnknown_Mask);
-        } else {    // not perspective
+        } else {
             tmp.fMat[kMScaleX] = muladdmul(a.fMat[kMScaleX],
                                            b.fMat[kMScaleX],
                                            a.fMat[kMSkewX],
@@ -640,9 +622,7 @@ void SkMatrix::setConcat(const SkMatrix& a, const SkMatrix& b) {
             tmp.fMat[kMTransX] = muladdmul(a.fMat[kMScaleX],
                                            b.fMat[kMTransX],
                                            a.fMat[kMSkewX],
-                                           b.fMat[kMTransY]);
-
-            tmp.fMat[kMTransX] += a.fMat[kMTransX];
+                                           b.fMat[kMTransY]) + a.fMat[kMTransX];
 
             tmp.fMat[kMSkewY]  = muladdmul(a.fMat[kMSkewY],
                                            b.fMat[kMScaleX],
@@ -657,10 +637,10 @@ void SkMatrix::setConcat(const SkMatrix& a, const SkMatrix& b) {
             tmp.fMat[kMTransY] = muladdmul(a.fMat[kMSkewY],
                                            b.fMat[kMTransX],
                                            a.fMat[kMScaleY],
-                                           b.fMat[kMTransY]);
+                                           b.fMat[kMTransY]) + a.fMat[kMTransY];
 
-            tmp.fMat[kMTransY] += a.fMat[kMTransY];
-            tmp.fMat[kMPersp0] = tmp.fMat[kMPersp1] = 0;
+            tmp.fMat[kMPersp0] = 0;
+            tmp.fMat[kMPersp1] = 0;
             tmp.fMat[kMPersp2] = 1;
             //SkDebugf("Concat mat non-persp type: %d\n", tmp.getType());
             //SkASSERT(!(tmp.getType() & kPerspective_Mask));