Bug 1473029, convert drag services to internally use CSSIntRegion instead ns nsIScriptableRegion, r=mstange
authorNeil Deakin <neil@mozilla.com>
Tue, 07 Aug 2018 09:32:08 -0400
changeset 488462 8727297a02487d109bf96fecd992375b5e1d31bb
parent 488461 b2955b86592b030822d771f990c155b2dee75e08
child 488463 74554b2b65bf79fe3682ed6176e4f524a131e4fd
push id1815
push userffxbld-merge
push dateMon, 15 Oct 2018 10:40:45 +0000
treeherdermozilla-release@18d4c09e9378 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1473029
milestone63.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 1473029, convert drag services to internally use CSSIntRegion instead ns nsIScriptableRegion, r=mstange
layout/base/PresShell.cpp
layout/base/PresShell.h
layout/base/nsIPresShell.h
widget/cocoa/nsDragService.h
widget/cocoa/nsDragService.mm
widget/gtk/nsDragService.cpp
widget/gtk/nsDragService.h
widget/nsBaseDragService.cpp
widget/nsBaseDragService.h
widget/nsDragServiceProxy.cpp
widget/nsDragServiceProxy.h
widget/windows/nsDragService.cpp
widget/windows/nsDragService.h
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -4971,17 +4971,17 @@ PresShell::CreateRangePaintInfo(nsRange*
   aSurfaceRect.UnionRect(aSurfaceRect, rangeRect);
 
   return info;
 }
 
 already_AddRefed<SourceSurface>
 PresShell::PaintRangePaintInfo(const nsTArray<UniquePtr<RangePaintInfo>>& aItems,
                                Selection* aSelection,
-                               nsIntRegion* aRegion,
+                               const Maybe<CSSIntRegion>& aRegion,
                                nsRect aArea,
                                const LayoutDeviceIntPoint aPoint,
                                LayoutDeviceIntRect* aScreenRect,
                                uint32_t aFlags)
 {
   nsPresContext* pc = GetPresContext();
   if (!pc || aArea.width == 0 || aArea.height == 0)
     return nullptr;
@@ -5068,20 +5068,20 @@ PresShell::PaintRangePaintInfo(const nsT
   RefPtr<gfxContext> ctx = gfxContext::CreateOrNull(dt);
   MOZ_ASSERT(ctx); // already checked the draw target above
 
   if (aRegion) {
     RefPtr<PathBuilder> builder = dt->CreatePathBuilder(FillRule::FILL_WINDING);
 
     // Convert aRegion from CSS pixels to dev pixels
     nsIntRegion region =
-      aRegion->ToAppUnits(nsPresContext::AppUnitsPerCSSPixel())
-        .ToOutsidePixels(pc->AppUnitsPerDevPixel());
+        aRegion->ToAppUnits(nsPresContext::AppUnitsPerCSSPixel())
+          .ToOutsidePixels(pc->AppUnitsPerDevPixel());
     for (auto iter = region.RectIter(); !iter.Done(); iter.Next()) {
-      const nsIntRect& rect = iter.Get();
+      const IntRect& rect = iter.Get();
 
       builder->MoveTo(rect.TopLeft());
       builder->LineTo(rect.TopRight());
       builder->LineTo(rect.BottomRight());
       builder->LineTo(rect.BottomLeft());
       builder->LineTo(rect.TopLeft());
     }
 
@@ -5131,17 +5131,17 @@ PresShell::PaintRangePaintInfo(const nsT
   // restore the old selection display state
   frameSelection->SetDisplaySelection(oldDisplaySelection);
 
   return dt->Snapshot();
 }
 
 already_AddRefed<SourceSurface>
 PresShell::RenderNode(nsINode* aNode,
-                      nsIntRegion* aRegion,
+                      const Maybe<CSSIntRegion>& aRegion,
                       const LayoutDeviceIntPoint aPoint,
                       LayoutDeviceIntRect* aScreenRect,
                       uint32_t aFlags)
 {
   // area will hold the size of the surface needed to draw the node, measured
   // from the root frame.
   nsRect area;
   nsTArray<UniquePtr<RangePaintInfo>> rangeItems;
@@ -5158,33 +5158,34 @@ PresShell::RenderNode(nsINode* aNode,
     return nullptr;
   }
 
   UniquePtr<RangePaintInfo> info = CreateRangePaintInfo(range, area, false);
   if (info && !rangeItems.AppendElement(std::move(info))) {
     return nullptr;
   }
 
-  if (aRegion) {
+  Maybe<CSSIntRegion> region = aRegion;
+  if (region) {
     // combine the area with the supplied region
-    nsIntRect rrectPixels = aRegion->GetBounds();
+    CSSIntRect rrectPixels = region->GetBounds();
 
     nsRect rrect = ToAppUnits(rrectPixels, nsPresContext::AppUnitsPerCSSPixel());
     area.IntersectRect(area, rrect);
 
     nsPresContext* pc = GetPresContext();
     if (!pc)
       return nullptr;
 
     // move the region so that it is offset from the topleft corner of the surface
-    aRegion->MoveBy(-nsPresContext::AppUnitsToIntCSSPixels(area.x),
-                    -nsPresContext::AppUnitsToIntCSSPixels(area.y));
-  }
-
-  return PaintRangePaintInfo(rangeItems, nullptr, aRegion, area, aPoint,
+    region->MoveBy(-nsPresContext::AppUnitsToIntCSSPixels(area.x),
+                   -nsPresContext::AppUnitsToIntCSSPixels(area.y));
+  }
+
+  return PaintRangePaintInfo(rangeItems, nullptr, region, area, aPoint,
                              aScreenRect, aFlags);
 }
 
 already_AddRefed<SourceSurface>
 PresShell::RenderSelection(Selection* aSelection,
                            const LayoutDeviceIntPoint aPoint,
                            LayoutDeviceIntRect* aScreenRect,
                            uint32_t aFlags)
@@ -5205,17 +5206,17 @@ PresShell::RenderSelection(Selection* aS
     RefPtr<nsRange> range = aSelection->GetRangeAt(r);
 
     UniquePtr<RangePaintInfo> info = CreateRangePaintInfo(range, area, true);
     if (info && !rangeItems.AppendElement(std::move(info))) {
       return nullptr;
     }
   }
 
-  return PaintRangePaintInfo(rangeItems, aSelection, nullptr, area, aPoint,
+  return PaintRangePaintInfo(rangeItems, aSelection, Nothing(), area, aPoint,
                              aScreenRect, aFlags);
 }
 
 void
 PresShell::AddPrintPreviewBackgroundItem(nsDisplayListBuilder& aBuilder,
                                          nsDisplayList&        aList,
                                          nsIFrame*             aFrame,
                                          const nsRect&         aBounds)
--- a/layout/base/PresShell.h
+++ b/layout/base/PresShell.h
@@ -186,17 +186,17 @@ public:
 
   nsresult RenderDocument(const nsRect& aRect,
                           uint32_t aFlags,
                           nscolor aBackgroundColor,
                           gfxContext* aThebesContext) override;
 
   already_AddRefed<SourceSurface>
   RenderNode(nsINode* aNode,
-             nsIntRegion* aRegion,
+             const Maybe<CSSIntRegion>& aRegion,
              const LayoutDeviceIntPoint aPoint,
              LayoutDeviceIntRect* aScreenRect,
              uint32_t aFlags) override;
 
   already_AddRefed<SourceSurface>
   RenderSelection(dom::Selection* aSelection,
                   const LayoutDeviceIntPoint aPoint,
                   LayoutDeviceIntRect* aScreenRect,
@@ -538,17 +538,17 @@ private:
    * aScreenRect - [out] set to the area of the screen the painted area should
    *               be displayed at
    * aFlags - set RENDER_AUTO_SCALE to scale down large images, but it must not
    *          be set if a custom image was specified
    */
   already_AddRefed<SourceSurface>
   PaintRangePaintInfo(const nsTArray<UniquePtr<RangePaintInfo>>& aItems,
                       dom::Selection* aSelection,
-                      nsIntRegion* aRegion,
+                      const Maybe<CSSIntRegion>& aRegion,
                       nsRect aArea,
                       const LayoutDeviceIntPoint aPoint,
                       LayoutDeviceIntRect* aScreenRect,
                       uint32_t aFlags);
 
   /**
    * Methods to handle changes to user and UA sheet lists that we get
    * notified about.
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -1157,17 +1157,17 @@ public:
   /**
    * 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 aFlags arguments
    * function in a similar manner as RenderSelection.
    */
   virtual already_AddRefed<mozilla::gfx::SourceSurface>
   RenderNode(nsINode* aNode,
-             nsIntRegion* aRegion,
+             const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
              const mozilla::LayoutDeviceIntPoint aPoint,
              mozilla::LayoutDeviceIntRect* aScreenRect,
              uint32_t aFlags) = 0;
 
   /**
    * Renders a selection to a surface and returns it. This method is primarily
    * intended to create the drag feedback when dragging a selection.
    *
--- a/widget/cocoa/nsDragService.h
+++ b/widget/cocoa/nsDragService.h
@@ -20,17 +20,17 @@ extern NSString* const kMozFileUrlsPboar
 
 class nsDragService : public nsBaseDragService
 {
 public:
   nsDragService();
 
   // nsBaseDragService
   virtual nsresult InvokeDragSessionImpl(nsIArray* anArrayTransferables,
-                                         nsIScriptableRegion* aRegion,
+                                         const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
                                          uint32_t aActionType) override;
   // nsIDragService
   NS_IMETHOD EndDragSession(bool aDoneDrag, uint32_t aKeyModifiers) override;
   NS_IMETHOD UpdateDragImage(nsINode* aImage, int32_t aImageX, int32_t aImageY) override;
 
   // nsIDragSession
   NS_IMETHOD GetData(nsITransferable * aTransferable, uint32_t aItemIndex) override;
   NS_IMETHOD IsDataFlavorSupported(const char *aDataFlavor, bool *_retval) override;
@@ -41,24 +41,24 @@ public:
 protected:
   virtual ~nsDragService();
 
 private:
 
   // Creates and returns the drag image for a drag. aImagePoint will be set to
   // the origin of the drag relative to mNativeDragView.
   NSImage* ConstructDragImage(nsINode* aDOMNode,
-                              nsIScriptableRegion* aRegion,
+                              const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
                               NSPoint* aImagePoint);
 
   // Creates and returns the drag image for a drag. aPoint should be the origin
   // of the drag, for example the mouse coordinate of the mousedown event.
   // aDragRect will be set the area of the drag relative to this.
   NSImage* ConstructDragImage(nsINode* aDOMNode,
-                              nsIScriptableRegion* aRegion,
+                              const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
                               mozilla::CSSIntPoint aPoint,
                               mozilla::LayoutDeviceIntRect* aDragRect);
 
   bool IsValidType(NSString* availableType, bool allowFileURL);
   NSString* GetStringForType(NSPasteboardItem* item, const NSString* type,
                              bool allowFileURL = false);
   NSString* GetTitleForURL(NSPasteboardItem* item);
   NSString* GetFilePath(NSPasteboardItem* item);
--- a/widget/cocoa/nsDragService.mm
+++ b/widget/cocoa/nsDragService.mm
@@ -61,17 +61,17 @@ nsDragService::nsDragService()
 }
 
 nsDragService::~nsDragService()
 {
 }
 
 NSImage*
 nsDragService::ConstructDragImage(nsINode* aDOMNode,
-                                  nsIScriptableRegion* aRegion,
+                                  const Maybe<CSSIntRegion>& aRegion,
                                   NSPoint* aDragPoint)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
   CGFloat scaleFactor = nsCocoaUtils::GetBackingScaleFactor(mNativeDragView);
 
   LayoutDeviceIntRect dragRect(0, 0, 20, 20);
   NSImage* image = ConstructDragImage(mSourceNode, aRegion, mScreenPosition, &dragRect);
@@ -103,17 +103,17 @@ nsDragService::ConstructDragImage(nsINod
 
   return image;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 NSImage*
 nsDragService::ConstructDragImage(nsINode* aDOMNode,
-                                  nsIScriptableRegion* aRegion,
+                                  const Maybe<CSSIntRegion>& aRegion,
                                   CSSIntPoint aPoint,
                                   LayoutDeviceIntRect* aDragRect)
  {
    NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
   CGFloat scaleFactor = nsCocoaUtils::GetBackingScaleFactor(mNativeDragView);
 
   RefPtr<SourceSurface> surface;
@@ -279,17 +279,17 @@ nsDragService::GetFilePath(NSPasteboardI
 
   return nil;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 nsresult
 nsDragService::InvokeDragSessionImpl(nsIArray* aTransferableArray,
-                                     nsIScriptableRegion* aDragRgn,
+                                     const Maybe<CSSIntRegion>& aRegion,
                                      uint32_t aActionType)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   if (!gLastDragView) {
     // gLastDragView is only set during -[ChildView mouseDragged:].
     // InvokeDragSessionImpl is only called while Gecko processes a mouse move
     // event. So if we get here with gLastDragView being null, that means that
@@ -339,17 +339,17 @@ nsDragService::InvokeDragSessionImpl(nsI
       // consider it. Add our wildcard type to the pasteboard to accomplish
       // this.
       [types addObject:[UTIHelper stringFromPboardType:kMozWildcardPboardType]];
     }
   }
   [pbItem setDataProvider:mNativeDragView forTypes:types];
 
   NSPoint draggingPoint;
-  NSImage* image = ConstructDragImage(mSourceNode, aDragRgn, &draggingPoint);
+  NSImage* image = ConstructDragImage(mSourceNode, aRegion, &draggingPoint);
 
   NSRect localDragRect = image.alignmentRect;
   localDragRect.origin.x = draggingPoint.x;
   localDragRect.origin.y = draggingPoint.y - localDragRect.size.height;
 
   NSDraggingItem* dragItem =
     [[NSDraggingItem alloc] initWithPasteboardWriter:pbItem];
   [pbItem release];
@@ -707,17 +707,17 @@ nsDragService::DragMovedWithView(NSDragg
 
         nsPoint pt = LayoutDevicePixel::ToAppUnits(devPoint,
                        pc->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom());
         CSSIntPoint screenPoint = CSSIntPoint(nsPresContext::AppUnitsToIntCSSPixels(pt.x),
                                               nsPresContext::AppUnitsToIntCSSPixels(pt.y));
 
         // Create a new image; if one isn't returned don't change the current one.
         LayoutDeviceIntRect newRect;
-        NSImage* image = ConstructDragImage(mSourceNode, nullptr, screenPoint, &newRect);
+        NSImage* image = ConstructDragImage(mSourceNode, Nothing(), screenPoint, &newRect);
         if (image) {
           NSRect draggingRect = nsCocoaUtils::GeckoRectToCocoaRectDevPix(newRect, scaleFactor);
           [draggingItem setDraggingFrame:draggingRect contents:image];
         }
       };
 
       [aSession enumerateDraggingItemsWithOptions:NSDraggingItemEnumerationConcurrent
                                           forView:nil
--- a/widget/gtk/nsDragService.cpp
+++ b/widget/gtk/nsDragService.cpp
@@ -329,17 +329,17 @@ nsDragService::InvokeDragSession(nsINode
                                                 aArrayTransferables,
                                                 aActionType,
                                                 aContentPolicyType);
 }
 
 // nsBaseDragService
 nsresult
 nsDragService::InvokeDragSessionImpl(nsIArray* aArrayTransferables,
-                                     nsIScriptableRegion* aRegion,
+                                     const Maybe<CSSIntRegion>& aRegion,
                                      uint32_t aActionType)
 {
     // make sure that we have an array of transferables to use
     if (!aArrayTransferables)
         return NS_ERROR_INVALID_ARG;
     // set our reference to the transferables.  this will also addref
     // the transferables since we're going to hang onto this beyond the
     // length of this call
@@ -1712,18 +1712,18 @@ nsDragService::SourceDataGet(GtkWidget  
 void nsDragService::SetDragIcon(GdkDragContext* aContext)
 {
     if (!mHasImage && !mSelection)
         return;
 
     LayoutDeviceIntRect dragRect;
     nsPresContext* pc;
     RefPtr<SourceSurface> surface;
-    DrawDrag(mSourceNode, mRegion, mScreenPosition,
-             &dragRect, &surface, &pc);
+    DrawDrag(mSourceNode, mRegion,
+             mScreenPosition, &dragRect, &surface, &pc);
     if (!pc)
         return;
 
     LayoutDeviceIntPoint screenPoint =
       ConvertToUnscaledDevPixels(pc, mScreenPosition);
     int32_t offsetX = screenPoint.x - dragRect.x;
     int32_t offsetY = screenPoint.y - dragRect.y;
 
--- a/widget/gtk/nsDragService.h
+++ b/widget/gtk/nsDragService.h
@@ -56,17 +56,17 @@ public:
     nsDragService();
 
     NS_DECL_ISUPPORTS_INHERITED
 
     NS_DECL_NSIOBSERVER
 
     // nsBaseDragService
     virtual nsresult InvokeDragSessionImpl(nsIArray* anArrayTransferables,
-                                           nsIScriptableRegion* aRegion,
+                                           const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
                                            uint32_t aActionType) override;
     // nsIDragService
     NS_IMETHOD InvokeDragSession (nsINode *aDOMNode,
                                   const nsACString& aPrincipalURISpec,
                                   nsIArray * anArrayTransferables,
                                   uint32_t aActionType,
                                   nsContentPolicyType aContentPolicyType) override;
     NS_IMETHOD StartDragSession() override;
--- a/widget/nsBaseDragService.cpp
+++ b/widget/nsBaseDragService.cpp
@@ -58,18 +58,17 @@ using namespace mozilla::image;
 
 nsBaseDragService::nsBaseDragService()
   : mCanDrop(false), mOnlyChromeDrop(false), mDoingDrag(false),
     mHasImage(false), mUserCancelled(false),
     mDragEventDispatchedToChildProcess(false),
     mDragAction(DRAGDROP_ACTION_NONE),
     mDragActionFromChildProcess(DRAGDROP_ACTION_UNINITIALIZED), mTargetSize(0,0),
     mContentPolicyType(nsIContentPolicy::TYPE_OTHER),
-    mSuppressLevel(0), mInputSource(MouseEvent_Binding::MOZ_SOURCE_MOUSE),
-    mRegion(nullptr)
+    mSuppressLevel(0), mInputSource(MouseEvent_Binding::MOZ_SOURCE_MOUSE)
 {
 }
 
 nsBaseDragService::~nsBaseDragService() = default;
 
 NS_IMPL_ISUPPORTS(nsBaseDragService, nsIDragService, nsIDragSession)
 
 //---------------------------------------------------------
@@ -297,35 +296,41 @@ nsBaseDragService::InvokeDragSessionWith
   mScreenPosition.y = aDragEvent->ScreenY(CallerType::System);
   mInputSource = aDragEvent->MozInputSource();
 
   // If dragging within a XUL tree and no custom drag image was
   // set, the region argument to InvokeDragSessionWithImage needs
   // to be set to the area encompassing the selected rows of the
   // tree to ensure that the drag feedback gets clipped to those
   // rows. For other content, region should be null.
-  mRegion = nullptr;
+  mRegion = Nothing();
 #ifdef MOZ_XUL
   if (aDOMNode && aDOMNode->IsContent() && !aImage) {
     if (aDOMNode->NodeInfo()->Equals(nsGkAtoms::treechildren,
                                      kNameSpaceID_XUL)) {
       nsTreeBodyFrame* treeBody =
         do_QueryFrame(aDOMNode->AsContent()->GetPrimaryFrame());
       if (treeBody) {
-        treeBody->GetSelectionRegion(getter_AddRefs(mRegion));
+        nsCOMPtr<nsIScriptableRegion> region;
+        treeBody->GetSelectionRegion(getter_AddRefs(region));
+        if (region) {
+          nsIntRegion intRegion;
+          region->GetRegion(&intRegion);
+          mRegion.emplace(CSSIntRegion::FromUnknownRegion(intRegion));
+        }
       }
     }
   }
 #endif
 
   nsresult rv = InvokeDragSession(aDOMNode, aPrincipalURISpec,
                                   aTransferableArray,
                                   aActionType,
                                   nsIContentPolicy::TYPE_INTERNAL_IMAGE);
-  mRegion = nullptr;
+  mRegion = Nothing();
   return rv;
 }
 
 NS_IMETHODIMP
 nsBaseDragService::InvokeDragSessionWithSelection(Selection* aSelection,
                                                   const nsACString& aPrincipalURISpec,
                                                   nsIArray* aTransferableArray,
                                                   uint32_t aActionType,
@@ -337,17 +342,17 @@ nsBaseDragService::InvokeDragSessionWith
   NS_ENSURE_TRUE(mSuppressLevel == 0, NS_ERROR_FAILURE);
 
   mDataTransfer = aDataTransfer;
   mSelection = aSelection;
   mHasImage = true;
   mDragPopup = nullptr;
   mImage = nullptr;
   mImageOffset = CSSIntPoint();
-  mRegion = nullptr;
+  mRegion = Nothing();
 
   mScreenPosition.x = aDragEvent->ScreenX(CallerType::System);
   mScreenPosition.y = aDragEvent->ScreenY(CallerType::System);
   mInputSource = aDragEvent->MozInputSource();
 
   // just get the focused node from the selection
   // XXXndeakin this should actually be the deepest node that contains both
   // endpoints of the selection
@@ -468,17 +473,17 @@ nsBaseDragService::EndDragSession(bool a
   mHasImage = false;
   mUserCancelled = false;
   mDragPopup = nullptr;
   mImage = nullptr;
   mImageOffset = CSSIntPoint();
   mScreenPosition = CSSIntPoint();
   mEndDragPoint = LayoutDeviceIntPoint(0, 0);
   mInputSource = MouseEvent_Binding::MOZ_SOURCE_MOUSE;
-  mRegion = nullptr;
+  mRegion = Nothing();
 
   return NS_OK;
 }
 
 void
 nsBaseDragService::DiscardInternalTransferData()
 {
   if (mDataTransfer && mSourceNode) {
@@ -568,17 +573,17 @@ GetPresShellForContent(nsINode* aDOMNode
     return document->GetShell();
   }
 
   return nullptr;
 }
 
 nsresult
 nsBaseDragService::DrawDrag(nsINode* aDOMNode,
-                            nsIScriptableRegion* aRegion,
+                            const Maybe<CSSIntRegion>& aRegion,
                             CSSIntPoint aScreenPosition,
                             LayoutDeviceIntRect* aScreenDragRect,
                             RefPtr<SourceSurface>* aSurface,
                             nsPresContext** aPresContext)
 {
   *aSurface = nullptr;
   *aPresContext = nullptr;
 
@@ -628,19 +633,17 @@ nsBaseDragService::DrawDrag(nsINode* aDO
 
   // didn't want an image, so just set the screen rectangle to the frame size
   if (!enableDragImages || !mHasImage) {
     // if a region was specified, set the screen rectangle to the area that
     // the region occupies
     CSSIntRect dragRect;
     if (aRegion) {
       // the region's coordinates are relative to the root frame
-      int32_t dragRectX, dragRectY, dragRectW, dragRectH;
-      aRegion->GetBoundingBox(&dragRectX, &dragRectY, &dragRectW, &dragRectH);
-      dragRect.SetRect(dragRectX, dragRectY, dragRectW, dragRectH);
+      dragRect = aRegion->GetBounds();
 
       nsIFrame* rootFrame = presShell->GetRootFrame();
       CSSIntRect screenRect = rootFrame->GetScreenRect();
       dragRect.MoveBy(screenRect.TopLeft());
     }
     else {
       // otherwise, there was no region so just set the rectangle to
       // the size of the primary frame of the content.
@@ -690,22 +693,17 @@ nsBaseDragService::DrawDrag(nsINode* aDO
     nsIFrame* frame = content->GetPrimaryFrame();
     if (frame && frame->IsMenuPopupFrame()) {
       mDragPopup = content;
     }
   }
 
   if (!mDragPopup) {
     // otherwise, just draw the node
-    nsIntRegion clipRegion;
     uint32_t renderFlags = mImage ? 0 : nsIPresShell::RENDER_AUTO_SCALE;
-    if (aRegion) {
-      aRegion->GetRegion(&clipRegion);
-    }
-
     if (renderFlags) {
       nsCOMPtr<nsINode> dragINode = do_QueryInterface(dragNode);
       // check if the dragged node itself is an img element
       if (dragINode->NodeName().LowerCaseEqualsLiteral("img")) {
         renderFlags = renderFlags | nsIPresShell::RENDER_IS_IMAGE;
       } else {
         nsINodeList* childList = dragINode->ChildNodes();
         uint32_t length = childList->Length();
@@ -716,17 +714,17 @@ nsBaseDragService::DrawDrag(nsINode* aDO
             // if the dragnode contains an image, set RENDER_IS_IMAGE flag
             renderFlags = renderFlags | nsIPresShell::RENDER_IS_IMAGE;
             break;
           }
         }
       }
     }
     LayoutDeviceIntPoint pnt(aScreenDragRect->TopLeft());
-    *aSurface = presShell->RenderNode(dragNode, aRegion ? &clipRegion : nullptr,
+    *aSurface = presShell->RenderNode(dragNode, aRegion,
                                       pnt, aScreenDragRect,
                                       renderFlags);
   }
 
   // If an image was specified, reset the position from the offset that was supplied.
   if (mImage) {
     aScreenDragRect->MoveTo(screenPoint.x, screenPoint.y);
   }
--- a/widget/nsBaseDragService.h
+++ b/widget/nsBaseDragService.h
@@ -13,16 +13,17 @@
 #include "nsCOMPtr.h"
 #include "nsRect.h"
 #include "nsPoint.h"
 #include "nsString.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/HTMLCanvasElement.h"
 #include "nsTArray.h"
+#include "nsRegion.h"
 #include "Units.h"
 
 // translucency level for drag images
 #define DRAG_TRANSLUCENCY 0.65
 
 class nsIContent;
 class nsIDocument;
 class nsINode;
@@ -77,17 +78,17 @@ protected:
   virtual ~nsBaseDragService();
 
   /**
    * Called from nsBaseDragService to initiate a platform drag from a source
    * in this process.  This is expected to ensure that StartDragSession() and
    * EndDragSession() get called if the platform drag is successfully invoked.
    */
   virtual nsresult InvokeDragSessionImpl(nsIArray* aTransferableArray,
-                                         nsIScriptableRegion* aDragRgn,
+                                         const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
                                          uint32_t aActionType) = 0;
 
   /**
    * Draw the drag image, if any, to a surface and return it. The drag image
    * is constructed from mImage if specified, or aDOMNode if mImage is null.
    *
    * aRegion may be used to draw only a subset of the element. This region
    * should be supplied using x and y coordinates measured in css pixels
@@ -103,17 +104,17 @@ protected:
    *
    * If there is no drag image, the returned surface will be null, but
    * aScreenDragRect will still be set to the drag area.
    *
    * aPresContext will be set to the nsPresContext used determined from
    * whichever of mImage or aDOMNode is used.
    */
   nsresult DrawDrag(nsINode* aDOMNode,
-                    nsIScriptableRegion* aRegion,
+                    const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
                     mozilla::CSSIntPoint aScreenPosition,
                     mozilla::LayoutDeviceIntRect* aScreenDragRect,
                     RefPtr<SourceSurface>* aSurface,
                     nsPresContext **aPresContext);
 
   /**
    * Draw a drag image for an image node specified by aImageLoader or aCanvas.
    * This is called by DrawDrag.
@@ -194,12 +195,12 @@ protected:
   uint32_t mSuppressLevel;
 
   // The input source of the drag event. Possible values are from MouseEvent.
   uint16_t mInputSource;
 
   nsTArray<RefPtr<mozilla::dom::ContentParent>> mChildProcesses;
 
   // Sub-region for tree-selections.
-  nsCOMPtr<nsIScriptableRegion> mRegion;
+  mozilla::Maybe<mozilla::CSSIntRegion> mRegion;
 };
 
 #endif // nsBaseDragService_h__
--- a/widget/nsDragServiceProxy.cpp
+++ b/widget/nsDragServiceProxy.cpp
@@ -42,17 +42,17 @@ GetPrincipalURIFromNode(nsCOMPtr<nsINode
     return;
   }
 
   principalURI->GetSpec(aPrincipalURISpec);
 }
 
 nsresult
 nsDragServiceProxy::InvokeDragSessionImpl(nsIArray* aArrayTransferables,
-                                          nsIScriptableRegion* aRegion,
+                                          const Maybe<CSSIntRegion>& aRegion,
                                           uint32_t aActionType)
 {
   NS_ENSURE_STATE(mSourceDocument->GetDocShell());
   TabChild* child = TabChild::GetFrom(mSourceDocument->GetDocShell());
   NS_ENSURE_STATE(child);
   nsTArray<mozilla::dom::IPCDataTransfer> dataTransfers;
   nsContentUtils::TransferablesToIPCTransferables(aArrayTransferables,
                                                   dataTransfers,
--- a/widget/nsDragServiceProxy.h
+++ b/widget/nsDragServiceProxy.h
@@ -12,15 +12,15 @@ class nsDragServiceProxy : public nsBase
 {
 public:
   nsDragServiceProxy();
 
   NS_INLINE_DECL_REFCOUNTING_INHERITED(nsDragServiceProxy, nsBaseDragService)
 
   // nsBaseDragService
   virtual nsresult InvokeDragSessionImpl(nsIArray* anArrayTransferables,
-                                         nsIScriptableRegion* aRegion,
+                                         const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
                                          uint32_t aActionType) override;
 private:
   virtual ~nsDragServiceProxy();
 };
 
 #endif // NSDRAGSERVICEPROXY_H
--- a/widget/windows/nsDragService.cpp
+++ b/widget/windows/nsDragService.cpp
@@ -63,17 +63,17 @@ nsDragService::nsDragService()
 //-------------------------------------------------------------------------
 nsDragService::~nsDragService()
 {
   NS_IF_RELEASE(mDataObject);
 }
 
 bool
 nsDragService::CreateDragImage(nsINode *aDOMNode,
-                               nsIScriptableRegion *aRegion,
+                               const Maybe<CSSIntRegion>& aRegion,
                                SHDRAGIMAGE *psdi)
 {
   if (!psdi)
     return false;
 
   memset(psdi, 0, sizeof(SHDRAGIMAGE));
   if (!aDOMNode)
     return false;
@@ -160,17 +160,17 @@ nsDragService::CreateDragImage(nsINode *
   dataSurface->Unmap();
 
   return psdi->hbmpDragImage != nullptr;
 }
 
 //-------------------------------------------------------------------------
 nsresult
 nsDragService::InvokeDragSessionImpl(nsIArray* anArrayTransferables,
-                                     nsIScriptableRegion* aRegion,
+                                     const Maybe<CSSIntRegion>& aRegion,
                                      uint32_t aActionType)
 {
   // Try and get source URI of the items that are being dragged
   nsIURI *uri = nullptr;
 
   nsCOMPtr<nsIDocument> doc(do_QueryInterface(mSourceDocument));
   if (doc) {
     uri = doc->GetDocumentURI();
@@ -649,17 +649,17 @@ nsDragService::UpdateDragImage(nsINode* 
 
   nsBaseDragService::UpdateDragImage(aImage, aImageX, aImageY);
 
   IDragSourceHelper *pdsh;
   if (SUCCEEDED(CoCreateInstance(CLSID_DragDropHelper, nullptr,
                                  CLSCTX_INPROC_SERVER,
                                  IID_IDragSourceHelper, (void**)&pdsh))) {
     SHDRAGIMAGE sdi;
-    if (CreateDragImage(mSourceNode, nullptr, &sdi)) {
+    if (CreateDragImage(mSourceNode, Nothing(), &sdi)) {
       nsNativeDragTarget::DragImageChanged();
       if (FAILED(pdsh->InitializeFromBitmap(&sdi, mDataObject)))
         DeleteObject(sdi.hbmpDragImage);
     }
     pdsh->Release();
   }
 
   return NS_OK;
--- a/widget/windows/nsDragService.h
+++ b/widget/windows/nsDragService.h
@@ -20,17 +20,17 @@ class  nsDataObjCollection;
 class nsDragService : public nsBaseDragService
 {
 public:
   nsDragService();
   virtual ~nsDragService();
   
   // nsBaseDragService
   virtual nsresult InvokeDragSessionImpl(nsIArray* anArrayTransferables,
-                                         nsIScriptableRegion* aRegion,
+                                         const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
                                          uint32_t aActionType);
 
   // nsIDragSession
   NS_IMETHOD GetData(nsITransferable * aTransferable, uint32_t anItem) override;
   NS_IMETHOD GetNumDropItems(uint32_t * aNumItems) override;
   NS_IMETHOD IsDataFlavorSupported(const char *aDataFlavor, bool *_retval) override;
   NS_IMETHOD EndDragSession(bool aDoneDrag, uint32_t aKeyModifiers) override;
   NS_IMETHOD UpdateDragImage(nsINode* aImage, int32_t aImageX, int32_t aImageY) override;
@@ -49,16 +49,16 @@ protected:
   nsDataObjCollection* GetDataObjCollection(IDataObject * aDataObj);
 
   // determine if we have a single data object or one of our private
   // collections
   bool IsCollectionObject(IDataObject* inDataObj);
 
   // Create a bitmap for drag operations
   bool CreateDragImage(nsINode *aDOMNode,
-                       nsIScriptableRegion *aRegion,
+                       const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
                        SHDRAGIMAGE *psdi);
 
   IDataObject * mDataObject;
   bool mSentLocalDropEvent;
 };
 
 #endif // nsDragService_h__