Bug 1025553, part 6 - Remove gfxMatrix::Multiply(). r=Bas
authorJonathan Watt <jwatt@jwatt.org>
Fri, 11 Jul 2014 08:07:07 +0100
changeset 214345 fb2ab91ddd34477e3e00eabee861935e3d5c6b5f
parent 214344 2d724821fb523fa3e67692e1eaf1a74979f49866
child 214346 b336c6598bf14dc67ccc9c2d8989964adcbde5a8
push id3857
push userraliiev@mozilla.com
push dateTue, 02 Sep 2014 16:39:23 +0000
treeherdermozilla-beta@5638b907b505 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBas
bugs1025553
milestone33.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1025553, part 6 - Remove gfxMatrix::Multiply(). r=Bas
gfx/thebes/gfxDrawable.cpp
gfx/thebes/gfxMatrix.cpp
gfx/thebes/gfxMatrix.h
gfx/thebes/gfxUtils.cpp
image/src/ClippedImage.cpp
image/src/RasterImage.cpp
image/src/imgFrame.cpp
layout/svg/SVGTextFrame.cpp
layout/svg/nsSVGGradientFrame.cpp
layout/svg/nsSVGIntegrationUtils.cpp
layout/svg/nsSVGUtils.cpp
--- a/gfx/thebes/gfxDrawable.cpp
+++ b/gfx/thebes/gfxDrawable.cpp
@@ -52,17 +52,17 @@ DeviceToImageTransform(gfxContext* aCont
     nsRefPtr<gfxASurface> currentTarget =
         aContext->CurrentSurface(&deviceX, &deviceY);
     gfxMatrix currentMatrix = aContext->CurrentMatrix();
     gfxMatrix deviceToUser = currentMatrix;
     if (!deviceToUser.Invert()) {
         return gfxMatrix(0, 0, 0, 0, 0, 0); // singular
     }
     deviceToUser.Translate(-gfxPoint(-deviceX, -deviceY));
-    return gfxMatrix(deviceToUser).Multiply(aUserSpaceToImageSpace);
+    return deviceToUser * aUserSpaceToImageSpace;
 }
 
 static void
 PreparePatternForUntiledDrawing(gfxPattern* aPattern,
                                 const gfxMatrix& aDeviceToImage,
                                 gfxASurface *currentTarget,
                                 const GraphicsFilter aDefaultFilter)
 {
@@ -154,17 +154,17 @@ gfxSurfaceDrawable::Draw(gfxContext* aCo
           filter = GraphicsFilter::FILTER_FAST;
         }
         nsRefPtr<gfxASurface> currentTarget = aContext->CurrentSurface();
         gfxMatrix deviceSpaceToImageSpace =
             DeviceToImageTransform(aContext, aTransform);
         PreparePatternForUntiledDrawing(pattern, deviceSpaceToImageSpace,
                                         currentTarget, filter);
     }
-    pattern->SetMatrix(gfxMatrix(aTransform).Multiply(mTransform));
+    pattern->SetMatrix(aTransform * mTransform);
     aContext->NewPath();
     aContext->SetPattern(pattern);
     aContext->Rectangle(aFillRect);
     aContext->Fill();
     // clear the pattern so that the snapshot is released before the
     // drawable is destroyed
     aContext->SetDeviceColor(gfxRGBA(0.0, 0.0, 0.0, 0.0));
     return true;
@@ -292,15 +292,15 @@ gfxPatternDrawable::Draw(gfxContext* aCo
         // will happen through this Draw() method with aRepeat = false.
         nsRefPtr<gfxCallbackDrawable> callbackDrawable = MakeCallbackDrawable();
         return callbackDrawable->Draw(aContext, aFillRect, true, aFilter,
                                       aTransform);
     }
 
     aContext->NewPath();
     gfxMatrix oldMatrix = mPattern->GetMatrix();
-    mPattern->SetMatrix(gfxMatrix(aTransform).Multiply(oldMatrix));
+    mPattern->SetMatrix(aTransform * oldMatrix);
     aContext->SetPattern(mPattern);
     aContext->Rectangle(aFillRect);
     aContext->Fill();
     mPattern->SetMatrix(oldMatrix);
     return true;
 }
