Bug 997014 - Part 3: Stop using the external Canvas API in nsBaseDragService. r=roc
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 17 Apr 2014 17:30:45 +1200
changeset 179105 ecb6a42d32ff235ca45d202f99a1211a780fee51
parent 179104 6e72c7a1d9d930fe27ee1c327ef2cf46be6a2f79
child 179106 2d7b34276247f26a53faca28dada0543900e7a04
push id26607
push userryanvm@gmail.com
push dateFri, 18 Apr 2014 02:31:26 +0000
treeherdermozilla-central@7fe3ee0cf8be [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs997014
milestone31.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 997014 - Part 3: Stop using the external Canvas API in nsBaseDragService. r=roc
widget/xpwidgets/nsBaseDragService.cpp
widget/xpwidgets/nsBaseDragService.h
--- a/widget/xpwidgets/nsBaseDragService.cpp
+++ b/widget/xpwidgets/nsBaseDragService.cpp
@@ -20,33 +20,33 @@
 #include "nsIPresShell.h"
 #include "nsViewManager.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMDragEvent.h"
 #include "nsISelection.h"
 #include "nsISelectionPrivate.h"
 #include "nsPresContext.h"
 #include "nsIDOMDataTransfer.h"
-#include "nsICanvasElementExternal.h"
 #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;
+using namespace mozilla::dom;
 
 #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),
@@ -502,17 +502,18 @@ nsBaseDragService::DrawDrag(nsIDOMNode* 
     *aSurface = presShell->RenderSelection(mSelection, pnt, aScreenDragRect);
     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);
+    nsCOMPtr<nsIContent> content = do_QueryInterface(dragNode);
+    HTMLCanvasElement *canvas = HTMLCanvasElement::FromContentOrNull(content);
     if (canvas) {
       return DrawDragForImage(*aPresContext, nullptr, canvas, sx, sy,
                               aScreenDragRect, aSurface);
     }
 
     nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(dragNode);
     // for image nodes, create the drag image from the actual image data
     if (imageLoader) {
@@ -520,17 +521,16 @@ nsBaseDragService::DrawDrag(nsIDOMNode* 
                               aScreenDragRect, aSurface);
     }
 
     // If the image is a popup, use that as the image. This allows custom drag
     // images that can change during the drag, but means that any platform
     // default image handling won't occur.
     // XXXndeakin this should be chrome-only
 
-    nsCOMPtr<nsIContent> content = do_QueryInterface(dragNode);
     nsIFrame* frame = content->GetPrimaryFrame();
     if (frame && frame->GetType() == nsGkAtoms::menuPopupFrame) {
       mDragPopup = content;
     }
   }
 
   if (!mDragPopup) {
     // otherwise, just draw the node
@@ -552,17 +552,17 @@ nsBaseDragService::DrawDrag(nsIDOMNode* 
   }
 
   return NS_OK;
 }
 
 nsresult
 nsBaseDragService::DrawDragForImage(nsPresContext* aPresContext,
                                     nsIImageLoadingContent* aImageLoader,
-                                    nsICanvasElementExternal* aCanvas,
+                                    HTMLCanvasElement* aCanvas,
                                     int32_t aScreenX, int32_t aScreenY,
                                     nsIntRect* aScreenDragRect,
                                     RefPtr<SourceSurface>* aSurface)
 {
   nsCOMPtr<imgIContainer> imgContainer;
   if (aImageLoader) {
     nsCOMPtr<imgIRequest> imgRequest;
     nsresult rv = aImageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
@@ -577,17 +577,17 @@ nsBaseDragService::DrawDragForImage(nsPr
       return NS_ERROR_NOT_AVAILABLE;
 
     // use the size of the image as the size of the drag image
     imgContainer->GetWidth(&aScreenDragRect->width);
     imgContainer->GetHeight(&aScreenDragRect->height);
   }
   else {
     NS_ASSERTION(aCanvas, "both image and canvas are null");
-    nsIntSize sz = aCanvas->GetSizeExternal();
+    nsIntSize sz = aCanvas->GetSize();
     aScreenDragRect->width = sz.width;
     aScreenDragRect->height = sz.height;
   }
 
   nsIntSize srcSize = aScreenDragRect->Size();
   nsIntSize destSize = srcSize;
 
   if (destSize.width == 0 || destSize.height == 0)
@@ -611,41 +611,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(destSize.ToIntSize(),
-                                       SurfaceFormat::B8G8R8A8);
-  if (!dt)
-    return NS_ERROR_FAILURE;
-
-  nsRefPtr<gfxContext> ctx = new gfxContext(dt);
-  if (!ctx)
-    return NS_ERROR_FAILURE;
-
   nsresult result = NS_OK;
   if (aImageLoader) {
+    RefPtr<DrawTarget> dt =
+      gfxPlatform::GetPlatform()->
+        CreateOffscreenContentDrawTarget(destSize.ToIntSize(),
+                                         SurfaceFormat::B8G8R8A8);
+    if (!dt)
+      return NS_ERROR_FAILURE;
+
+    nsRefPtr<gfxContext> ctx = new gfxContext(dt);
+    if (!ctx)
+      return NS_ERROR_FAILURE;
+
     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);
+    *aSurface = dt->Snapshot();
   } else {
-    result = aCanvas->RenderContextsExternal(ctx, GraphicsFilter::FILTER_GOOD);
+    *aSurface = aCanvas->GetSurfaceSnapshot();
   }
 
-  *aSurface = dt->Snapshot();
   return result;
 }
 
 void
 nsBaseDragService::ConvertToUnscaledDevPixels(nsPresContext* aPresContext,
                                               int32_t* aScreenX, int32_t* aScreenY)
 {
   int32_t adj = aPresContext->DeviceContext()->UnscaledAppUnitsPerDevPixel();
--- a/widget/xpwidgets/nsBaseDragService.h
+++ b/widget/xpwidgets/nsBaseDragService.h
@@ -10,16 +10,17 @@
 #include "nsIDragSession.h"
 #include "nsITransferable.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMDataTransfer.h"
 #include "nsCOMPtr.h"
 #include "nsRect.h"
 #include "nsPoint.h"
 #include "mozilla/RefPtr.h"
+#include "mozilla/dom/HTMLCanvasElement.h"
 
 // translucency level for drag images
 #define DRAG_TRANSLUCENCY 0.65
 
 class nsIContent;
 class nsIDOMNode;
 class nsIFrame;
 class nsPresContext;
@@ -89,17 +90,17 @@ protected:
                     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,
+                            mozilla::dom::HTMLCanvasElement* aCanvas,
                             int32_t aScreenX, int32_t aScreenY,
                             nsIntRect* aScreenDragRect,
                             mozilla::RefPtr<SourceSurface>* aSurface);
 
   /**
    * Convert aScreenX and aScreenY from CSS pixels into unscaled device pixels.
    */
   void