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 179375 ecb6a42d32ff235ca45d202f99a1211a780fee51
parent 179374 6e72c7a1d9d930fe27ee1c327ef2cf46be6a2f79
child 179376 2d7b34276247f26a53faca28dada0543900e7a04
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersroc
bugs997014
milestone31.0a1
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