--- a/gfx/thebes/gfxMatrix.cpp
+++ b/gfx/thebes/gfxMatrix.cpp
@@ -40,17 +40,17 @@ gfxMatrix::Translate(const gfxPoint& pt)
 const gfxMatrix&
 gfxMatrix::Rotate(gfxFloat radians)
 {
     cairo_matrix_rotate(CAIRO_MATRIX(this), radians);
     return *this;
 }
 
 const gfxMatrix&
-gfxMatrix::Multiply(const gfxMatrix& m)
+gfxMatrix::operator *= (const gfxMatrix& m)
 {
     cairo_matrix_multiply(CAIRO_MATRIX(this), CAIRO_MATRIX(this), CONST_CAIRO_MATRIX(&m));
     return *this;
 }
 
 const gfxMatrix&
 gfxMatrix::PreMultiply(const gfxMatrix& m)
 {
--- a/gfx/thebes/gfxMatrix.h
+++ b/gfx/thebes/gfxMatrix.h
@@ -48,25 +48,23 @@ public:
     gfxMatrix(gfxFloat a, gfxFloat b, gfxFloat c, gfxFloat d, gfxFloat tx, gfxFloat ty) :
         _11(a),  _12(b),
         _21(c),  _22(d),
         _31(tx), _32(ty) { }
 
     /**
      * Post-multiplies m onto the matrix.
      */
-    const gfxMatrix& operator *= (const gfxMatrix& m) {
-        return Multiply(m);
-    }
+    const gfxMatrix& operator *= (const gfxMatrix& m);
 
     /**
      * Multiplies *this with m and returns the result.
      */
     gfxMatrix operator * (const gfxMatrix& m) const {
-        return gfxMatrix(*this).Multiply(m);
+        return gfxMatrix(*this) *= m;
     }
 
     /* Returns true if the other matrix is fuzzy-equal to this matrix.
      * Note that this isn't a cheap comparison!
      */
     bool operator==(const gfxMatrix& other) const
     {
       return FuzzyEqual(_11, other._11) && FuzzyEqual(_12, other._12) &&
@@ -123,25 +121,16 @@ public:
     /**
      * Rotates this matrix. The rotation is pre-multiplied onto this matrix,
      * i.e. the translation takes place after the other transformations.
      *
      * @param radians Angle in radians.
      */
     const gfxMatrix& Rotate(gfxFloat radians);
 
-     /**
-      * Multiplies the current matrix with m.
-      * This is a post-multiplication, i.e. the transformations of m are
-      * applied _after_ the existing transformations.
-      *
-      * XXX is that difference (compared to Rotate etc) a good thing?
-      */
-    const gfxMatrix& Multiply(const gfxMatrix& m);
-
     /**
      * Multiplies the current matrix with m.
      * This is a pre-multiplication, i.e. the transformations of m are
      * applied _before_ the existing transformations.
      */
     const gfxMatrix& PreMultiply(const gfxMatrix& m);
 
     static gfxMatrix Translation(gfxFloat aX, gfxFloat aY)
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -496,17 +496,17 @@ DeviceToImageTransform(gfxContext* aCont
     nsRefPtr<gfxASurface> currentTarget =
         aContext->CurrentSurface(&deviceX, &deviceY);
     gfxMatrix currentMatrix = aContext->CurrentMatrix();
     gfxMatrix deviceToUser = currentMatrix;
     if (!deviceToUser.Invert()) {
         return gfxMatrix(0, 0, 0, 0, 0, 0); // singular
     }
     deviceToUser.Translate(-gfxPoint(-deviceX, -deviceY));
-    return gfxMatrix(deviceToUser).Multiply(aUserSpaceToImageSpace);
+    return deviceToUser * aUserSpaceToImageSpace;
 }
 
 /* These heuristics are based on Source/WebCore/platform/graphics/skia/ImageSkia.cpp:computeResamplingMode() */
 #ifdef MOZ_GFX_OPTIMIZE_MOBILE
 static GraphicsFilter ReduceResamplingFilter(GraphicsFilter aFilter,
                                              int aImgWidth, int aImgHeight,
                                              float aSourceWidth, float aSourceHeight)
 {
--- a/image/src/ClippedImage.cpp
+++ b/image/src/ClippedImage.cpp
@@ -383,29 +383,28 @@ ClippedImage::DrawSingleTile(gfxContext*
   if (NS_SUCCEEDED(InnerImage()->GetWidth(&imgWidth)) &&
       NS_SUCCEEDED(InnerImage()->GetHeight(&imgHeight))) {
     viewportSize = nsIntSize(imgWidth, imgHeight);
   } else {
     MOZ_ASSERT(false, "If ShouldClip() led us to draw then we should never get here");
   }
 
   // Add a translation to the transform to reflect the clipping region.
-  gfxMatrix transform(aUserSpaceToImageSpace);
-  transform.Multiply(gfxMatrix().Translate(gfxPoint(mClip.x, mClip.y)));
+  gfxMatrix transform =
+    aUserSpaceToImageSpace * gfxMatrix::Translation(mClip.x, mClip.y);
 
   // "Clamp the source rectangle" to the clipping region's width and height.
   // Really, this means modifying the transform to get the results we want.
   gfxRect sourceRect = transform.Transform(aFill);
   if (sourceRect.width > mClip.width || sourceRect.height > mClip.height) {
-    gfxMatrix clampSource;
-    clampSource.Translate(gfxPoint(sourceRect.x, sourceRect.y));
+    gfxMatrix clampSource = gfxMatrix::Translation(sourceRect.TopLeft());
     clampSource.Scale(ClampFactor(sourceRect.width, mClip.width),
                       ClampFactor(sourceRect.height, mClip.height));
-    clampSource.Translate(gfxPoint(-sourceRect.x, -sourceRect.y));
-    transform.Multiply(clampSource);
+    clampSource.Translate(-sourceRect.TopLeft());
+    transform *= clampSource;
   }
 
   return InnerImage()->Draw(aContext, aFilter, transform, aFill, aSubimage,
                             viewportSize, aSVGContext, aWhichFrame, aFlags);
 }
 
 NS_IMETHODIMP
 ClippedImage::RequestDiscard()
--- a/image/src/RasterImage.cpp
+++ b/image/src/RasterImage.cpp
@@ -2618,18 +2618,17 @@ RasterImage::DrawWithPreDownscaleIfNeede
     // for each RasterImage.
     bool needScaleReq;
     if (mScaleResult.status == SCALE_DONE && mScaleResult.scale == scale) {
       // Grab and hold the surface to make sure the OS didn't destroy it
       surf = mScaleResult.frame->GetSurface();
       needScaleReq = !surf;
       if (surf) {
         frame = mScaleResult.frame;
-        userSpaceToImageSpace.Multiply(gfxMatrix().Scale(scale.width,
-                                                         scale.height));
+        userSpaceToImageSpace *= gfxMatrix::Scaling(scale.width, scale.height);
 
         // Since we're switching to a scaled image, we need to transform the
         // area of the subimage to draw accordingly, since imgFrame::Draw()
         // doesn't know about scaled frames.
         subimage.ScaleRoundOut(scale.width, scale.height);
       }
     } else {
       needScaleReq = !(mScaleResult.status == SCALE_PENDING &&
--- a/image/src/imgFrame.cpp
+++ b/image/src/imgFrame.cpp
@@ -360,17 +360,17 @@ imgFrame::SurfaceForDrawing(bool        
   // padding and/or a partial decode just by twiddling parameters.
   // First, update our user-space fill rect.
   aSourceRect = aSourceRect.Intersect(available);
   gfxMatrix imageSpaceToUserSpace = aUserSpaceToImageSpace;
   imageSpaceToUserSpace.Invert();
   aFill = imageSpaceToUserSpace.Transform(aSourceRect);
 
   aSubimage = aSubimage.Intersect(available) - gfxPoint(aPadding.left, aPadding.top);
-  aUserSpaceToImageSpace.Multiply(gfxMatrix().Translate(-gfxPoint(aPadding.left, aPadding.top)));
+  aUserSpaceToImageSpace *= gfxMatrix::Translation(-aPadding.left, -aPadding.top);
   aSourceRect = aSourceRect - gfxPoint(aPadding.left, aPadding.top);
   aImageRect = gfxRect(0, 0, mSize.width, mSize.height);
 
   gfxIntSize availableSize(mDecoded.width, mDecoded.height);
   return SurfaceWithFormat(new gfxSurfaceDrawable(aSurface, availableSize),
                            mFormat);
 }
 
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -970,17 +970,17 @@ TextRenderedRun::GetUserSpaceRect(nsPres
                                   const gfxMatrix* aAdditionalTransform) const
 {
   SVGBBox r = GetRunUserSpaceRect(aContext, aFlags);
   if (r.IsEmpty()) {
     return r;
   }
   gfxMatrix m = GetTransformFromRunUserSpaceToUserSpace(aContext);
   if (aAdditionalTransform) {
-    m.Multiply(*aAdditionalTransform);
+    m *= *aAdditionalTransform;
   }
   return m.TransformBounds(r.ToThebesRect());
 }
 
 void
 TextRenderedRun::GetClipEdges(nscoord& aLeftEdge, nscoord& aRightEdge) const
 {
   uint32_t contentLength = mFrame->GetContentLength();
@@ -3589,18 +3589,17 @@ SVGTextFrame::PaintSVG(nsRenderingContex
   }
 
   gfxMatrix canvasTM = GetCanvasTM(FOR_PAINTING, aTransformRoot);
   if (canvasTM.IsSingular()) {
     NS_WARNING("Can't render text element!");
     return NS_ERROR_FAILURE;
   }
 
-  gfxMatrix matrixForPaintServers(canvasTM);
-  matrixForPaintServers.Multiply(initialMatrix);
+  gfxMatrix matrixForPaintServers = canvasTM * initialMatrix;
 
   // Check if we need to draw anything.
   if (aDirtyRect) {
     NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() ||
                  (mState & NS_FRAME_IS_NONDISPLAY),
                  "Display lists handle dirty rect intersection test");
     nsRect dirtyRect(aDirtyRect->x, aDirtyRect->y,
                      aDirtyRect->width, aDirtyRect->height);
@@ -3653,18 +3652,18 @@ SVGTextFrame::PaintSVG(nsRenderingContex
     nsAutoPtr<gfxTextContextPaint> contextPaint;
     DrawMode drawMode =
       SetupCairoState(gfx, frame, outerContextPaint,
                       getter_Transfers(contextPaint));
 
     // Set up the transform for painting the text frame for the substring
     // indicated by the run.
     gfxMatrix runTransform =
-      run.GetTransformFromUserSpaceForPainting(presContext, item);
-    runTransform.Multiply(currentMatrix);
+      run.GetTransformFromUserSpaceForPainting(presContext, item) *
+      currentMatrix;
     gfx->SetMatrix(runTransform);
 
     if (drawMode != DrawMode(0)) {
       nsRect frameRect = frame->GetVisualOverflowRect();
       bool paintSVGGlyphs;
       if (ShouldRenderAsPath(aContext, frame, paintSVGGlyphs)) {
         SVGTextDrawPathCallbacks callbacks(aContext, frame,
                                            matrixForPaintServers,
@@ -3713,18 +3712,18 @@ SVGTextFrame::GetFrameForPoint(const nsP
   TextRenderedRunIterator it(this);
   nsIFrame* hit = nullptr;
   for (TextRenderedRun run = it.Current(); run.mFrame; run = it.Next()) {
     uint16_t hitTestFlags = nsSVGUtils::GetGeometryHitTestFlags(run.mFrame);
     if (!(hitTestFlags & (SVG_HIT_TEST_FILL | SVG_HIT_TEST_STROKE))) {
       continue;
     }
 
-    gfxMatrix m = GetCanvasTM(FOR_HIT_TESTING);
-    m.PreMultiply(run.GetTransformFromRunUserSpaceToUserSpace(presContext));
+    gfxMatrix m = run.GetTransformFromRunUserSpaceToUserSpace(presContext) *
+                    GetCanvasTM(FOR_HIT_TESTING);
     if (!m.Invert()) {
       return nullptr;
     }
 
     gfxPoint pointInRunUserSpace = m.Transform(pointInOuterSVGUserUnits);
     gfxRect frameRect =
       run.GetRunUserSpaceRect(presContext, TextRenderedRun::eIncludeFill |
                                            TextRenderedRun::eIncludeStroke).ToThebesRect();
@@ -5446,19 +5445,18 @@ SVGTextFrame::TransformFrameRectToTextCh
                              aChildFrame);
   for (TextRenderedRun run = it.Current(); run.mFrame; run = it.Next()) {
     // Convert the incoming rect into frame user space.
     gfxMatrix userSpaceToRunUserSpace =
       run.GetTransformFromRunUserSpaceToUserSpace(presContext);
     if (!userSpaceToRunUserSpace.Invert()) {
       return result;
     }
-    gfxMatrix m;
-    m.PreMultiply(userSpaceToRunUserSpace);
-    m.PreMultiply(run.GetTransformFromRunUserSpaceToFrameUserSpace(presContext));
+    gfxMatrix m = run.GetTransformFromRunUserSpaceToFrameUserSpace(presContext) *
+                    userSpaceToRunUserSpace;
     gfxRect incomingRectInFrameUserSpace =
       m.TransformBounds(incomingRectInUserSpace);
 
     // Intersect it with this run's rectangle.
     uint32_t flags = TextRenderedRun::eIncludeFill |
                      TextRenderedRun::eIncludeStroke;
     SVGBBox runRectInFrameUserSpace = run.GetFrameUserSpaceRect(presContext, flags);
     if (runRectInFrameUserSpace.IsEmpty()) {
--- a/layout/svg/nsSVGGradientFrame.cpp
+++ b/layout/svg/nsSVGGradientFrame.cpp
@@ -263,17 +263,17 @@ nsSVGGradientFrame::GetPaintServerPatter
   }
 
   // revert the vector effect transform so that the gradient appears unchanged
   if (aFillOrStroke == &nsStyleSVG::mStroke) {
     gfxMatrix nonScalingStrokeTM = nsSVGUtils::GetStrokeTransform(aSource);
     if (!nonScalingStrokeTM.Invert()) {
       return nullptr;
     }
-    patternMatrix.Multiply(nonScalingStrokeTM);
+    patternMatrix *= nonScalingStrokeTM;
   }
 
   if (!patternMatrix.Invert()) {
     return nullptr;
   }
 
   nsRefPtr<gfxPattern> gradient = CreateGradient();
   if (!gradient || gradient->CairoStatus())
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -706,18 +706,18 @@ nsSVGIntegrationUtils::DrawableFromPaint
 
     // pattern is now set up to fill aPaintServerSize. But we want it to
     // fill aRenderSize, so we need to add a scaling transform.
     // We couldn't just have set overrideBounds to aRenderSize - it would have
     // worked for gradients, but for patterns it would result in a different
     // pattern size.
     gfxFloat scaleX = overrideBounds.Width() / aRenderSize.width;
     gfxFloat scaleY = overrideBounds.Height() / aRenderSize.height;
-    gfxMatrix scaleMatrix = gfxMatrix().Scale(scaleX, scaleY);
-    pattern->SetMatrix(scaleMatrix.Multiply(pattern->GetMatrix()));
+    gfxMatrix scaleMatrix = gfxMatrix::Scaling(scaleX, scaleY);
+    pattern->SetMatrix(scaleMatrix * pattern->GetMatrix());
     nsRefPtr<gfxDrawable> drawable =
       new gfxPatternDrawable(pattern, aRenderSize);
     return drawable.forget();
   }
 
   // We don't want to paint into a surface as long as we don't need to, so we
   // set up a drawing callback.
   nsRefPtr<gfxDrawingCallback> cb =
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -1120,18 +1120,17 @@ static gfxRect
 PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
                               nsIFrame* aFrame,
                               double aStyleExpansionFactor,
                               const gfxMatrix& aMatrix)
 {
   double style_expansion =
     aStyleExpansionFactor * nsSVGUtils::GetStrokeWidth(aFrame);
 
-  gfxMatrix matrix = aMatrix;
-  matrix.Multiply(nsSVGUtils::GetStrokeTransform(aFrame));
+  gfxMatrix matrix = aMatrix * nsSVGUtils::GetStrokeTransform(aFrame);
 
   double dx = style_expansion * (fabs(matrix._11) + fabs(matrix._21));
   double dy = style_expansion * (fabs(matrix._22) + fabs(matrix._12));
 
   gfxRect strokeExtents = aPathExtents;
   strokeExtents.Inflate(dx, dy);
   return strokeExtents;
 }