Bug 606279, part 4: Only allocate an image large enough to cover the <canvas>. r=joe a=blocking-fennec
authorChris Jones <jones.chris.g@gmail.com>
Tue, 26 Oct 2010 17:20:53 -0500
changeset 56523 ac44827872c935007c46f003d037470f6b0397da
parent 56522 302c05f763445c922e241694329935012d6bc901
child 56524 3a1b694e88243800a729d60e0e96d3b00db66a67
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersjoe, blocking-fennec
bugs606279
milestone2.0b8pre
Bug 606279, part 4: Only allocate an image large enough to cover the <canvas>. r=joe a=blocking-fennec
content/canvas/public/DocumentRendererChild.h
content/canvas/src/DocumentRendererChild.cpp
content/canvas/src/nsCanvasRenderingContext2D.cpp
dom/ipc/PBrowser.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
--- a/content/canvas/public/DocumentRendererChild.h
+++ b/content/canvas/public/DocumentRendererChild.h
@@ -52,17 +52,17 @@ class DocumentRendererChild : public PDo
 public:
     DocumentRendererChild();
     virtual ~DocumentRendererChild();
     
     bool RenderDocument(nsIDOMWindow *window,
                         const nsRect& documentRect, const gfxMatrix& transform,
                         const nsString& bgcolor,
                         PRUint32 renderFlags, PRBool flushLayout, 
-                        nsIntSize* renderedSize, nsCString& data);
+                        const nsIntSize& renderSize, nsCString& data);
 
 private:
 
     DISALLOW_EVIL_CONSTRUCTORS(DocumentRendererChild);
 };
 
 }
 }
--- a/content/canvas/src/DocumentRendererChild.cpp
+++ b/content/canvas/src/DocumentRendererChild.cpp
@@ -100,17 +100,18 @@ FlushLayoutForTree(nsIDOMWindow* aWindow
 
 bool
 DocumentRendererChild::RenderDocument(nsIDOMWindow *window,
                                       const nsRect& documentRect,
                                       const gfxMatrix& transform,
                                       const nsString& bgcolor,
                                       PRUint32 renderFlags,
                                       PRBool flushLayout, 
-                                      nsIntSize* renderedSize, nsCString& data)
+                                      const nsIntSize& renderSize,
+                                      nsCString& data)
 {
     if (flushLayout)
         FlushLayoutForTree(window);
 
     nsCOMPtr<nsPresContext> presContext;
     nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(window);
     if (win) {
         nsIDocShell* docshell = win->GetDocShell();
@@ -125,26 +126,23 @@ DocumentRendererChild::RenderDocument(ns
     nsCSSParser parser;
     nsresult rv = parser.ParseColorString(PromiseFlatString(bgcolor),
                                           nsnull, 0, &bgColor);
     if (NS_FAILED(rv))
         return false;
 
     nsIPresShell* presShell = presContext->PresShell();
 
-    PRInt32 w = nsPresContext::AppUnitsToIntCSSPixels(documentRect.width);
-    PRInt32 h = nsPresContext::AppUnitsToIntCSSPixels(documentRect.height);
+    // Draw directly into the output array.
+    data.SetLength(renderSize.width * renderSize.height * 4);
 
-    // Draw directly into the output array.
-    data.SetLength(w * h * 4);
     nsRefPtr<gfxImageSurface> surf =
         new gfxImageSurface(reinterpret_cast<uint8*>(data.BeginWriting()),
-                            gfxIntSize(w, h),
-                            4 * w,
+                            gfxIntSize(renderSize.width, renderSize.height),
+                            4 * renderSize.width,
                             gfxASurface::ImageFormatARGB32);
     nsRefPtr<gfxContext> ctx = new gfxContext(surf);
     ctx->SetMatrix(transform);
 
     presShell->RenderDocument(documentRect, renderFlags, bgColor, ctx);
-    *renderedSize = nsIntSize(w, h);
 
     return true;
 }
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -3743,17 +3743,18 @@ nsCanvasRenderingContext2D::AsyncDrawXUL
                 nsPresContext::CSSPixelsToAppUnits(aY),
                 nsPresContext::CSSPixelsToAppUnits(aW),
                 nsPresContext::CSSPixelsToAppUnits(aH));
     if (mIPC) {
         PDocumentRendererParent *pdocrender =
             child->SendPDocumentRendererConstructor(rect,
                                                     mThebes->CurrentMatrix(),
                                                     nsString(aBGColor),
-                                                    renderDocFlags, flush);
+                                                    renderDocFlags, flush,
+                                                    nsIntSize(mWidth, mHeight));
         if (!pdocrender)
             return NS_ERROR_FAILURE;
 
         DocumentRendererParent *docrender =
             static_cast<DocumentRendererParent *>(pdocrender);
 
         docrender->SetCanvasContext(this, mThebes);
     }
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -275,21 +275,22 @@ child:
      * request finishes, PDocumentRenderer:__delete__ is sent back to
      * this side to notify completion.
      *
      * |documentRect| is the area of the remote document to draw,
      * transformed by |transform|.  The rendered area will have the
      * default background color |bgcolor|.  |renderFlags| are the
      * nsIPresShell::RenderDocument() flags to use on the remote side,
      * and if true, |flushLayout| will do just that before rendering
