Backed out 5 changesets (bug 962786, bug 952011) for svg test_text_selection.html bustage
authorPhil Ringnalda <philringnalda@gmail.com>
Tue, 28 Jan 2014 19:37:54 -0800
changeset 182692 91dd7ce4cfafa6f19dbc432d734995c6b6067fe6
parent 182691 3b88bcc4c3d4cf4bde110eb83d70810d5dd00a1c
child 182693 cb10967d98f2cfea9d3b9644cda3b6eb83573d54
child 182722 aa98ff644f896e25f1ae83c890c32452ce0a49d2
push id462
push userraliiev@mozilla.com
push dateTue, 22 Apr 2014 00:22:30 +0000
treeherdermozilla-release@ac5db8c74ac0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs962786, 952011
milestone29.0a1
backs outd7a6a64b42f0268cecb94026aa334fb3eb13304c
e50ced4f404083c4a90aac577c8e6cf56f17a27b
c9e6fd6d5a03bc6b9858d4935105aaca87ded8cc
406540ed9da060acf3398acb026bb0d045bc8032
d6f164b6421a800e2739b89d0c467c534e800801
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 5 changesets (bug 962786, bug 952011) for svg test_text_selection.html bustage CLOSED TREE Backed out changeset d7a6a64b42f0 (bug 962786) Backed out changeset e50ced4f4040 (bug 952011) Backed out changeset c9e6fd6d5a03 (bug 952011) Backed out changeset 406540ed9da0 (bug 952011) Backed out changeset d6f164b6421a (bug 962786)
gfx/thebes/gfx3DMatrix.cpp
gfx/thebes/gfx3DMatrix.h
layout/base/FrameLayerBuilder.cpp
layout/base/nsDisplayList.cpp
layout/base/nsDisplayList.h
layout/base/nsIPresShell.h
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/base/nsPresShell.cpp
layout/base/nsPresShell.h
widget/cocoa/nsDragService.mm
widget/gtk/nsDragService.cpp
widget/gtk/nsDragService.h
widget/gtk/nsImageToPixbuf.cpp
widget/gtk/nsImageToPixbuf.h
widget/windows/nsDragService.cpp
widget/xpwidgets/nsBaseDragService.cpp
widget/xpwidgets/nsBaseDragService.h
--- a/gfx/thebes/gfx3DMatrix.cpp
+++ b/gfx/thebes/gfx3DMatrix.cpp
@@ -783,19 +783,20 @@ gfxPoint gfx3DMatrix::ProjectPoint(const
   return result;
 }
 
 gfxRect gfx3DMatrix::ProjectRectBounds(const gfxRect& aRect) const
 {
   gfxPoint points[4];
 
   points[0] = ProjectPoint(aRect.TopLeft());
-  points[1] = ProjectPoint(aRect.TopRight());
-  points[2] = ProjectPoint(aRect.BottomLeft());
-  points[3] = ProjectPoint(aRect.BottomRight());
+  points[1] = ProjectPoint(gfxPoint(aRect.X() + aRect.Width(), aRect.Y()));
+  points[2] = ProjectPoint(gfxPoint(aRect.X(), aRect.Y() + aRect.Height()));
+  points[3] = ProjectPoint(gfxPoint(aRect.X() + aRect.Width(),
+                                    aRect.Y() + aRect.Height()));
 
   gfxFloat min_x, max_x;
   gfxFloat min_y, max_y;
 
   min_x = max_x = points[0].x;
   min_y = max_y = points[0].y;
 
   for (int i=1; i<4; i++) {
@@ -803,37 +804,16 @@ gfxRect gfx3DMatrix::ProjectRectBounds(c
     max_x = max(points[i].x, max_x);
     min_y = min(points[i].y, min_y);
     max_y = max(points[i].y, max_y);
   }
 
   return gfxRect(min_x, min_y, max_x - min_x, max_y - min_y);
 }
 
-gfxRect gfx3DMatrix::UntransformBounds(const gfxRect& aRect, const gfxRect& aChildBounds) const
-{
-  gfxRect bounds = TransformBounds(aChildBounds);
-
-  gfxRect rect = aRect.Intersect(bounds);
-
-  return Inverse().ProjectRectBounds(rect);
-}
-
-bool gfx3DMatrix::UntransformPoint(const gfxPoint& aPoint, const gfxRect& aChildBounds, gfxPoint* aOut) const
-{
-  gfxRect bounds = TransformBounds(aChildBounds);
-
-  if (!bounds.Contains(aPoint)) {
-    return false;
-  }
-
-  *aOut = Inverse().ProjectPoint(aPoint);
-  return true;
-}
-
 gfxPoint3D gfx3DMatrix::GetNormalVector() const
 {
   // Define a plane in transformed space as the transformations
   // of 3 points on the z=0 screen plane.
   gfxPoint3D a = Transform3D(gfxPoint3D(0, 0, 0));
   gfxPoint3D b = Transform3D(gfxPoint3D(0, 1, 0));
   gfxPoint3D c = Transform3D(gfxPoint3D(1, 0, 0));
 
--- a/gfx/thebes/gfx3DMatrix.h
+++ b/gfx/thebes/gfx3DMatrix.h
@@ -245,35 +245,16 @@ public:
    */
   gfxPoint3D Transform3D(const gfxPoint3D& point) const;
   gfxPointH3D Transform4D(const gfxPointH3D& aPoint) const;
   gfxPointH3D TransposeTransform4D(const gfxPointH3D& aPoint) const;
 
   gfxPoint ProjectPoint(const gfxPoint& aPoint) const;
   gfxRect ProjectRectBounds(const gfxRect& aRect) const;
 
-  /**
-   * Transforms a point by the inverse of this matrix. In the case of projective transforms, some screen
-   * points have no equivalent in the untransformed plane (if they exist past the vanishing point). To
-   * avoid this, we need to specify the bounds of the untransformed plane to restrict the search area.
-   *
-   * @param aPoint Point to untransform.
-   * @param aChildBounds Bounds of the untransformed plane.
-   * @param aOut Untransformed point.
-   * @return Returns true if a point was found within a ChildBounds, false otherwise.
-   */
-  bool UntransformPoint(const gfxPoint& aPoint, const gfxRect& aChildBounds, gfxPoint* aOut) const;
-
-
-  /**
-   * Same as UntransformPoint, but untransforms a rect and returns the bounding rect of the result.
-   * Returns an empty rect if the result doesn't intersect aChildBounds.
-   */
-  gfxRect UntransformBounds(const gfxRect& aRect, const gfxRect& aChildBounds) const;
-
 
   /**
    * Inverts this matrix, if possible. Otherwise, the matrix is left
    * unchanged.
    */
   gfx3DMatrix Inverse() const;
 
   gfx3DMatrix& Invert()
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -1554,20 +1554,17 @@ SetVisibleRegionForLayer(Layer* aLayer, 
 {
   gfx3DMatrix transform;
   To3DMatrix(aLayer->GetTransform(), transform);
 
   // if 'transform' is not invertible, then nothing will be displayed
   // for the layer, so it doesn't really matter what we do here
   gfxRect itemVisible(aRestrictToRect.x, aRestrictToRect.y,
                       aRestrictToRect.width, aRestrictToRect.height);
-  nsIntRect childBounds = aLayerVisibleRegion.GetBounds();
-  gfxRect childGfxBounds(childBounds.x, childBounds.y,
-                         childBounds.width, childBounds.height);
-  gfxRect layerVisible = transform.UntransformBounds(itemVisible, childGfxBounds);
+  gfxRect layerVisible = transform.Inverse().ProjectRectBounds(itemVisible);
   layerVisible.RoundOut();
 
   nsIntRect visibleRect;
   if (!gfxUtils::GfxRectToIntRect(layerVisible, &visibleRect)) {
     aLayer->SetVisibleRegion(nsIntRegion());
   } else {
     nsIntRegion rgn;
     rgn.And(aLayerVisibleRegion, visibleRect);
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -1391,17 +1391,17 @@ void nsDisplayList::HitTest(nsDisplayLis
           item->Frame()->Preserves3D()) {
         if (outFrames.Length()) {
           nsDisplayTransform *transform = static_cast<nsDisplayTransform*>(item);
           nsPoint point = aRect.TopLeft();
           // A 1x1 rect means a point, otherwise use the center of the rect
           if (aRect.width != 1 || aRect.height != 1) {
             point = aRect.Center();
           }
-          temp.AppendElement(FramesWithDepth(transform->GetHitDepthAtPoint(aBuilder, point)));
+          temp.AppendElement(FramesWithDepth(transform->GetHitDepthAtPoint(point)));
           writeFrames = &temp[temp.Length() - 1].mFrames;
         }
       } else {
         // We may have just finished a run of consecutive preserve-3d transforms,
         // so flush these into the destination array before processing our frame list.
         FlushFramesArray(temp, aOutFrames);
       }
 
@@ -4445,18 +4445,23 @@ bool nsDisplayTransform::ComputeVisibili
                                              nsRegion *aVisibleRegion,
                                              const nsRect& aAllowVisibleRegionExpansion)
 {
   /* As we do this, we need to be sure to
    * untransform the visible rect, since we want everything that's painting to
    * think that it's painting in its original rectangular coordinate space.
    * If we can't untransform, take the entire overflow rect */
   nsRect untransformedVisibleRect;
+  // GetTransform always operates in dev pixels.
+  float factor = mFrame->PresContext()->AppUnitsPerDevPixel();
   if (ShouldPrerenderTransformedContent(aBuilder, mFrame) ||
-      !UntransformVisibleRect(aBuilder, &untransformedVisibleRect))
+      !UntransformRectMatrix(mVisibleRect,
+                             GetTransform(),
+                             factor,
+                             &untransformedVisibleRect))
   {
     untransformedVisibleRect = mFrame->GetVisualOverflowRectRelativeToSelf();
   }
   nsRegion untransformedVisible = untransformedVisibleRect;
   // Call RecomputeVisiblity instead of ComputeVisibility since
   // nsDisplayItem::ComputeVisibility should only be called from
   // nsDisplayList::ComputeVisibility (which sets mVisibleRect on the item)
   mStoredList.RecomputeVisibility(aBuilder, &untransformedVisible);
@@ -4487,57 +4492,43 @@ void nsDisplayTransform::HitTest(nsDispl
   if (!IsFrameVisible(mFrame, matrix)) {
     return;
   }
 
   /* We want to go from transformed-space to regular space.
    * Thus we have to invert the matrix, which normally does
    * the reverse operation (e.g. regular->transformed)
    */
-  bool snap;
-  nsRect childBounds = mStoredList.GetBounds(aBuilder, &snap);
-  gfxRect childGfxBounds(NSAppUnitsToFloatPixels(childBounds.x, factor),
-                         NSAppUnitsToFloatPixels(childBounds.y, factor),
-                         NSAppUnitsToFloatPixels(childBounds.width, factor),
-                         NSAppUnitsToFloatPixels(childBounds.height, factor));
 
   /* Now, apply the transform and pass it down the channel. */
   nsRect resultingRect;
   if (aRect.width == 1 && aRect.height == 1) {
     // Magic width/height indicating we're hit testing a point, not a rect
-    gfxPoint point;
-    if (!matrix.UntransformPoint(gfxPoint(NSAppUnitsToFloatPixels(aRect.x, factor),
-                                          NSAppUnitsToFloatPixels(aRect.y, factor)),
-                                 childGfxBounds,
-                                 &point)) {
-      return;
-    }
+    gfxPoint point = matrix.Inverse().ProjectPoint(
+                       gfxPoint(NSAppUnitsToFloatPixels(aRect.x, factor),
+                                NSAppUnitsToFloatPixels(aRect.y, factor)));
 
     resultingRect = nsRect(NSFloatPixelsToAppUnits(float(point.x), factor),
                            NSFloatPixelsToAppUnits(float(point.y), factor),
                            1, 1);
 
   } else {
     gfxRect originalRect(NSAppUnitsToFloatPixels(aRect.x, factor),
                          NSAppUnitsToFloatPixels(aRect.y, factor),
                          NSAppUnitsToFloatPixels(aRect.width, factor),
                          NSAppUnitsToFloatPixels(aRect.height, factor));
 
-    gfxRect rect = matrix.UntransformBounds(originalRect, childGfxBounds);
+    gfxRect rect = matrix.Inverse().ProjectRectBounds(originalRect);;
 
     resultingRect = nsRect(NSFloatPixelsToAppUnits(float(rect.X()), factor),
                            NSFloatPixelsToAppUnits(float(rect.Y()), factor),
                            NSFloatPixelsToAppUnits(float(rect.Width()), factor),
                            NSFloatPixelsToAppUnits(float(rect.Height()), factor));
   }
 
-  if (resultingRect.IsEmpty()) {
-    return;
-  }
-
 
 #ifdef DEBUG_HIT
   printf("Frame: %p\n", dynamic_cast<void *>(mFrame));
   printf("  Untransformed point: (%f, %f)\n", resultingRect.X(), resultingRect.Y());
   uint32_t originalFrameCount = aOutFrames.Length();
 #endif
 
   mStoredList.HitTest(aBuilder, resultingRect, aState, aOutFrames);
@@ -4547,37 +4538,27 @@ void nsDisplayTransform::HitTest(nsDispl
     printf("  Hit! Time: %f, first frame: %p\n", static_cast<double>(clock()),
            dynamic_cast<void *>(aOutFrames.ElementAt(0)));
   printf("=== end of hit test ===\n");
 #endif
 
 }
 
 float
-nsDisplayTransform::GetHitDepthAtPoint(nsDisplayListBuilder* aBuilder, const nsPoint& aPoint)
+nsDisplayTransform::GetHitDepthAtPoint(const nsPoint& aPoint)
 {
   // GetTransform always operates in dev pixels.
   float factor = mFrame->PresContext()->AppUnitsPerDevPixel();
   gfx3DMatrix matrix = GetTransform();
 
   NS_ASSERTION(IsFrameVisible(mFrame, matrix), "We can't have hit a frame that isn't visible!");
 
-  bool snap;
-  nsRect childBounds = mStoredList.GetBounds(aBuilder, &snap);
-  gfxRect childGfxBounds(NSAppUnitsToFloatPixels(childBounds.x, factor),
-                         NSAppUnitsToFloatPixels(childBounds.y, factor),
-                         NSAppUnitsToFloatPixels(childBounds.width, factor),
-                         NSAppUnitsToFloatPixels(childBounds.height, factor));
-
-  gfxPoint point;
-  DebugOnly<bool> result = matrix.UntransformPoint(gfxPoint(NSAppUnitsToFloatPixels(aPoint.x, factor),
-                                                            NSAppUnitsToFloatPixels(aPoint.y, factor)),
-                                                   childGfxBounds,
-                                                   &point);
-  NS_ASSERTION(result, "Why are we trying to get the depth for a point we didn't hit?");
+  gfxPoint point =
+    matrix.Inverse().ProjectPoint(gfxPoint(NSAppUnitsToFloatPixels(aPoint.x, factor),
+                                           NSAppUnitsToFloatPixels(aPoint.y, factor)));
 
   gfxPoint3D transformed = matrix.Transform3D(gfxPoint3D(point.x, point.y, 0));
   return transformed.z;
 }
 
 /* The bounding rectangle for the object is the overflow rectangle translated
  * by the reference point.
  */
@@ -4611,24 +4592,26 @@ nsRect nsDisplayTransform::GetBounds(nsD
  * mStoredList.GetVisibleRect().Contains(untransformedVisible), then it
  * certainly contains the actual (non-axis-aligned) untransformed rect.
  */
 nsRegion nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
                                              bool* aSnap)
 {
   *aSnap = false;
   nsRect untransformedVisible;
+  // GetTransform always operates in dev pixels.
+  float factor = mFrame->PresContext()->AppUnitsPerDevPixel();
   // If we're going to prerender all our content, pretend like we
   // don't have opqaue content so that everything under us is rendered
   // as well.  That will increase graphics memory usage if our frame
   // covers the entire window, but it allows our transform to be
   // updated extremely cheaply, without invalidating any other
   // content.
   if (ShouldPrerenderTransformedContent(aBuilder, mFrame) ||
-      !UntransformVisibleRect(aBuilder, &untransformedVisible)) {
+      !UntransformRectMatrix(mVisibleRect, GetTransform(), factor, &untransformedVisible)) {
       return nsRegion();
   }
 
   const gfx3DMatrix& matrix = GetTransform();
 
   nsRegion result;
   gfxMatrix matrix2d;
   bool tmpSnap;
@@ -4642,17 +4625,19 @@ nsRegion nsDisplayTransform::GetOpaqueRe
 
 /* The transform is uniform if it fills the entire bounding rect and the
  * wrapped list is uniform.  See GetOpaqueRegion for discussion of why this
  * works.
  */
 bool nsDisplayTransform::IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor)
 {
   nsRect untransformedVisible;
-  if (!UntransformVisibleRect(aBuilder, &untransformedVisible)) {
+  // GetTransform always operates in dev pixels.
+  float factor = mFrame->PresContext()->AppUnitsPerDevPixel();
+  if (!UntransformRectMatrix(mVisibleRect, GetTransform(), factor, &untransformedVisible)) {
     return false;
   }
   const gfx3DMatrix& matrix = GetTransform();
 
   gfxMatrix matrix2d;
   return matrix.Is2D(&matrix2d) &&
          matrix2d.PreservesAxisAlignedRectangles() &&
          mStoredList.GetVisibleRect().Contains(untransformedVisible) &&
@@ -4738,44 +4723,53 @@ nsRect nsDisplayTransform::TransformRect
 
   float factor = aFrame->PresContext()->AppUnitsPerDevPixel();
   return nsLayoutUtils::MatrixTransformRectOut
     (aUntransformedBounds,
      GetResultingTransformMatrix(aFrame, aOrigin, factor, aBoundsOverride),
      factor);
 }
 
-bool nsDisplayTransform::UntransformVisibleRect(nsDisplayListBuilder* aBuilder,
-                                                nsRect *aOutRect)
+bool nsDisplayTransform::UntransformRectMatrix(const nsRect &aUntransformedBounds,
+                                               const gfx3DMatrix& aMatrix,
+                                               float aAppUnitsPerPixel,
+                                               nsRect *aOutRect)
 {
-  const gfx3DMatrix& matrix = GetTransform();
-  if (matrix.IsSingular())
+  if (aMatrix.IsSingular())
     return false;
 
-  // GetTransform always operates in dev pixels.
-  float factor = mFrame->PresContext()->AppUnitsPerDevPixel();
-  gfxRect result(NSAppUnitsToFloatPixels(mVisibleRect.x, factor),
-                 NSAppUnitsToFloatPixels(mVisibleRect.y, factor),
-                 NSAppUnitsToFloatPixels(mVisibleRect.width, factor),
-                 NSAppUnitsToFloatPixels(mVisibleRect.height, factor));
-
-  bool snap;
-  nsRect childBounds = mStoredList.GetBounds(aBuilder, &snap);
-  gfxRect childGfxBounds(NSAppUnitsToFloatPixels(childBounds.x, factor),
-                         NSAppUnitsToFloatPixels(childBounds.y, factor),
-                         NSAppUnitsToFloatPixels(childBounds.width, factor),
-                         NSAppUnitsToFloatPixels(childBounds.height, factor));
-
-  result = matrix.UntransformBounds(result, childGfxBounds);
-
-  *aOutRect = nsLayoutUtils::RoundGfxRectToAppRect(result, factor);
+  gfxRect result(NSAppUnitsToFloatPixels(aUntransformedBounds.x, aAppUnitsPerPixel),
+                 NSAppUnitsToFloatPixels(aUntransformedBounds.y, aAppUnitsPerPixel),
+                 NSAppUnitsToFloatPixels(aUntransformedBounds.width, aAppUnitsPerPixel),
+                 NSAppUnitsToFloatPixels(aUntransformedBounds.height, aAppUnitsPerPixel));
+
+  /* We want to untransform the matrix, so invert the transformation first! */
+  result = aMatrix.Inverse().ProjectRectBounds(result);
+
+  *aOutRect = nsLayoutUtils::RoundGfxRectToAppRect(result, aAppUnitsPerPixel);
 
   return true;
 }
 
+bool nsDisplayTransform::UntransformRect(const nsRect &aUntransformedBounds,
+                                           const nsIFrame* aFrame,
+                                           const nsPoint &aOrigin,
+                                           nsRect* aOutRect)
+{
+  NS_PRECONDITION(aFrame, "Can't take the transform based on a null frame!");
+
+  /* Grab the matrix.  If the transform is degenerate, just hand back the
+   * empty rect.
+   */
+  float factor = aFrame->PresContext()->AppUnitsPerDevPixel();
+  gfx3DMatrix matrix = GetResultingTransformMatrix(aFrame, aOrigin, factor);
+
+  return UntransformRectMatrix(aUntransformedBounds, matrix, factor, aOutRect);
+}
+
 nsDisplaySVGEffects::nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder,
                                          nsIFrame* aFrame, nsDisplayList* aList)
     : nsDisplayWrapList(aBuilder, aFrame, aList),
       mEffectsBounds(aFrame->GetVisualOverflowRectRelativeToSelf())
 {
   MOZ_COUNT_CTOR(nsDisplaySVGEffects);
 }
 
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -3057,17 +3057,17 @@ public:
   }
 
   enum {
     INDEX_MAX = UINT32_MAX >> nsDisplayItem::TYPE_BITS
   };
 
   const gfx3DMatrix& GetTransform();
 
-  float GetHitDepthAtPoint(nsDisplayListBuilder* aBuilder, const nsPoint& aPoint);
+  float GetHitDepthAtPoint(const nsPoint& aPoint);
 
   /**
    * TransformRect takes in as parameters a rectangle (in aFrame's coordinate
    * space) and returns the smallest rectangle (in aFrame's coordinate space)
    * containing the transformed image of that rectangle.  That is, it takes
    * the four corners of the rectangle, transforms them according to the
    * matrix associated with the specified frame, then returns the smallest
    * rectangle containing the four transformed points.
@@ -3090,18 +3090,25 @@ public:
   static nsRect TransformRectOut(const nsRect &aUntransformedBounds, 
                                  const nsIFrame* aFrame,
                                  const nsPoint &aOrigin,
                                  const nsRect* aBoundsOverride = nullptr);
 
   /* UntransformRect is like TransformRect, except that it inverts the
    * transform.
    */
-  bool UntransformVisibleRect(nsDisplayListBuilder* aBuilder,
-                              nsRect* aOutRect);
+  static bool UntransformRect(const nsRect &aUntransformedBounds, 
+                                const nsIFrame* aFrame,
+                                const nsPoint &aOrigin,
+                                nsRect* aOutRect);
+  
+  static bool UntransformRectMatrix(const nsRect &aUntransformedBounds, 
+                                    const gfx3DMatrix& aMatrix,
+                                    float aAppUnitsPerPixel,
+                                    nsRect* aOutRect);
 
   static gfxPoint3D GetDeltaToTransformOrigin(const nsIFrame* aFrame,
                                               float aAppUnitsPerPixel,
                                               const nsRect* aBoundsOverride);
 
   static gfxPoint3D GetDeltaToPerspectiveOrigin(const nsIFrame* aFrame,
                                                 float aAppUnitsPerPixel);
 
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -98,23 +98,19 @@ namespace mozilla {
 class Selection;
 
 namespace dom {
 class Element;
 class Touch;
 class ShadowRoot;
 } // namespace dom
 
-namespace layers {
+namespace layers{
 class LayerManager;
 } // namespace layers
-
-namespace gfx {
-class SourceSurface;
-} // namespace gfx
 } // namespace mozilla
 
 // Flags to pass to SetCapturingContent
 //
 // when assigning capture, ignore whether capture is allowed or not
 #define CAPTURE_IGNOREALLOWED 1
 // true if events should be targeted at the capturing content or its children
 #define CAPTURE_RETARGETTOELEMENT 2
@@ -127,20 +123,21 @@ typedef struct CapturingContentInfo {
   // capture should only be allowed during a mousedown event
   bool mAllowed;
   bool mPointerLock;
   bool mRetargetToElement;
   bool mPreventDrag;
   nsIContent* mContent;
 } CapturingContentInfo;
 
-//bccc1c01-5123-4f49-9572-c0bf506b6418
+
+// db8d5e1e-6392-4ec1-9a29-18ee2ec0889b
 #define NS_IPRESSHELL_IID \
-{ 0xbccc1c01, 0x5123, 0x4f49, \
-  {0x95, 0x72, 0xc0, 0xbf, 0x50, 0x6b, 0x64, 0x18}}
+{ 0xdb8d5e1e, 0x6392, 0x4ec1, \
+  {0x9a, 0x29, 0x18, 0xee, 0x2e, 0xc0, 0x88, 0x9b}}
 
 // debug VerifyReflow flags
 #define VERIFY_REFLOW_ON                    0x01
 #define VERIFY_REFLOW_NOISY                 0x02
 #define VERIFY_REFLOW_ALL                   0x04
 #define VERIFY_REFLOW_DUMP_COMMANDS         0x08
 #define VERIFY_REFLOW_NOISY_RC              0x10
 #define VERIFY_REFLOW_REALLY_NOISY_RC       0x20
@@ -176,17 +173,16 @@ public:
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIPresShell_base, NS_IPRESSHELL_IID)
 
 class nsIPresShell : public nsIPresShell_base
 {
 protected:
   typedef mozilla::layers::LayerManager LayerManager;
-  typedef mozilla::gfx::SourceSurface SourceSurface;
 
   enum eRenderFlag {
     STATE_IGNORING_VIEWPORT_SCROLLING = 0x1,
     STATE_DRAWWINDOW_NOT_FLUSHING = 0x2
   };
   typedef uint8_t RenderFlags; // for storing the above flags
 
 public:
@@ -1030,41 +1026,39 @@ public:
                                               gfxContext* aRenderedContext) = 0;
 
   /**
    * Renders a node aNode to a surface and returns it. The aRegion may be used
    * to clip the rendering. This region is measured in CSS pixels from the
    * edge of the presshell area. The aPoint, aScreenRect and aSurface
    * arguments function in a similar manner as RenderSelection.
    */
-  virtual mozilla::TemporaryRef<SourceSurface>
-  RenderNode(nsIDOMNode* aNode,
-             nsIntRegion* aRegion,
-             nsIntPoint& aPoint,
-             nsIntRect* aScreenRect) = 0;
+  virtual already_AddRefed<gfxASurface> RenderNode(nsIDOMNode* aNode,
+                                                   nsIntRegion* aRegion,
+                                                   nsIntPoint& aPoint,
+                                                   nsIntRect* aScreenRect) = 0;
 
   /**
    * Renders a selection to a surface and returns it. This method is primarily
    * intended to create the drag feedback when dragging a selection.
    *
    * aScreenRect will be filled in with the bounding rectangle of the
    * selection area on screen.
    *
    * If the area of the selection is large, the image will be scaled down.
    * The argument aPoint is used in this case as a reference point when
    * determining the new screen rectangle after scaling. Typically, this
    * will be the mouse position, so that the screen rectangle is positioned
    * such that the mouse is over the same point in the scaled image as in
    * the original. When scaling does not occur, the mouse point isn't used
    * as the position can be determined from the displayed frames.
    */
-  virtual mozilla::TemporaryRef<SourceSurface>
-  RenderSelection(nsISelection* aSelection,
-                  nsIntPoint& aPoint,
-                  nsIntRect* aScreenRect) = 0;
+  virtual already_AddRefed<gfxASurface> RenderSelection(nsISelection* aSelection,
+                                                        nsIntPoint& aPoint,
+                                                        nsIntRect* aScreenRect) = 0;
 
   void AddWeakFrameInternal(nsWeakFrame* aWeakFrame);
   virtual void AddWeakFrameExternal(nsWeakFrame* aWeakFrame);
 
   void AddWeakFrame(nsWeakFrame* aWeakFrame)
   {
 #ifdef MOZILLA_INTERNAL_API
     AddWeakFrameInternal(aWeakFrame);
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -1815,31 +1815,32 @@ nsLayoutUtils::GetLayerTransformForFrame
 
   *aTransform =
     item->GetTransform();
   item->~nsDisplayTransform();
 
   return true;
 }
 
-static bool
+static gfxPoint
 TransformGfxPointFromAncestor(nsIFrame *aFrame,
                               const gfxPoint &aPoint,
-                              nsIFrame *aAncestor,
-                              gfxPoint* aOut)
+                              nsIFrame *aAncestor)
 {
   gfx3DMatrix ctm = nsLayoutUtils::GetTransformToAncestor(aFrame, aAncestor);
-
-  float factor = aFrame->PresContext()->AppUnitsPerDevPixel();
-  nsRect childBounds = aFrame->GetVisualOverflowRectRelativeToSelf();
-  gfxRect childGfxBounds(NSAppUnitsToFloatPixels(childBounds.x, factor),
-                         NSAppUnitsToFloatPixels(childBounds.y, factor),
-                         NSAppUnitsToFloatPixels(childBounds.width, factor),
-                         NSAppUnitsToFloatPixels(childBounds.height, factor));
-  return ctm.UntransformPoint(aPoint, childGfxBounds, aOut);
+  return ctm.Inverse().ProjectPoint(aPoint);
+}
+
+static gfxRect
+TransformGfxRectFromAncestor(nsIFrame *aFrame,
+                             const gfxRect &aRect,
+                             const nsIFrame *aAncestor)
+{
+  gfx3DMatrix ctm = nsLayoutUtils::GetTransformToAncestor(aFrame, aAncestor);
+  return ctm.Inverse().ProjectRectBounds(aRect);
 }
 
 static gfxRect
 TransformGfxRectToAncestor(nsIFrame *aFrame,
                            const gfxRect &aRect,
                            const nsIFrame *aAncestor,
                            bool* aPreservesAxisAlignedRectangles = nullptr)
 {
@@ -1871,30 +1872,53 @@ nsLayoutUtils::TransformAncestorPointToF
 {
     SVGTextFrame* text = GetContainingSVGTextFrame(aFrame);
 
     float factor = aFrame->PresContext()->AppUnitsPerDevPixel();
     gfxPoint result(NSAppUnitsToFloatPixels(aPoint.x, factor),
                     NSAppUnitsToFloatPixels(aPoint.y, factor));
 
     if (text) {
-        if (!TransformGfxPointFromAncestor(text, result, aAncestor, &result)) {
-            return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
-        }
+        result = TransformGfxPointFromAncestor(text, result, aAncestor);
         result = text->TransformFramePointToTextChild(result, aFrame);
     } else {
-        if (!TransformGfxPointFromAncestor(aFrame, result, nullptr, &result)) {
-            return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
-        }
+        result = TransformGfxPointFromAncestor(aFrame, result, nullptr);
     }
 
     return nsPoint(NSFloatPixelsToAppUnits(float(result.x), factor),
                    NSFloatPixelsToAppUnits(float(result.y), factor));
 }
 
+nsRect 
+nsLayoutUtils::TransformAncestorRectToFrame(nsIFrame* aFrame,
+                                            const nsRect &aRect,
+                                            const nsIFrame* aAncestor)
+{
+    SVGTextFrame* text = GetContainingSVGTextFrame(aFrame);
+
+    float srcAppUnitsPerDevPixel = aAncestor->PresContext()->AppUnitsPerDevPixel();
+    gfxRect result(NSAppUnitsToFloatPixels(aRect.x, srcAppUnitsPerDevPixel),
+                   NSAppUnitsToFloatPixels(aRect.y, srcAppUnitsPerDevPixel),
+                   NSAppUnitsToFloatPixels(aRect.width, srcAppUnitsPerDevPixel),
+                   NSAppUnitsToFloatPixels(aRect.height, srcAppUnitsPerDevPixel));
+
+    if (text) {
+      result = TransformGfxRectFromAncestor(text, result, aAncestor);
+      result = text->TransformFrameRectToTextChild(result, aFrame);
+    } else {
+      result = TransformGfxRectFromAncestor(aFrame, result, aAncestor);
+    }
+
+    float destAppUnitsPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
+    return nsRect(NSFloatPixelsToAppUnits(float(result.x), destAppUnitsPerDevPixel),
+                  NSFloatPixelsToAppUnits(float(result.y), destAppUnitsPerDevPixel),
+                  NSFloatPixelsToAppUnits(float(result.width), destAppUnitsPerDevPixel),
+                  NSFloatPixelsToAppUnits(float(result.height), destAppUnitsPerDevPixel));
+}
+
 nsRect
 nsLayoutUtils::TransformFrameRectToAncestor(nsIFrame* aFrame,
                                             const nsRect& aRect,
                                             const nsIFrame* aAncestor,
                                             bool* aPreservesAxisAlignedRectangles /* = nullptr */)
 {
   SVGTextFrame* text = GetContainingSVGTextFrame(aFrame);
 
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -632,16 +632,24 @@ public:
    * @param aOutFrames an array to add all the frames found
    * @param aFlags some combination of FrameForPointFlags
    */
   static nsresult GetFramesForArea(nsIFrame* aFrame, const nsRect& aRect,
                                    nsTArray<nsIFrame*> &aOutFrames,
                                    uint32_t aFlags = 0);
 
   /**
+   * Transform aRect relative to aAncestor down to the coordinate system of
+   * aFrame. Computes the bounding-box of the true quadrilateral.
+   */
+  static nsRect TransformAncestorRectToFrame(nsIFrame* aFrame,
+                                             const nsRect& aRect,
+                                             const nsIFrame* aAncestor);
+
+  /**
    * Transform aRect relative to aFrame up to the coordinate system of
    * aAncestor. Computes the bounding-box of the true quadrilateral.
    * Pass non-null aPreservesAxisAlignedRectangles and it will be set to true if
    * we only need to use a 2d transform that PreservesAxisAlignedRectangles().
    */
   static nsRect TransformFrameRectToAncestor(nsIFrame* aFrame,
                                              const nsRect& aRect,
                                              const nsIFrame* aAncestor,
@@ -676,19 +684,16 @@ public:
                                            const nsPoint &aPoint)
   {
     return TransformAncestorPointToFrame(aFrame, aPoint, nullptr);
   }
 
   /**
    * Transform aPoint relative to aAncestor down to the coordinate system of
    * aFrame.
-   *
-   * Returns nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if no equivalent
-   * point exists in the child frame (can happen with projective transforms).
    */
   static nsPoint TransformAncestorPointToFrame(nsIFrame* aFrame,
                                                const nsPoint& aPoint,
                                                nsIFrame* aAncestor);
 
   /**
    * Helper function that, given a rectangle and a matrix, returns the smallest
    * rectangle containing the image of the source rectangle.
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -160,30 +160,28 @@
 #include "nsIScreenManager.h"
 #include "nsPlaceholderFrame.h"
 #include "nsTransitionManager.h"
 #include "ChildIterator.h"
 #include "RestyleManager.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDragSession.h"
 #include "nsIFrameInlines.h"
-#include "mozilla/gfx/2D.h"
 
 #ifdef ANDROID
 #include "nsIDocShellTreeOwner.h"
 #endif
 
 #define ANCHOR_SCROLL_FLAGS \
   (nsIPresShell::SCROLL_OVERFLOW_HIDDEN | nsIPresShell::SCROLL_NO_PARENT_FRAMES)
 
 using namespace mozilla;
 using namespace mozilla::css;
 using namespace mozilla::dom;
 using namespace mozilla::layers;
-using namespace mozilla::gfx;
 
 CapturingContentInfo nsIPresShell::gCaptureInfo =
   { false /* mAllowed */, false /* mPointerLock */, false /* mRetargetToElement */,
     false /* mPreventDrag */, nullptr /* mContent */ };
 nsIContent* nsIPresShell::gKeyDownTarget;
 nsRefPtrHashtable<nsUint32HashKey, dom::Touch>* nsIPresShell::gCaptureTouchList;
 bool nsIPresShell::gPreventMouseEvents = false;
 
@@ -4806,17 +4804,17 @@ PresShell::CreateRangePaintInfo(nsIDOMRa
   // to all be offset from the same point
   info->mRootOffset = ancestorFrame->GetOffsetTo(rootFrame);
   rangeRect.MoveBy(info->mRootOffset);
   aSurfaceRect.UnionRect(aSurfaceRect, rangeRect);
 
   return info;
 }
 
-TemporaryRef<SourceSurface>
+already_AddRefed<gfxASurface>
 PresShell::PaintRangePaintInfo(nsTArray<nsAutoPtr<RangePaintInfo> >* aItems,
                                nsISelection* aSelection,
                                nsIntRegion* aRegion,
                                nsRect aArea,
                                nsIntPoint& aPoint,
                                nsIntRect* aScreenRect)
 {
   nsPresContext* pc = GetPresContext();
@@ -4875,24 +4873,18 @@ PresShell::PaintRangePaintInfo(nsTArray<
   }
 
   // clear the image
   gfxContext context(surface);
   context.SetOperator(gfxContext::OPERATOR_CLEAR);
   context.Rectangle(gfxRect(0, 0, pixelArea.width, pixelArea.height));
   context.Fill();
 
-
-  RefPtr<DrawTarget> dt =
-    gfxPlatform::GetPlatform()->
-      CreateDrawTargetForSurface(surface, gfx::IntSize(pixelArea.width, pixelArea.height));
-
-  nsRefPtr<gfxContext> ctx = new gfxContext(dt);
   nsRefPtr<nsRenderingContext> rc = new nsRenderingContext();
-  rc->Init(deviceContext, ctx);
+  rc->Init(deviceContext, surface);
 
   if (aRegion) {
     // Convert aRegion from CSS pixels to dev pixels
     nsIntRegion region =
       aRegion->ToAppUnits(nsPresContext::AppUnitsPerCSSPixel())
         .ToOutsidePixels(pc->AppUnitsPerDevPixel());
     rc->SetClip(region);
   }
@@ -4930,20 +4922,20 @@ PresShell::PaintRangePaintInfo(nsTArray<
     rangeInfo->mList.ComputeVisibilityForRoot(&rangeInfo->mBuilder, &visible);
     rangeInfo->mList.PaintRoot(&rangeInfo->mBuilder, rc, nsDisplayList::PAINT_DEFAULT);
     aArea.MoveBy(rangeInfo->mRootOffset.x, rangeInfo->mRootOffset.y);
   }
 
   // restore the old selection display state
   frameSelection->SetDisplaySelection(oldDisplaySelection);
 
-  return dt->Snapshot();
-}
-
-TemporaryRef<SourceSurface>
+  return surface.forget();
+}
+
+already_AddRefed<gfxASurface>
 PresShell::RenderNode(nsIDOMNode* aNode,
                       nsIntRegion* aRegion,
                       nsIntPoint& aPoint,
                       nsIntRect* aScreenRect)
 {
   // area will hold the size of the surface needed to draw the node, measured
   // from the root frame.
   nsRect area;
@@ -4979,17 +4971,17 @@ PresShell::RenderNode(nsIDOMNode* aNode,
     aRegion->MoveBy(-pc->AppUnitsToDevPixels(area.x),
                     -pc->AppUnitsToDevPixels(area.y));
   }
 
   return PaintRangePaintInfo(&rangeItems, nullptr, aRegion, area, aPoint,
                              aScreenRect);
 }
 
-TemporaryRef<SourceSurface>
+already_AddRefed<gfxASurface>
 PresShell::RenderSelection(nsISelection* aSelection,
                            nsIntPoint& aPoint,
                            nsIntRect* aScreenRect)
 {
   // area will hold the size of the surface needed to draw the selection,
   // measured from the root frame.
   nsRect area;
   nsTArray<nsAutoPtr<RangePaintInfo> > rangeItems;
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -157,26 +157,24 @@ public:
   virtual void Freeze() MOZ_OVERRIDE;
   virtual void Thaw() MOZ_OVERRIDE;
   virtual void FireOrClearDelayedEvents(bool aFireEvents) MOZ_OVERRIDE;
 
   virtual NS_HIDDEN_(nsresult) RenderDocument(const nsRect& aRect, uint32_t aFlags,
                                               nscolor aBackgroundColor,
                                               gfxContext* aThebesContext) MOZ_OVERRIDE;
 
-  virtual mozilla::TemporaryRef<SourceSurface>
-  RenderNode(nsIDOMNode* aNode,
-             nsIntRegion* aRegion,
-             nsIntPoint& aPoint,
-             nsIntRect* aScreenRect) MOZ_OVERRIDE;
+  virtual already_AddRefed<gfxASurface> RenderNode(nsIDOMNode* aNode,
+                                                   nsIntRegion* aRegion,
+                                                   nsIntPoint& aPoint,
+                                                   nsIntRect* aScreenRect) MOZ_OVERRIDE;
 
-  virtual mozilla::TemporaryRef<SourceSurface>
-  RenderSelection(nsISelection* aSelection,
-                  nsIntPoint& aPoint,
-                  nsIntRect* aScreenRect) MOZ_OVERRIDE;
+  virtual already_AddRefed<gfxASurface> RenderSelection(nsISelection* aSelection,
+                                                        nsIntPoint& aPoint,
+                                                        nsIntRect* aScreenRect) MOZ_OVERRIDE;
 
   virtual already_AddRefed<nsPIDOMWindow> GetRootWindow() MOZ_OVERRIDE;
 
   virtual LayerManager* GetLayerManager() MOZ_OVERRIDE;
 
   virtual void SetIgnoreViewportScrolling(bool aIgnore) MOZ_OVERRIDE;
 
   virtual void SetDisplayPort(const nsRect& aDisplayPort);
@@ -499,17 +497,17 @@ protected:
    *
    * aSelection - selection being painted, if any
    * aRegion - clip region, if any
    * aArea - area that the surface occupies, relative to the root frame
    * aPoint - reference point, typically the mouse position
    * aScreenRect - [out] set to the area of the screen the painted area should
    *               be displayed at
    */
-  mozilla::TemporaryRef<SourceSurface>
+  already_AddRefed<gfxASurface>
   PaintRangePaintInfo(nsTArray<nsAutoPtr<RangePaintInfo> >* aItems,
                       nsISelection* aSelection,
                       nsIntRegion* aRegion,
                       nsRect aArea,
                       nsIntPoint& aPoint,
                       nsIntRect* aScreenRect);
 
   /**
--- a/widget/cocoa/nsDragService.mm
+++ b/widget/cocoa/nsDragService.mm
@@ -25,21 +25,16 @@
 #include "nsIIOService.h"
 #include "nsNetUtil.h"
 #include "nsIDocument.h"
 #include "nsIContent.h"
 #include "nsView.h"
 #include "gfxASurface.h"
 #include "gfxContext.h"
 #include "nsCocoaUtils.h"
-#include "mozilla/gfx/2D.h"
-#include "gfxPlatform.h"
-
-using namespace mozilla;
-using namespace mozilla::gfx;
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* sCocoaLog;
 #endif
 
 extern void EnsureLogInitialized();
 
 extern NSPasteboard* globalDragPboard;
@@ -141,22 +136,22 @@ nsDragService::ConstructDragImage(nsIDOM
   NSPoint screenPoint =
     [[gLastDragView window] convertBaseToScreen:
       [gLastDragMouseDownEvent locationInWindow]];
   // Y coordinates are bottom to top, so reverse this
   screenPoint.y = nsCocoaUtils::FlippedScreenY(screenPoint.y);
 
   CGFloat scaleFactor = nsCocoaUtils::GetBackingScaleFactor(gLastDragView);
 
-  RefPtr<SourceSurface> surface;
+  nsRefPtr<gfxASurface> surface;
   nsPresContext* pc;
   nsresult rv = DrawDrag(aDOMNode, aRegion,
                          NSToIntRound(screenPoint.x),
                          NSToIntRound(screenPoint.y),
-                         aDragRect, &surface, &pc);
+                         aDragRect, getter_AddRefs(surface), &pc);
   if (!aDragRect->width || !aDragRect->height) {
     // just use some suitable defaults
     int32_t size = nsCocoaUtils::CocoaPointsToDevPixels(20, scaleFactor);
     aDragRect->SetRect(nsCocoaUtils::CocoaPointsToDevPixels(screenPoint.x, scaleFactor),
                        nsCocoaUtils::CocoaPointsToDevPixels(screenPoint.y, scaleFactor),
                        size, size);
   }
 
@@ -166,25 +161,23 @@ nsDragService::ConstructDragImage(nsIDOM
   uint32_t width = aDragRect->width;
   uint32_t height = aDragRect->height;
 
   nsRefPtr<gfxImageSurface> imgSurface = new gfxImageSurface(
     gfxIntSize(width, height), gfxImageFormat::ARGB32);
   if (!imgSurface)
     return nil;
 
-  RefPtr<DrawTarget> dt =
-    gfxPlatform::GetPlatform()->
-      CreateDrawTargetForSurface(imgSurface, IntSize(width, height));
-  if (!dt)
+  nsRefPtr<gfxContext> context = new gfxContext(imgSurface);
+  if (!context)
     return nil;
 
-  dt->FillRect(gfx::Rect(0, 0, width, height),
-               SurfacePattern(surface, ExtendMode::CLAMP),
-               DrawOptions(1.0f, CompositionOp::OP_SOURCE));
+  context->SetOperator(gfxContext::OPERATOR_SOURCE);
+  context->SetSource(surface);
+  context->Paint();
 
   uint32_t* imageData = (uint32_t*)imgSurface->Data();
   int32_t stride = imgSurface->Stride();
 
   NSBitmapImageRep* imageRep =
     [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
                                             pixelsWide:width
                                             pixelsHigh:height
--- a/widget/gtk/nsDragService.cpp
+++ b/widget/gtk/nsDragService.cpp
@@ -31,21 +31,16 @@
 #include "nsImageToPixbuf.h"
 #include "nsPresContext.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsISelection.h"
 #include "nsViewManager.h"
 #include "nsIFrame.h"
 #include "nsGtkUtils.h"
-#include "mozilla/gfx/2D.h"
-#include "gfxPlatform.h"
-
-using namespace mozilla;
-using namespace mozilla::gfx;
 
 // This sets how opaque the drag image is
 #define DRAG_IMAGE_ALPHA_LEVEL 0.5
 
 // These values are copied from GtkDragResult (rather than using GtkDragResult
 // directly) so that this code can be compiled against versions of GTK+ that
 // do not have GtkDragResult.
 // GtkDragResult is available from GTK+ version 2.12.
@@ -390,21 +385,21 @@ nsDragService::InvokeDragSession(nsIDOMN
     }
 
     gtk_target_list_unref(sourceList);
 
     return rv;
 }
 
 bool
-nsDragService::SetAlphaPixmap(SourceSurface *aSurface,
-                              GdkDragContext *aContext,
-                              int32_t aXOffset,
-                              int32_t aYOffset,
-                              const nsIntRect& dragRect)
+nsDragService::SetAlphaPixmap(gfxASurface *aSurface,
+                                 GdkDragContext *aContext,
+                                 int32_t aXOffset,
+                                 int32_t aYOffset,
+                                 const nsIntRect& dragRect)
 {
 #if (MOZ_WIDGET_GTK == 2)
     GdkScreen* screen = gtk_widget_get_screen(mHiddenWidget);
 
     // Transparent drag icons need, like a lot of transparency-related things,
     // a compositing X window manager
     if (!gdk_screen_is_composited(screen))
       return false;
@@ -422,31 +417,26 @@ nsDragService::SetAlphaPixmap(SourceSurf
 
     // Make a gfxXlibSurface wrapped around the pixmap to render on
     nsRefPtr<gfxASurface> xPixmapSurface =
          nsWindow::GetSurfaceForGdkDrawable(GDK_DRAWABLE(pixmap),
                                             dragRect.Size());
     if (!xPixmapSurface)
       return false;
 
-    RefPtr<DrawTarget> dt =
-    gfxPlatform::GetPlatform()->
-      CreateDrawTargetForSurface(xPixmapSurface, IntSize(dragRect.width, dragRect.height));
-    if (!dt)
-      return false;
+    nsRefPtr<gfxContext> xPixmapCtx = new gfxContext(xPixmapSurface);
 
     // Clear it...
-    dt->ClearRect(Rect(0, 0, dragRect.width, dragRect.height));
+    xPixmapCtx->SetOperator(gfxContext::OPERATOR_CLEAR);
+    xPixmapCtx->Paint();
 
     // ...and paint the drag image with translucency
-    dt->DrawSurface(aSurface,
-                    Rect(0, 0, dragRect.width, dragRect.height),
-                    Rect(0, 0, dragRect.width, dragRect.height),
-                    DrawSurfaceOptions(),
-                    DrawOptions(DRAG_IMAGE_ALPHA_LEVEL, CompositionOp::OP_SOURCE));
+    xPixmapCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
+    xPixmapCtx->SetSource(aSurface);
+    xPixmapCtx->Paint(DRAG_IMAGE_ALPHA_LEVEL);
 
     // The drag transaction addrefs the pixmap, so we can just unref it from us here
     gtk_drag_set_icon_pixmap(aContext, alphaColormap, pixmap, nullptr,
                              aXOffset, aYOffset);
     g_object_unref(pixmap);
     return true;
 #else
     // TODO GTK3
@@ -1570,19 +1560,19 @@ nsDragService::SourceDataGet(GtkWidget  
 
 void nsDragService::SetDragIcon(GdkDragContext* aContext)
 {
     if (!mHasImage && !mSelection)
         return;
 
     nsIntRect dragRect;
     nsPresContext* pc;
-    RefPtr<SourceSurface> surface;
+    nsRefPtr<gfxASurface> surface;
     DrawDrag(mSourceNode, mSourceRegion, mScreenX, mScreenY,
-             &dragRect, &surface, &pc);
+             &dragRect, getter_AddRefs(surface), &pc);
     if (!pc)
         return;
 
     int32_t sx = mScreenX, sy = mScreenY;
     ConvertToUnscaledDevPixels(pc, &sx, &sy);
 
     int32_t offsetX = sx - dragRect.x;
     int32_t offsetY = sy - dragRect.y;
@@ -1602,17 +1592,17 @@ void nsDragService::SetDragIcon(GdkDragC
                     gtk_drag_set_icon_widget(aContext, gtkWidget, offsetX, offsetY);
                 }
             }
         }
     }
     else if (surface) {
         if (!SetAlphaPixmap(surface, aContext, offsetX, offsetY, dragRect)) {
             GdkPixbuf* dragPixbuf =
-              nsImageToPixbuf::SourceSurfaceToPixbuf(surface, dragRect.width, dragRect.height);
+              nsImageToPixbuf::SurfaceToPixbuf(surface, dragRect.width, dragRect.height);
             if (dragPixbuf) {
                 gtk_drag_set_icon_pixbuf(aContext, dragPixbuf, offsetX, offsetY);
                 g_object_unref(dragPixbuf);
             }
         }
     }
 }
 
--- a/widget/gtk/nsDragService.h
+++ b/widget/gtk/nsDragService.h
@@ -9,22 +9,16 @@
 
 #include "nsBaseDragService.h"
 #include "nsIObserver.h"
 #include "nsAutoRef.h"
 #include <gtk/gtk.h>
 
 class nsWindow;
 
-namespace mozilla {
-namespace gfx {
-class SourceSurface;
-}
-}
-
 #ifndef HAVE_NSGOBJECTREFTRAITS
 #define HAVE_NSGOBJECTREFTRAITS
 template <class T>
 class nsGObjectRefTraits : public nsPointerRefTraits<T> {
 public:
     static void Release(T *aPtr) { g_object_unref(aPtr); }
     static void AddRef(T *aPtr) { g_object_ref(aPtr); }
 };
@@ -184,21 +178,21 @@ private:
 
     nsCOMPtr<nsIScriptableRegion> mSourceRegion;
 
     // get a list of the sources in gtk's format
     GtkTargetList *GetSourceList(void);
 
     // attempts to create a semi-transparent drag image. Returns TRUE if
     // successful, FALSE if not
-    bool SetAlphaPixmap(SourceSurface *aPixbuf,
-                        GdkDragContext  *aContext,
-                        int32_t          aXOffset,
-                        int32_t          aYOffset,
-                        const nsIntRect &dragRect);
+    bool SetAlphaPixmap(gfxASurface     *aPixbuf,
+                          GdkDragContext  *aContext,
+                          int32_t          aXOffset,
+                          int32_t          aYOffset,
+                          const nsIntRect &dragRect);
 
     gboolean Schedule(DragTask aTask, nsWindow *aWindow,
                       GdkDragContext *aDragContext,
                       nsIntPoint aWindowPoint, guint aTime);
 
     // Callback for g_idle_add_full() to run mScheduledTask.
     static gboolean TaskDispatchCallback(gpointer data);
     gboolean RunScheduledTask();
--- a/widget/gtk/nsImageToPixbuf.cpp
+++ b/widget/gtk/nsImageToPixbuf.cpp
@@ -124,8 +124,42 @@ nsImageToPixbuf::SourceSurfaceToPixbuf(S
         }
     }
 
     dataSurface->Unmap();
 
     return pixbuf;
 }
 
+GdkPixbuf*
+nsImageToPixbuf::SurfaceToPixbuf(gfxASurface* aSurface, int32_t aWidth, int32_t aHeight)
+{
+    if (aSurface->CairoStatus()) {
+        NS_ERROR("invalid surface");
+        return nullptr;
+    }
+
+    nsRefPtr<gfxImageSurface> imgSurface;
+    if (aSurface->GetType() == gfxSurfaceType::Image) {
+        imgSurface = static_cast<gfxImageSurface*>
+                                (static_cast<gfxASurface*>(aSurface));
+    } else {
+        imgSurface = new gfxImageSurface(gfxIntSize(aWidth, aHeight),
+					 gfxImageFormat::ARGB32);
+                                       
+        if (!imgSurface)
+            return nullptr;
+
+        nsRefPtr<gfxContext> context = new gfxContext(imgSurface);
+        if (!context)
+            return nullptr;
+
+        context->SetOperator(gfxContext::OPERATOR_SOURCE);
+        context->SetSource(aSurface);
+        context->Paint();
+    }
+
+    RefPtr<SourceSurface> surface =
+        gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr,
+                                                               imgSurface);
+
+    return SourceSurfaceToPixbuf(surface, aWidth, aHeight);
+}
--- a/widget/gtk/nsImageToPixbuf.h
+++ b/widget/gtk/nsImageToPixbuf.h
@@ -28,16 +28,18 @@ class nsImageToPixbuf MOZ_FINAL : public
 
         // Friendlier version of ConvertImageToPixbuf for callers inside of
         // widget
         /**
          * The return value of all these, if not null, should be
          * released as needed by the caller using g_object_unref.
          */
         static GdkPixbuf* ImageToPixbuf(imgIContainer * aImage);
+        static GdkPixbuf* SurfaceToPixbuf(gfxASurface* aSurface,
+                                          int32_t aWidth, int32_t aHeight);
         static GdkPixbuf* SourceSurfaceToPixbuf(SourceSurface* aSurface,
                                                 int32_t aWidth,
                                                 int32_t aHeight);
 
     private:
         ~nsImageToPixbuf() {}
 };
 
--- a/widget/windows/nsDragService.cpp
+++ b/widget/windows/nsDragService.cpp
@@ -35,20 +35,16 @@
 #include "nsCRT.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsUnicharUtils.h"
 #include "gfxASurface.h"
 #include "gfxContext.h"
 #include "nsRect.h"
 #include "nsMathUtils.h"
 #include "gfxWindowsPlatform.h"
-#include "mozilla/gfx/2D.h"
-
-using namespace mozilla;
-using namespace mozilla::gfx;
 
 //-------------------------------------------------------------------------
 //
 // DragService constructor
 //
 //-------------------------------------------------------------------------
 nsDragService::nsDragService()
   : mDataObject(nullptr), mSentLocalDropEvent(false)
@@ -74,52 +70,44 @@ nsDragService::CreateDragImage(nsIDOMNod
     return false;
 
   memset(psdi, 0, sizeof(SHDRAGIMAGE));
   if (!aDOMNode) 
     return false;
 
   // Prepare the drag image
   nsIntRect dragRect;
-  RefPtr<SourceSurface> surface;
+  nsRefPtr<gfxASurface> surface;
   nsPresContext* pc;
   DrawDrag(aDOMNode, aRegion,
            mScreenX, mScreenY,
-           &dragRect, &surface, &pc);
+           &dragRect, getter_AddRefs(surface), &pc);
   if (!surface)
     return false;
 
   uint32_t bmWidth = dragRect.width, bmHeight = dragRect.height;
 
   if (bmWidth == 0 || bmHeight == 0)
     return false;
 
   psdi->crColorKey = CLR_NONE;
 
-  RefPtr<DataSourceSurface> data = surface->GetDataSurface();
-  DataSourceSurface::MappedSurface map;
-  if (!data->Map(DataSourceSurface::READ, &map)) {
-    return false;
-  }
-
   nsRefPtr<gfxImageSurface> imgSurface = new gfxImageSurface(
     gfxIntSize(bmWidth, bmHeight), 
     gfxImageFormat::ARGB32);
   if (!imgSurface)
     return false;
 
-  RefPtr<DrawTarget> dt =
-    gfxPlatform::GetPlatform()->
-      CreateDrawTargetForSurface(imgSurface, IntSize(bmWidth, bmHeight));
-  if (!dt)
+  nsRefPtr<gfxContext> context = new gfxContext(imgSurface);
+  if (!context)
     return false;
 
-  dt->FillRect(Rect(0, 0, bmWidth, bmHeight),
-               SurfacePattern(surface, ExtendMode::CLAMP),
-               DrawOptions(1.0f, CompositionOp::OP_SOURCE));
+  context->SetOperator(gfxContext::OPERATOR_SOURCE);
+  context->SetSource(surface);
+  context->Paint();
 
   BITMAPV5HEADER bmih;
   memset((void*)&bmih, 0, sizeof(BITMAPV5HEADER));
   bmih.bV5Size        = sizeof(BITMAPV5HEADER);
   bmih.bV5Width       = bmWidth;
   bmih.bV5Height      = -(int32_t)bmHeight; // flip vertical
   bmih.bV5Planes      = 1;
   bmih.bV5BitCount    = 32;
@@ -151,18 +139,16 @@ nsDragService::CreateDragImage(nsIDOMNod
       ConvertToUnscaledDevPixels(pc, &sx, &sy);
       psdi->ptOffset.x = sx - dragRect.x;
       psdi->ptOffset.y = sy - dragRect.y;
     }
 
     DeleteDC(hdcSrc);
   }
 
-  data->Unmap();
-
   return psdi->hbmpDragImage != nullptr;
 }
 
 //-------------------------------------------------------------------------
 NS_IMETHODIMP
 nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode,
                                  nsISupportsArray *anArrayTransferables,
                                  nsIScriptableRegion *aRegion,
--- a/widget/xpwidgets/nsBaseDragService.cpp
+++ b/widget/xpwidgets/nsBaseDragService.cpp
@@ -29,24 +29,22 @@
 #include "nsIImageLoadingContent.h"
 #include "imgIContainer.h"
 #include "imgIRequest.h"
 #include "nsRegion.h"
 #include "nsXULPopupManager.h"
 #include "nsMenuPopupFrame.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/Preferences.h"
-#include "mozilla/gfx/2D.h"
 
 #include "gfxContext.h"
 #include "gfxPlatform.h"
 #include <algorithm>
 
 using namespace mozilla;
-using namespace mozilla::gfx;
 
 #define DRAGIMAGES_PREF "nglayout.enable_drag_images"
 
 nsBaseDragService::nsBaseDragService()
   : mCanDrop(false), mOnlyChromeDrop(false), mDoingDrag(false),
     mHasImage(false), mUserCancelled(false),
     mDragAction(DRAGDROP_ACTION_NONE), mTargetSize(0,0),
     mImageX(0), mImageY(0), mScreenX(-1), mScreenY(-1), mSuppressLevel(0),
@@ -423,17 +421,17 @@ GetPresShellForContent(nsIDOMNode* aDOMN
   return nullptr;
 }
 
 nsresult
 nsBaseDragService::DrawDrag(nsIDOMNode* aDOMNode,
                             nsIScriptableRegion* aRegion,
                             int32_t aScreenX, int32_t aScreenY,
                             nsIntRect* aScreenDragRect,
-                            RefPtr<SourceSurface>* aSurface,
+                            gfxASurface** aSurface,
                             nsPresContext** aPresContext)
 {
   *aSurface = nullptr;
   *aPresContext = nullptr;
 
   // use a default size, in case of an error.
   aScreenDragRect->x = aScreenX - mImageX;
   aScreenDragRect->y = aScreenY - mImageY;
@@ -494,17 +492,19 @@ nsBaseDragService::DrawDrag(nsIDOMNode* 
     }
 
     return NS_OK;
   }
 
   // draw the image for selections
   if (mSelection) {
     nsIntPoint pnt(aScreenDragRect->x, aScreenDragRect->y);
-    *aSurface = presShell->RenderSelection(mSelection, pnt, aScreenDragRect);
+    nsRefPtr<gfxASurface> surface = presShell->RenderSelection(mSelection, pnt, aScreenDragRect);
+    *aSurface = surface;
+    NS_IF_ADDREF(*aSurface);
     return NS_OK;
   }
 
   // if a custom image was specified, check if it is an image node and draw
   // using the source rather than the displayed image. But if mImage isn't
   // an image or canvas, fall through to RenderNode below.
   if (mImage) {
     nsCOMPtr<nsICanvasElementExternal> canvas = do_QueryInterface(dragNode);
@@ -527,45 +527,49 @@ nsBaseDragService::DrawDrag(nsIDOMNode* 
 
     nsCOMPtr<nsIContent> content = do_QueryInterface(dragNode);
     nsIFrame* frame = content->GetPrimaryFrame();
     if (frame && frame->GetType() == nsGkAtoms::menuPopupFrame) {
       mDragPopup = content;
     }
   }
 
+  nsRefPtr<gfxASurface> surface;
   if (!mDragPopup) {
     // otherwise, just draw the node
     nsIntRegion clipRegion;
     if (aRegion) {
       aRegion->GetRegion(&clipRegion);
     }
 
     nsIntPoint pnt(aScreenDragRect->x, aScreenDragRect->y);
-    *aSurface = presShell->RenderNode(dragNode, aRegion ? &clipRegion : nullptr,
-                                      pnt, aScreenDragRect);
+    surface = presShell->RenderNode(dragNode, aRegion ? &clipRegion : nullptr,
+                                    pnt, aScreenDragRect);
   }
 
   // if an image was specified, reposition the drag rectangle to
   // the supplied offset in mImageX and mImageY.
   if (mImage) {
     aScreenDragRect->x = sx - mImageX;
     aScreenDragRect->y = sy - mImageY;
   }
 
+  *aSurface = surface;
+  NS_IF_ADDREF(*aSurface);
+
   return NS_OK;
 }
 
 nsresult
 nsBaseDragService::DrawDragForImage(nsPresContext* aPresContext,
                                     nsIImageLoadingContent* aImageLoader,
                                     nsICanvasElementExternal* aCanvas,
                                     int32_t aScreenX, int32_t aScreenY,
                                     nsIntRect* aScreenDragRect,
-                                    RefPtr<SourceSurface>* aSurface)
+                                    gfxASurface** aSurface)
 {
   nsCOMPtr<imgIContainer> imgContainer;
   if (aImageLoader) {
     nsCOMPtr<imgIRequest> imgRequest;
     nsresult rv = aImageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
                                           getter_AddRefs(imgRequest));
     NS_ENSURE_SUCCESS(rv, rv);
     if (!imgRequest)
@@ -611,43 +615,41 @@ nsBaseDragService::DrawDragForImage(nsPr
     destSize.height = NSToIntFloor(float(destSize.height) * scale);
 
     aScreenDragRect->x = NSToIntFloor(aScreenX - float(mImageX) * scale);
     aScreenDragRect->y = NSToIntFloor(aScreenY - float(mImageY) * scale);
     aScreenDragRect->width = destSize.width;
     aScreenDragRect->height = destSize.height;
   }
 
-  RefPtr<DrawTarget> dt =
-    gfxPlatform::GetPlatform()->
-      CreateOffscreenContentDrawTarget(IntSize(destSize.width, destSize.height),
-
-                                       SurfaceFormat::B8G8R8A8);
-  if (!dt)
+  nsRefPtr<gfxASurface> surface =
+    gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(destSize.width, destSize.height),
+                                                       gfxContentType::COLOR_ALPHA);
+  if (!surface)
     return NS_ERROR_FAILURE;
 
