Bug 681858 - Improve performance of gfx3DMatrix multiplication by reverting to 2d operations where possible. r=derf

This commit is contained in:
Matt Woodrow 2011-08-27 12:07:05 +12:00
parent f9d4b0bc4e
commit fd0bfbd9fd
3 changed files with 65 additions and 9 deletions

View File

@ -54,6 +54,10 @@ gfx3DMatrix::gfx3DMatrix(void)
gfx3DMatrix
gfx3DMatrix::operator*(const gfx3DMatrix &aMatrix) const
{
if (Is2D() && aMatrix.Is2D()) {
return Multiply2D(aMatrix);
}
gfx3DMatrix matrix;
matrix._11 = _11 * aMatrix._11 + _12 * aMatrix._21 + _13 * aMatrix._31 + _14 * aMatrix._41;
@ -82,6 +86,21 @@ gfx3DMatrix::operator*=(const gfx3DMatrix &aMatrix)
return *this = *this * aMatrix;
}
gfx3DMatrix
gfx3DMatrix::Multiply2D(const gfx3DMatrix &aMatrix) const
{
gfx3DMatrix matrix;
matrix._11 = _11 * aMatrix._11 + _12 * aMatrix._21;
matrix._21 = _21 * aMatrix._11 + _22 * aMatrix._21;
matrix._41 = _41 * aMatrix._11 + _42 * aMatrix._21 + aMatrix._41;
matrix._12 = _11 * aMatrix._12 + _12 * aMatrix._22;
matrix._22 = _21 * aMatrix._12 + _22 * aMatrix._22;
matrix._42 = _41 * aMatrix._12 + _42 * aMatrix._22 + aMatrix._42;
return matrix;
}
bool
gfx3DMatrix::operator==(const gfx3DMatrix& o) const
{
@ -145,6 +164,23 @@ gfx3DMatrix::Translate(const gfxPoint3D& aPoint)
_44 += aPoint.x * _14 + aPoint.y * _24 + aPoint.z * _34;
}
void
gfx3DMatrix::TranslatePost(const gfxPoint3D& aPoint)
{
_11 += _14 * aPoint.x;
_21 += _24 * aPoint.x;
_31 += _34 * aPoint.x;
_41 += _44 * aPoint.x;
_12 += _14 * aPoint.y;
_22 += _24 * aPoint.y;
_32 += _34 * aPoint.y;
_42 += _44 * aPoint.y;
_13 += _14 * aPoint.z;
_23 += _24 * aPoint.z;
_33 += _34 * aPoint.z;
_43 += _44 * aPoint.z;
}
void
gfx3DMatrix::SkewXY(float aSkew)
{
@ -460,7 +496,7 @@ gfx3DMatrix::TransformBounds(const gfxRect& rect) const
}
PRBool
gfx3DMatrix::Is2D(gfxMatrix* aMatrix) const
gfx3DMatrix::Is2D() const
{
if (_13 != 0.0f || _14 != 0.0f ||
_23 != 0.0f || _24 != 0.0f ||
@ -468,6 +504,15 @@ gfx3DMatrix::Is2D(gfxMatrix* aMatrix) const
_43 != 0.0f || _44 != 1.0f) {
return PR_FALSE;
}
return PR_TRUE;
}
PRBool
gfx3DMatrix::Is2D(gfxMatrix* aMatrix) const
{
if (!Is2D()) {
return PR_FALSE;
}
if (aMatrix) {
aMatrix->xx = _11;
aMatrix->yx = _12;

View File

@ -106,7 +106,8 @@ public:
* (i.e. as obtained by From2D). If it is, optionally returns the 2D
* matrix in aMatrix.
*/
PRBool Is2D(gfxMatrix* aMatrix = nsnull) const;
PRBool Is2D(gfxMatrix* aMatrix) const;
PRBool Is2D() const;
/**
* Returns true if the matrix can be reduced to a 2D affine transformation
@ -132,6 +133,13 @@ public:
*/
void Translate(const gfxPoint3D& aPoint);
/**
* Add a translation by aPoint after the matrix.
* This is functionally equivalent to:
* matrix *gfx3DMatrix::Translation(aPoint)
*/
void TranslatePost(const gfxPoint3D& aPoint);
void SkewXY(float aSkew);
void SkewXZ(float aSkew);
void SkewYZ(float aSkew);
@ -231,6 +239,8 @@ private:
gfxFloat Determinant3x3() const;
gfx3DMatrix Inverse3x3() const;
gfx3DMatrix Multiply2D(const gfx3DMatrix &aMatrix) const;
public:
/** Matrix elements */

View File

@ -1008,14 +1008,15 @@ gfx3DMatrix
nsLayoutUtils::ChangeMatrixBasis(const gfxPoint3D &aOrigin,
const gfx3DMatrix &aMatrix)
{
/* These are translation matrices from world-to-origin of relative frame and
* vice-versa.
*/
gfx3DMatrix worldToOrigin = gfx3DMatrix::Translation(-aOrigin);
gfx3DMatrix originToWorld = gfx3DMatrix::Translation(aOrigin);
gfx3DMatrix result = aMatrix;
/* Multiply all three to get the transform! */
return worldToOrigin * aMatrix * originToWorld;
/* Translate to the origin before aMatrix */
result.Translate(-aOrigin);
/* Translate back into position after aMatrix */
result.TranslatePost(aOrigin);
return result;
}
/**