Title: [135038] trunk/Source/WebCore
Revision
135038
Author
benja...@webkit.org
Date
2012-11-16 22:26:56 -0800 (Fri, 16 Nov 2012)

Log Message

Improve the performance of rect transform
https://bugs.webkit.org/show_bug.cgi?id=101828

Patch by Benjamin Poulain <bpoul...@apple.com> on 2012-11-16
Reviewed by Simon Fraser.

Mapping a rect and a quad by a transform is a common operation because
we use it to recompute the repaint rect, overflow rect, etc.

The way it was done, is by transforming through mapRect()->mapQuad()->4 times mapPoint().
Each of those functions tests isIdentityOrTranslation() which has to read the whole matrix
and perform many comparison.
Because of that, the simple mapping of a rect was loading and checking the matrix 5 times
too many.

This patch just cut the intermediary calls.

On ARM, putting the operation together also has the advantage of loading the matrix
only once in registers and reusing it for every point.

* platform/graphics/transforms/TransformationMatrix.cpp:
(WebCore::TransformationMatrix::mapPoint):
(WebCore::TransformationMatrix::mapRect):
* platform/graphics/transforms/TransformationMatrix.h:
(WebCore):
(WebCore::TransformationMatrix::mapPointImpl): New convenience function to perform the
point project without doing isIdentityOrTranslation().

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (135037 => 135038)


--- trunk/Source/WebCore/ChangeLog	2012-11-17 06:11:21 UTC (rev 135037)
+++ trunk/Source/WebCore/ChangeLog	2012-11-17 06:26:56 UTC (rev 135038)
@@ -1,3 +1,32 @@
+2012-11-16  Benjamin Poulain  <bpoul...@apple.com>
+
+        Improve the performance of rect transform
+        https://bugs.webkit.org/show_bug.cgi?id=101828
+
+        Reviewed by Simon Fraser.
+
+        Mapping a rect and a quad by a transform is a common operation because
+        we use it to recompute the repaint rect, overflow rect, etc.
+
+        The way it was done, is by transforming through mapRect()->mapQuad()->4 times mapPoint().
+        Each of those functions tests isIdentityOrTranslation() which has to read the whole matrix
+        and perform many comparison.
+        Because of that, the simple mapping of a rect was loading and checking the matrix 5 times
+        too many.
+
+        This patch just cut the intermediary calls.
+
+        On ARM, putting the operation together also has the advantage of loading the matrix
+        only once in registers and reusing it for every point.
+
+        * platform/graphics/transforms/TransformationMatrix.cpp:
+        (WebCore::TransformationMatrix::mapPoint):
+        (WebCore::TransformationMatrix::mapRect):
+        * platform/graphics/transforms/TransformationMatrix.h:
+        (WebCore):
+        (WebCore::TransformationMatrix::mapPointImpl): New convenience function to perform the
+        point project without doing isIdentityOrTranslation().
+
 2012-11-16  Simon Fraser  <simon.fra...@apple.com>
 
         Avoid calling the virtual isBlockFlow() in RenderBox::computeRectForRepaint()

Modified: trunk/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp (135037 => 135038)


--- trunk/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp	2012-11-17 06:11:21 UTC (rev 135037)
+++ trunk/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp	2012-11-17 06:26:56 UTC (rev 135038)
@@ -28,7 +28,6 @@
 #include "TransformationMatrix.h"
 
 #include "AffineTransform.h"
-#include "FloatPoint3D.h"
 #include "FloatRect.h"
 #include "FloatQuad.h"
 #include "IntRect.h"
@@ -647,9 +646,7 @@
     if (isIdentityOrTranslation())
         return FloatPoint(p.x() + static_cast<float>(m_matrix[3][0]), p.y() + static_cast<float>(m_matrix[3][1]));
 