-  nsRefPtr<gfxContext> ctx = new gfxContext(dt);
+  nsRefPtr<gfxContext> ctx = new gfxContext(surface);
   if (!ctx)
     return NS_ERROR_FAILURE;
 
-  nsresult result = NS_OK;
+  *aSurface = surface;
+  NS_ADDREF(*aSurface);
+
   if (aImageLoader) {
     gfxRect outRect(0, 0, destSize.width, destSize.height);
     gfxMatrix scale =
       gfxMatrix().Scale(srcSize.width/outRect.Width(), srcSize.height/outRect.Height());
     nsIntRect imgSize(0, 0, srcSize.width, srcSize.height);
     imgContainer->Draw(ctx, GraphicsFilter::FILTER_GOOD, scale, outRect, imgSize,
                        destSize, nullptr, imgIContainer::FRAME_CURRENT,
                        imgIContainer::FLAG_SYNC_DECODE);
+    return NS_OK;
   } else {
-    result = aCanvas->RenderContextsExternal(ctx, GraphicsFilter::FILTER_GOOD);
+    return aCanvas->RenderContextsExternal(ctx, GraphicsFilter::FILTER_GOOD);
   }
-
-  *aSurface = dt->Snapshot();
-  return result;
 }
 
 void
 nsBaseDragService::ConvertToUnscaledDevPixels(nsPresContext* aPresContext,
                                               int32_t* aScreenX, int32_t* aScreenY)
 {
   int32_t adj = aPresContext->DeviceContext()->UnscaledAppUnitsPerDevPixel();
   *aScreenX = nsPresContext::CSSPixelsToAppUnits(*aScreenX) / adj;
--- a/widget/xpwidgets/nsBaseDragService.h
+++ b/widget/xpwidgets/nsBaseDragService.h
@@ -8,47 +8,38 @@
 
 #include "nsIDragService.h"
 #include "nsIDragSession.h"
 #include "nsITransferable.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMDataTransfer.h"
 #include "nsCOMPtr.h"
 #include "nsPoint.h"
-#include "mozilla/RefPtr.h"
 
 #include "gfxImageSurface.h"
 
 // translucency level for drag images
 #define DRAG_TRANSLUCENCY 0.65
 
 class nsIContent;
 class nsIDOMNode;
 class nsIFrame;
 class nsPresContext;
 class nsIImageLoadingContent;
 class nsICanvasElementExternal;
 
-namespace mozilla {
-namespace gfx {
-class SourceSurface;
-}
-}
-
 /**
  * XP DragService wrapper base class
  */
 
 class nsBaseDragService : public nsIDragService,
                           public nsIDragSession
 {
 
 public:
-  typedef mozilla::gfx::SourceSurface SourceSurface;
-
   nsBaseDragService();
   virtual ~nsBaseDragService();
 
   //nsISupports
   NS_DECL_ISUPPORTS
 
   //nsIDragSession and nsIDragService
   NS_DECL_NSIDRAGSERVICE
@@ -81,29 +72,29 @@ protected:
    *
    * aPresContext will be set to the nsPresContext used determined from
    * whichever of mImage or aDOMNode is used.
    */
   nsresult DrawDrag(nsIDOMNode* aDOMNode,
                     nsIScriptableRegion* aRegion,
                     int32_t aScreenX, int32_t aScreenY,
                     nsIntRect* aScreenDragRect,
-                    mozilla::RefPtr<SourceSurface>* aSurface,
+                    gfxASurface** aSurface,
                     nsPresContext **aPresContext);
 
   /**
    * Draw a drag image for an image node specified by aImageLoader or aCanvas.
    * This is called by DrawDrag.
    */
   nsresult DrawDragForImage(nsPresContext* aPresContext,
                             nsIImageLoadingContent* aImageLoader,
                             nsICanvasElementExternal* aCanvas,
                             int32_t aScreenX, int32_t aScreenY,
                             nsIntRect* aScreenDragRect,
-                            mozilla::RefPtr<SourceSurface>* aSurface);
+                            gfxASurface** aSurface);
 
   /**
    * Convert aScreenX and aScreenY from CSS pixels into unscaled device pixels.
    */
   void
   ConvertToUnscaledDevPixels(nsPresContext* aPresContext,
                              int32_t* aScreenX, int32_t* aScreenY);