Backed out changeset 318fa507832d (bug 1073086)
authorEd Morley <emorley@mozilla.com>
Mon, 29 Sep 2014 17:42:34 +0100
changeset 207714 8d578891aa895100ab0f5cf312b13a9313ff5860
parent 207713 318fa507832d7fa368612ff20ebf891e084fdfc0
child 207715 da12cd0ebe40db3492857c4067b77c662ac0bf0c
push id27564
push userryanvm@gmail.com
push dateMon, 29 Sep 2014 18:57:04 +0000
treeherdermozilla-central@ce9a0b34225e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1073086
milestone35.0a1
backs out318fa507832d7fa368612ff20ebf891e084fdfc0
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
Backed out changeset 318fa507832d (bug 1073086)
gfx/layers/RotatedBuffer.cpp
gfx/thebes/gfxUtils.cpp
gfx/thebes/gfxUtils.h
--- a/gfx/layers/RotatedBuffer.cpp
+++ b/gfx/layers/RotatedBuffer.cpp
@@ -224,17 +224,17 @@ RotatedContentBuffer::DrawTo(PaintedLaye
       (ToData(aLayer)->GetClipToVisibleRegion() &&
        !aLayer->GetVisibleRegion().Contains(BufferRect())) ||
       IsClippingCheap(aTarget, aLayer->GetEffectiveVisibleRegion())) {
     // We don't want to draw invalid stuff, so we need to clip. Might as
     // well clip to the smallest area possible --- the visible region.
     // Bug 599189 if there is a non-integer-translation transform in aTarget,
     // we might sample pixels outside GetEffectiveVisibleRegion(), which is wrong
     // and may cause gray lines.
-    gfxUtils::ClipToRegion(aTarget, aLayer->GetEffectiveVisibleRegion());
+    gfxUtils::ClipToRegionSnapped(aTarget, aLayer->GetEffectiveVisibleRegion());
     clipped = true;
   }
 
   DrawBufferWithRotation(aTarget, BUFFER_BLACK, aOpacity, aOp, aMask, aMaskTransform);
   if (clipped) {
     aTarget->PopClip();
   }
 }
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -659,66 +659,95 @@ static void
 ClipToRegionInternal(gfxContext* aContext, const nsIntRegion& aRegion,
                      bool aSnap)
 {
   PathFromRegionInternal(aContext, aRegion, aSnap);
   aContext->Clip();
 }
 
 static TemporaryRef<Path>
-PathFromRegionInternal(DrawTarget* aTarget, const nsIntRegion& aRegion)
+PathFromRegionInternal(DrawTarget* aTarget, const nsIntRegion& aRegion,
+                       bool aSnap)
 {
   Matrix mat = aTarget->GetTransform();
+  const gfxFloat epsilon = 0.000001;
+#define WITHIN_E(a,b) (fabs((a)-(b)) < epsilon)
+  // We're essentially duplicating the logic in UserToDevicePixelSnapped here.
+  bool shouldNotSnap = !aSnap || (WITHIN_E(mat._11,1.0) &&
+                                  WITHIN_E(mat._22,1.0) &&
+                                  WITHIN_E(mat._12,0.0) &&
+                                  WITHIN_E(mat._21,0.0));
+#undef WITHIN_E
 
   RefPtr<PathBuilder> pb = aTarget->CreatePathBuilder();
   nsIntRegionRectIterator iter(aRegion);
 
   const nsIntRect* r;
-  while ((r = iter.Next()) != nullptr) {
-    pb->MoveTo(Point(r->x, r->y));
-    pb->LineTo(Point(r->XMost(), r->y));
-    pb->LineTo(Point(r->XMost(), r->YMost()));
-    pb->LineTo(Point(r->x, r->YMost()));
-    pb->Close();
+  if (shouldNotSnap) {
+    while ((r = iter.Next()) != nullptr) {
+      pb->MoveTo(Point(r->x, r->y));
+      pb->LineTo(Point(r->XMost(), r->y));
+      pb->LineTo(Point(r->XMost(), r->YMost()));
+      pb->LineTo(Point(r->x, r->YMost()));
+      pb->Close();
+    }
+  } else {
+    while ((r = iter.Next()) != nullptr) {
+      Rect rect(r->x, r->y, r->width, r->height);
+
+      rect.Round();
+      pb->MoveTo(rect.TopLeft());
+      pb->LineTo(rect.TopRight());
+      pb->LineTo(rect.BottomRight());
+      pb->LineTo(rect.BottomLeft());
+      pb->Close();
+    }
   }
   RefPtr<Path> path = pb->Finish();
   return path;
 }
 
 static void
-ClipToRegionInternal(DrawTarget* aTarget, const nsIntRegion& aRegion)
+ClipToRegionInternal(DrawTarget* aTarget, const nsIntRegion& aRegion,
+                     bool aSnap)
 {
   if (!aRegion.IsComplex()) {
     nsIntRect rect = aRegion.GetBounds();
     aTarget->PushClipRect(Rect(rect.x, rect.y, rect.width, rect.height));
     return;
   }
 
-  RefPtr<Path> path = PathFromRegionInternal(aTarget, aRegion);
+  RefPtr<Path> path = PathFromRegionInternal(aTarget, aRegion, aSnap);
   aTarget->PushClip(path);
 }
 
 /*static*/ void
 gfxUtils::ClipToRegion(gfxContext* aContext, const nsIntRegion& aRegion)
 {
   ClipToRegionInternal(aContext, aRegion, false);
 }
 
 /*static*/ void
 gfxUtils::ClipToRegion(DrawTarget* aTarget, const nsIntRegion& aRegion)
 {
-  ClipToRegionInternal(aTarget, aRegion);
+  ClipToRegionInternal(aTarget, aRegion, false);
 }
 
 /*static*/ void
 gfxUtils::ClipToRegionSnapped(gfxContext* aContext, const nsIntRegion& aRegion)
 {
   ClipToRegionInternal(aContext, aRegion, true);
 }
 
+/*static*/ void
+gfxUtils::ClipToRegionSnapped(DrawTarget* aTarget, const nsIntRegion& aRegion)
+{
+  ClipToRegionInternal(aTarget, aRegion, true);
+}
+
 /*static*/ gfxFloat
 gfxUtils::ClampToScaleFactor(gfxFloat aVal)
 {
   // Arbitary scale factor limitation. We can increase this
   // for better scaling performance at the cost of worse
   // quality.
   static const gfxFloat kScaleResolution = 2;
 
--- a/gfx/thebes/gfxUtils.h
+++ b/gfx/thebes/gfxUtils.h
@@ -95,16 +95,21 @@ public:
     static void ClipToRegion(mozilla::gfx::DrawTarget* aTarget, const nsIntRegion& aRegion);
 
     /**
      * Clip aContext to the region aRegion, snapping the rectangles.
      */
     static void ClipToRegionSnapped(gfxContext* aContext, const nsIntRegion& aRegion);
 
     /**
+     * Clip aTarget to the region aRegion, snapping the rectangles.
+     */
+    static void ClipToRegionSnapped(mozilla::gfx::DrawTarget* aTarget, const nsIntRegion& aRegion);
+
+    /**
      * Create a path consisting of rectangles in |aRegion|.
      */
     static void PathFromRegion(gfxContext* aContext, const nsIntRegion& aRegion);
 
     /**
      * Create a path consisting of rectangles in |aRegion|, snapping the rectangles.
      */
     static void PathFromRegionSnapped(gfxContext* aContext, const nsIntRegion& aRegion);