-    double x, y;
-    multVecMatrix(p.x(), p.y(), x, y);
-    return FloatPoint(static_cast<float>(x), static_cast<float>(y));
+    return internalMapPoint(p);
 }
 
 FloatPoint3D TransformationMatrix::mapPoint(const FloatPoint3D& p) const
@@ -659,9 +656,7 @@
                             p.y() + static_cast<float>(m_matrix[3][1]),
                             p.z() + static_cast<float>(m_matrix[3][2]));
 
-    double x, y, z;
-    multVecMatrix(p.x(), p.y(), p.z(), x, y, z);
-    return FloatPoint3D(static_cast<float>(x), static_cast<float>(y), static_cast<float>(z));
+    return internalMapPoint(p);
 }
 
 IntRect TransformationMatrix::mapRect(const IntRect &rect) const
@@ -682,8 +677,16 @@
         return mappedRect;
     }
 
-    FloatQuad resultQuad = mapQuad(FloatQuad(r));
-    return resultQuad.boundingBox();
+    FloatQuad result;
+
+    float maxX = r.maxX();
+    float maxY = r.maxY();
+    result.setP1(internalMapPoint(FloatPoint(r.x(), r.y())));
+    result.setP2(internalMapPoint(FloatPoint(maxX, r.y())));
+    result.setP3(internalMapPoint(FloatPoint(maxX, maxY)));
+    result.setP4(internalMapPoint(FloatPoint(r.x(), maxY)));
+
+    return result.boundingBox();
 }
 
 FloatQuad TransformationMatrix::mapQuad(const FloatQuad& q) const
@@ -695,10 +698,10 @@
     }
 
     FloatQuad result;
-    result.setP1(mapPoint(q.p1()));
-    result.setP2(mapPoint(q.p2()));
-    result.setP3(mapPoint(q.p3()));
-    result.setP4(mapPoint(q.p4()));
+    result.setP1(internalMapPoint(q.p1()));
+    result.setP2(internalMapPoint(q.p2()));
+    result.setP3(internalMapPoint(q.p3()));
+    result.setP4(internalMapPoint(q.p4()));
     return result;
 }
 

Modified: trunk/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h (135037 => 135038)


--- trunk/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h	2012-11-17 06:11:21 UTC (rev 135037)
+++ trunk/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h	2012-11-17 06:26:56 UTC (rev 135038)
@@ -27,6 +27,7 @@
 #define TransformationMatrix_h
 
 #include "FloatPoint.h"
+#include "FloatPoint3D.h"
 #include "IntPoint.h"
 #include <string.h> //for memcpy
 #include <wtf/FastAllocBase.h>
@@ -65,7 +66,6 @@
 class AffineTransform;
 class IntRect;
 class LayoutRect;
-class FloatPoint3D;
 class FloatRect;
 class FloatQuad;
 
@@ -379,9 +379,24 @@
 private:
     // multiply passed 2D point by matrix (assume z=0)
     void multVecMatrix(double x, double y, double& dstX, double& dstY) const;
+    FloatPoint internalMapPoint(const FloatPoint& sourcePoint) const
+    {
+        double resultX;
+        double resultY;
+        multVecMatrix(sourcePoint.x(), sourcePoint.y(), resultX, resultY);
+        return FloatPoint(static_cast<float>(resultX), static_cast<float>(resultY));
+    }
 
     // multiply passed 3D point by matrix
     void multVecMatrix(double x, double y, double z, double& dstX, double& dstY, double& dstZ) const;
+    FloatPoint3D internalMapPoint(const FloatPoint3D& sourcePoint) const
+    {
+        double resultX;
+        double resultY;
+        double resultZ;
+        multVecMatrix(sourcePoint.x(), sourcePoint.y(), sourcePoint.z(), resultX, resultY, resultZ);
+        return FloatPoint3D(static_cast<float>(resultX), static_cast<float>(resultY), static_cast<float>(resultZ));
+    }
 
     void setMatrix(const Matrix4 m)
     {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to