Bug 1507021. Add a SnappedClip function to gfxContext. r=mattwoodrow
authorJeff Muizelaar <jrmuizel@gmail.com>
Tue, 13 Nov 2018 19:17:03 -0500
changeset 503698 7825009998ae5d5bebef3096a332918ed18defb6
parent 503697 3fee9c5dc2c258a40f542cf5040b46447d1cffa8
child 503699 6beca6ad237ecb0d709350380c9b83003f5f577c
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1507021
milestone65.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 1507021. Add a SnappedClip function to gfxContext. r=mattwoodrow Differential Revision: https://phabricator.services.mozilla.com/D11839
gfx/layers/basic/BasicLayerManager.cpp
gfx/thebes/gfxContext.cpp
gfx/thebes/gfxContext.h
gfx/thebes/gfxTextRun.cpp
layout/mathml/nsMathMLChar.cpp
layout/painting/nsCSSRendering.cpp
--- a/gfx/layers/basic/BasicLayerManager.cpp
+++ b/gfx/layers/basic/BasicLayerManager.cpp
@@ -786,20 +786,18 @@ InstallLayerClipPreserves3D(gfxContext* 
   Matrix transform;
   if (!transform3d.CanDraw2D(&transform)) {
     gfxDevCrash(LogReason::CannotDraw3D) << "GFX: We should not have a 3D transform that CanDraw2D() is false!";
   }
   Matrix oldTransform = aTarget->CurrentMatrix();
   transform *= oldTransform;
   aTarget->SetMatrix(transform);
 
-  aTarget->NewPath();
-  aTarget->SnappedRectangle(gfxRect(clipRect->X(), clipRect->Y(),
-                                    clipRect->Width(), clipRect->Height()));
-  aTarget->Clip();
+  aTarget->SnappedClip(gfxRect(clipRect->X(), clipRect->Y(),
+                               clipRect->Width(), clipRect->Height()));
 
   aTarget->SetMatrix(oldTransform);
 }
 
 void
 BasicLayerManager::PaintLayer(gfxContext* aTarget,
                               Layer* aLayer,
                               DrawPaintedLayerCallback aCallback,
@@ -942,19 +940,17 @@ BasicLayerManager::PaintLayer(gfxContext
     if (xformSurf) {
       aTarget->SetPattern(
         new gfxPattern(xformSurf,
                        Matrix::Translation(xformBounds.TopLeft())));
 
       // Azure doesn't support EXTEND_NONE, so to avoid extending the edges
       // of the source surface out to the current clip region, clip to
       // the rectangle of the result surface now.
-      aTarget->NewPath();
-      aTarget->SnappedRectangle(ThebesRect(xformBounds));
-      aTarget->Clip();
+      aTarget->SnappedClip(ThebesRect(xformBounds));
       FlushGroup(paintLayerContext, needsClipToVisibleRegion);
     }
   }
 }
 
 void
 BasicLayerManager::ClearCachedResources(Layer* aSubtree)
 {
--- a/gfx/thebes/gfxContext.cpp
+++ b/gfx/thebes/gfxContext.cpp
@@ -296,16 +296,35 @@ gfxContext::Rectangle(const gfxRect& rec
 
   mPathBuilder->MoveTo(rec.TopLeft());
   mPathBuilder->LineTo(rec.TopRight());
   mPathBuilder->LineTo(rec.BottomRight());
   mPathBuilder->LineTo(rec.BottomLeft());
   mPathBuilder->Close();
 }
 
+void
+gfxContext::SnappedClip(const gfxRect& rect)
+{
+  Rect rec = ToRect(rect);
+
+  gfxRect newRect(rect);
+  if (UserToDevicePixelSnapped(newRect, true)) {
+    gfxMatrix mat = ThebesMatrix(mTransform);
+    if (mat.Invert()) {
+      // We need the user space rect.
+      rec = ToRect(mat.TransformBounds(newRect));
+    } else {
+      rec = Rect();
+    }
+  }
+
+  Clip(rec);
+}
+
 // transform stuff
 void
 gfxContext::Multiply(const gfxMatrix& matrix)
 {
   CURRENTSTATE_CHANGED()
   ChangeTransform(ToMatrix(matrix) * mTransform);
 }
 
--- a/gfx/thebes/gfxContext.h
+++ b/gfx/thebes/gfxContext.h
@@ -369,16 +369,17 @@ public:
     void Clip();
 
     /**
      * Helper functions that will create a rect path and call Clip().
      * Any current path will be destroyed by these functions!
      */
     void Clip(const Rect& rect);
     void Clip(const gfxRect& rect); // will clip to a rect
+    void SnappedClip(const gfxRect& rect); // snap rect and clip to the result
     void Clip(Path* aPath);
 
     void PopClip();
 
     enum ClipExtentsSpace {
         eUserSpace = 0,
         eDeviceSpace = 1,
     };
--- a/gfx/thebes/gfxTextRun.cpp
+++ b/gfx/thebes/gfxTextRun.cpp
@@ -556,22 +556,20 @@ struct MOZ_STACK_CLASS BufferAlphaColor 
 
     }
 
     ~BufferAlphaColor() {}
 
     void PushSolidColor(const gfxRect& aBounds, const Color& aAlphaColor, uint32_t appsPerDevUnit)
     {
         mContext->Save();
-        mContext->NewPath();
-        mContext->SnappedRectangle(gfxRect(aBounds.X() / appsPerDevUnit,
+        mContext->SnappedClip(gfxRect(aBounds.X() / appsPerDevUnit,
                     aBounds.Y() / appsPerDevUnit,
                     aBounds.Width() / appsPerDevUnit,
                     aBounds.Height() / appsPerDevUnit));
-        mContext->Clip();
         mContext->SetColor(Color(aAlphaColor.r, aAlphaColor.g, aAlphaColor.b));
         mContext->PushGroupForBlendBack(gfxContentType::COLOR_ALPHA, aAlphaColor.a);
     }
 
     void PopAlpha()
     {
         // pop the text, using the color alpha as the opacity
         mContext->PopGroupAndBlend();
--- a/layout/mathml/nsMathMLChar.cpp
+++ b/layout/mathml/nsMathMLChar.cpp
@@ -2111,20 +2111,18 @@ nsMathMLChar::PaintForeground(nsIFrame* 
 
 class AutoPushClipRect {
   gfxContext* mThebesContext;
 public:
   AutoPushClipRect(gfxContext* aThebesContext, int32_t aAppUnitsPerGfxUnit,
                    const nsRect& aRect)
     : mThebesContext(aThebesContext) {
     mThebesContext->Save();
-    mThebesContext->NewPath();
     gfxRect clip = nsLayoutUtils::RectToGfxRect(aRect, aAppUnitsPerGfxUnit);
-    mThebesContext->SnappedRectangle(clip);
-    mThebesContext->Clip();
+    mThebesContext->SnappedClip(clip);
   }
   ~AutoPushClipRect() {
     mThebesContext->Restore();
   }
 };
 
 static nsPoint
 SnapToDevPixels(const gfxContext* aThebesContext, int32_t aAppUnitsPerGfxUnit,
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -2537,19 +2537,17 @@ SetupImageLayerClip(nsCSSRendering::Imag
 
   if (aClipState.mHasAdditionalBGClipArea) {
     gfxRect bgAreaGfx = nsLayoutUtils::RectToGfxRect(
       aClipState.mAdditionalBGClipArea, aAppUnitsPerPixel);
     bgAreaGfx.Round();
     gfxUtils::ConditionRect(bgAreaGfx);
 
     aAutoSR->EnsureSaved(aCtx);
-    aCtx->NewPath();
-    aCtx->SnappedRectangle(bgAreaGfx);
-    aCtx->Clip();
+    aCtx->SnappedClip(bgAreaGfx);
   }
 
   if (aClipState.mHasRoundedCorners) {
     Rect bgAreaGfx = NSRectToRect(aClipState.mBGClipArea, aAppUnitsPerPixel);
     bgAreaGfx.Round();
 
     if (bgAreaGfx.IsEmpty()) {
       // I think it's become possible to hit this since
@@ -2600,28 +2598,24 @@ DrawBackgroundColor(nsCSSRendering::Imag
     // Make our caller not do anything.
     aClipState.mDirtyRectInDevPx.SizeTo(gfxSize(0.0, 0.0));
     return;
   }
 
   aCtx->Save();
   gfxRect dirty = ThebesRect(bgAreaGfx).Intersect(aClipState.mDirtyRectInDevPx);
 
-  aCtx->NewPath();
-  aCtx->SnappedRectangle(dirty);
-  aCtx->Clip();
+  aCtx->SnappedClip(dirty);
 
   if (aClipState.mHasAdditionalBGClipArea) {
     gfxRect bgAdditionalAreaGfx = nsLayoutUtils::RectToGfxRect(
       aClipState.mAdditionalBGClipArea, aAppUnitsPerPixel);
     bgAdditionalAreaGfx.Round();
     gfxUtils::ConditionRect(bgAdditionalAreaGfx);
-    aCtx->NewPath();
-    aCtx->SnappedRectangle(bgAdditionalAreaGfx);
-    aCtx->Clip();
+    aCtx->SnappedClip(bgAdditionalAreaGfx);
   }
 
   RefPtr<Path> roundedRect =
     MakePathForRoundedRect(*drawTarget, bgAreaGfx, aClipState.mClippedRadii);
   aCtx->SetPath(roundedRect);
   aCtx->Fill();
   aCtx->Restore();
 }
@@ -2933,19 +2927,17 @@ nsCSSRendering::PaintStyleImageLayerWith
           currentLayerClipState, &aRenderingCtx, appUnitsPerPixel, &autoSR);
         if (!clipBorderArea.IsEqualEdges(aParams.borderArea)) {
           // We're drawing the background for the joined continuation boxes
           // so we need to clip that to the slice that we want for this
           // frame.
           gfxRect clip =
             nsLayoutUtils::RectToGfxRect(aParams.borderArea, appUnitsPerPixel);
           autoSR.EnsureSaved(&aRenderingCtx);
-          aRenderingCtx.NewPath();
-          aRenderingCtx.SnappedRectangle(clip);
-          aRenderingCtx.Clip();
+          aRenderingCtx.SnappedClip(clip);
         }
       }
     }
 
     // Skip the following layer preparing and painting code if the current
     // layer is not selected for drawing.
     if (aParams.layer >= 0 && i != (uint32_t)aParams.layer) {
       continue;