-     * the document.
+     * the document.  The rendered image will be of size |renderSize|.
      */
     PDocumentRenderer(nsRect documentRect, gfxMatrix transform,
                       nsString bgcolor,
-                      PRUint32 renderFlags, bool flushLayout);
+                      PRUint32 renderFlags, bool flushLayout,
+                      nsIntSize renderSize);
 
     /**
      * Sent by the chrome process when it no longer wants this remote
      * <browser>.  The child side cleans up in response, then
      * finalizing its death by sending back __delete__() to the
      * parent.
      */
     Destroy();
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -592,17 +592,18 @@ TabChild::DispatchWidgetEvent(nsGUIEvent
   return true;
 }
 
 PDocumentRendererChild*
 TabChild::AllocPDocumentRenderer(const nsRect& documentRect,
                                  const gfxMatrix& transform,
                                  const nsString& bgcolor,
                                  const PRUint32& renderFlags,
-                                 const bool& flushLayout)
+                                 const bool& flushLayout,
+                                 const nsIntSize& renderSize)
 {
     return new DocumentRendererChild();
 }
 
 bool
 TabChild::DeallocPDocumentRenderer(PDocumentRendererChild* actor)
 {
     delete actor;
@@ -610,41 +611,41 @@ TabChild::DeallocPDocumentRenderer(PDocu
 }
 
 bool
 TabChild::RecvPDocumentRendererConstructor(PDocumentRendererChild* actor,
                                            const nsRect& documentRect,
                                            const gfxMatrix& transform,
                                            const nsString& bgcolor,
                                            const PRUint32& renderFlags,
-                                           const bool& flushLayout)
+                                           const bool& flushLayout,
+                                           const nsIntSize& renderSize)
 {
     DocumentRendererChild *render = static_cast<DocumentRendererChild *>(actor);
 
     nsCOMPtr<nsIWebBrowser> browser = do_QueryInterface(mWebNav);
     if (!browser)
         return true; // silently ignore
     nsCOMPtr<nsIDOMWindow> window;
     if (NS_FAILED(browser->GetContentDOMWindow(getter_AddRefs(window))) ||
         !window)
     {
         return true; // silently ignore
     }
 
-    nsIntSize renderedSize;
     nsCString data;
     bool ret = render->RenderDocument(window,
                                       documentRect, transform,
                                       bgcolor,
                                       renderFlags, flushLayout,
-                                      &renderedSize, data);
+                                      renderSize, data);
     if (!ret)
         return true; // silently ignore
 
-    return PDocumentRendererChild::Send__delete__(actor, renderedSize, data);
+    return PDocumentRendererChild::Send__delete__(actor, renderSize, data);
 }
 
 PContentDialogChild*
 TabChild::AllocPContentDialog(const PRUint32&,
                               const nsCString&,
                               const nsCString&,
                               const nsTArray<int>&,
                               const nsTArray<nsString>&)
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -196,24 +196,26 @@ public:
     virtual bool RecvActivateFrameEvent(const nsString& aType, const bool& capture);
     virtual bool RecvLoadRemoteScript(const nsString& aURL);
     virtual bool RecvAsyncMessage(const nsString& aMessage,
                                   const nsString& aJSON);
 
     virtual PDocumentRendererChild*
     AllocPDocumentRenderer(const nsRect& documentRect, const gfxMatrix& transform,
                            const nsString& bgcolor,
-                           const PRUint32& renderFlags, const bool& flushLayout);
+                           const PRUint32& renderFlags, const bool& flushLayout,
+                           const nsIntSize& renderSize);
     virtual bool DeallocPDocumentRenderer(PDocumentRendererChild* actor);
     virtual bool RecvPDocumentRendererConstructor(PDocumentRendererChild* actor,
                                                   const nsRect& documentRect,
                                                   const gfxMatrix& transform,
                                                   const nsString& bgcolor,
                                                   const PRUint32& renderFlags,
-                                                  const bool& flushLayout);
+                                                  const bool& flushLayout,
+                                                  const nsIntSize& renderSize);
 
     virtual PContentDialogChild* AllocPContentDialog(const PRUint32&,
                                                      const nsCString&,
                                                      const nsCString&,
                                                      const nsTArray<int>&,
                                                      const nsTArray<nsString>&);
     virtual bool DeallocPContentDialog(PContentDialogChild* aDialog);
     static void ParamsToArrays(nsIDialogParamBlock* aParams,
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -218,17 +218,18 @@ TabParent::GetSSLStatus(nsISupports ** a
 }
 
 
 PDocumentRendererParent*
 TabParent::AllocPDocumentRenderer(const nsRect& documentRect,
                                   const gfxMatrix& transform,
                                   const nsString& bgcolor,
                                   const PRUint32& renderFlags,
-                                  const bool& flushLayout)
+                                  const bool& flushLayout,
+                                  const nsIntSize& renderSize)
 {
     return new DocumentRendererParent();
 }
 
 bool
 TabParent::DeallocPDocumentRenderer(PDocumentRendererParent* actor)
 {
     delete actor;
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -130,17 +130,18 @@ public:
                         PRInt32 aModifiers, PRBool aIgnoreRootScrollFrame);
     void SendKeyEvent(const nsAString& aType, PRInt32 aKeyCode,
                       PRInt32 aCharCode, PRInt32 aModifiers,
                       PRBool aPreventDefault);
 
     virtual PDocumentRendererParent*
     AllocPDocumentRenderer(const nsRect& documentRect, const gfxMatrix& transform,
                            const nsString& bgcolor,
-                           const PRUint32& renderFlags, const bool& flushLayout);
+                           const PRUint32& renderFlags, const bool& flushLayout,
+                           const nsIntSize& renderSize);
     virtual bool DeallocPDocumentRenderer(PDocumentRendererParent* actor);
 
     virtual PContentPermissionRequestParent* AllocPContentPermissionRequest(const nsCString& aType, const IPC::URI& uri);
     virtual bool DeallocPContentPermissionRequest(PContentPermissionRequestParent* actor);
 
     virtual POfflineCacheUpdateParent* AllocPOfflineCacheUpdate(
             const URI& aManifestURI,
             const URI& aDocumentURI,