From 00437f12589251bd04c3fa1d60a00abeabbfbc62 Mon Sep 17 00:00:00 2001 From: Joe Drew Date: Wed, 28 Oct 2009 16:55:49 -0400 Subject: [PATCH] Bug 505847 - Implement asyncDrawXULElement in 2D canvas. r=bz,bsmedberg --- content/base/src/nsFrameLoader.cpp | 11 ++ content/base/src/nsFrameLoader.h | 6 + content/canvas/public/DocumentRendererChild.h | 68 +++++++++ .../canvas/public/DocumentRendererParent.h | 70 +++++++++ content/canvas/public/Makefile.in | 7 + .../nsICanvasRenderingContextInternal.h | 3 + content/canvas/src/DocumentRendererChild.cpp | 144 ++++++++++++++++++ content/canvas/src/DocumentRendererParent.cpp | 77 ++++++++++ content/canvas/src/Makefile.in | 8 + content/canvas/src/WebGLContext.h | 1 + .../canvas/src/nsCanvasRenderingContext2D.cpp | 77 +++++++++- .../canvas/nsIDOMCanvasRenderingContext2D.idl | 6 +- dom/ipc/PDocumentRenderer.ipdl | 49 ++++++ dom/ipc/PIFrameEmbedding.ipdl | 9 ++ dom/ipc/TabChild.cpp | 61 ++++++++ dom/ipc/TabChild.h | 22 +++ dom/ipc/TabParent.cpp | 30 ++++ dom/ipc/TabParent.h | 19 +++ dom/ipc/ipdl.mk | 1 + .../tests/fennec-tile-testapp/application.ini | 2 +- .../chrome/content/BrowserView.js | 10 +- .../chrome/content/TileManager.js | 5 +- .../chrome/content/foo.xul | 2 +- .../defaults/preferences/prefs.js | 1 + 24 files changed, 672 insertions(+), 17 deletions(-) create mode 100644 content/canvas/public/DocumentRendererChild.h create mode 100644 content/canvas/public/DocumentRendererParent.h create mode 100644 content/canvas/src/DocumentRendererChild.cpp create mode 100644 content/canvas/src/DocumentRendererParent.cpp create mode 100644 dom/ipc/PDocumentRenderer.ipdl diff --git a/content/base/src/nsFrameLoader.cpp b/content/base/src/nsFrameLoader.cpp index df8739987e0..f10527b3005 100644 --- a/content/base/src/nsFrameLoader.cpp +++ b/content/base/src/nsFrameLoader.cpp @@ -1436,3 +1436,14 @@ nsFrameLoader::TryNewProcess() return PR_TRUE; } #endif + +mozilla::dom::PIFrameEmbeddingParent* +nsFrameLoader::GetChildProcess() +{ +#ifdef MOZ_IPC + return mChildProcess; +#else + return nsnull; +#endif +} + diff --git a/content/base/src/nsFrameLoader.h b/content/base/src/nsFrameLoader.h index 8f048d1b551..3f572790ecd 100644 --- a/content/base/src/nsFrameLoader.h +++ b/content/base/src/nsFrameLoader.h @@ -59,6 +59,7 @@ class nsIFrameFrame; namespace mozilla { namespace dom { class TabParent; + class PIFrameEmbeddingParent; } } #endif @@ -116,6 +117,11 @@ public: nsresult SwapWithOtherLoader(nsFrameLoader* aOther, nsRefPtr& aFirstToSwap, nsRefPtr& aSecondToSwap); + +#ifdef MOZ_IPC + mozilla::dom::PIFrameEmbeddingParent* GetChildProcess(); +#endif + private: #ifdef MOZ_IPC diff --git a/content/canvas/public/DocumentRendererChild.h b/content/canvas/public/DocumentRendererChild.h new file mode 100644 index 00000000000..f793eb66fc7 --- /dev/null +++ b/content/canvas/public/DocumentRendererChild.h @@ -0,0 +1,68 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Fennec Electrolysis. + * + * The Initial Developer of the Original Code is + * The Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef mozilla_dom_DocumentRendererChild +#define mozilla_dom_DocumentRendererChild + +#include "mozilla/ipc/PDocumentRendererChild.h" +#include "nsICanvasRenderingContextInternal.h" +#include "nsString.h" +#include "gfxContext.h" + +class nsIDOMWindow; + +namespace mozilla { +namespace ipc { + +class DocumentRendererChild : public PDocumentRendererChild +{ +public: + DocumentRendererChild(); + virtual ~DocumentRendererChild(); + + bool RenderDocument(nsIDOMWindow *window, const PRInt32& x, const PRInt32& y, const PRInt32& w, const PRInt32& h, + const nsString& bgcolor, const PRUint32& flags, const PRBool& flush, + PRUint32& _width, PRUint32& _height, nsCString& data); + +private: + + DISALLOW_EVIL_CONSTRUCTORS(DocumentRendererChild); +}; + +} +} + +#endif diff --git a/content/canvas/public/DocumentRendererParent.h b/content/canvas/public/DocumentRendererParent.h new file mode 100644 index 00000000000..e2ff79aa593 --- /dev/null +++ b/content/canvas/public/DocumentRendererParent.h @@ -0,0 +1,70 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Fennec Electrolysis. + * + * The Initial Developer of the Original Code is + * The Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef mozilla_dom_DocumentRendererParent +#define mozilla_dom_DocumentRendererParent + +#include "mozilla/ipc/PDocumentRendererParent.h" +#include "nsICanvasRenderingContextInternal.h" +#include "nsCOMPtr.h" +#include "nsString.h" +#include "gfxContext.h" + +namespace mozilla { +namespace ipc { + +class DocumentRendererParent : public PDocumentRendererParent +{ +public: + DocumentRendererParent(); + virtual ~DocumentRendererParent(); + + void SetCanvasContext(nsICanvasRenderingContextInternal* aCanvas, + gfxContext* ctx); + void DrawToCanvas(PRUint32 aWidth, PRUint32 aHeight, + const nsCString& aData); + +private: + nsCOMPtr mCanvas; + nsRefPtr mCanvasContext; + + DISALLOW_EVIL_CONSTRUCTORS(DocumentRendererParent); +}; + +} +} + +#endif diff --git a/content/canvas/public/Makefile.in b/content/canvas/public/Makefile.in index cc4b2fa1612..93fa8c81474 100644 --- a/content/canvas/public/Makefile.in +++ b/content/canvas/public/Makefile.in @@ -45,12 +45,19 @@ include $(DEPTH)/config/autoconf.mk MODULE = content XPIDL_MODULE = content_canvas +EXPORTS_NAMESPACES = mozilla/ipc + EXPORTS = \ nsICanvasRenderingContextInternal.h \ nsICanvasElement.h \ WebGLArray.h \ $(NULL) +EXPORTS_mozilla/ipc = \ + DocumentRendererChild.h \ + DocumentRendererParent.h \ + $(NULL) + XPIDLSRCS = \ nsICanvasGLPrivate.idl \ $(NULL) diff --git a/content/canvas/public/nsICanvasRenderingContextInternal.h b/content/canvas/public/nsICanvasRenderingContextInternal.h index fe8120e9091..d8f09084dc0 100644 --- a/content/canvas/public/nsICanvasRenderingContextInternal.h +++ b/content/canvas/public/nsICanvasRenderingContextInternal.h @@ -87,6 +87,9 @@ public: // dst alpha is always 1.0. If this is never called, the context // defaults to false (not opaque). NS_IMETHOD SetIsOpaque(PRBool isOpaque) = 0; + + // Redraw the dirty rectangle of this canvas. + NS_IMETHOD Redraw(const gfxRect &dirty) = 0; }; NS_DEFINE_STATIC_IID_ACCESSOR(nsICanvasRenderingContextInternal, diff --git a/content/canvas/src/DocumentRendererChild.cpp b/content/canvas/src/DocumentRendererChild.cpp new file mode 100644 index 00000000000..c320fa96ea6 --- /dev/null +++ b/content/canvas/src/DocumentRendererChild.cpp @@ -0,0 +1,144 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Fennec Electrolysis. + * + * The Initial Developer of the Original Code is + * The Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "mozilla/ipc/DocumentRendererChild.h" +#include "gfxImageSurface.h" +#include "gfxPattern.h" +#include "nsPIDOMWindow.h" +#include "nsIDOMWindow.h" +#include "nsIDOMDocument.h" +#include "nsIDocShellTreeNode.h" +#include "nsIDocShellTreeItem.h" +#include "nsIDocument.h" +#include "nsIInterfaceRequestorUtils.h" +#include "nsComponentManagerUtils.h" +#include "nsICSSParser.h" +#include "nsPresContext.h" +#include "nsCOMPtr.h" +#include "nsColor.h" +#include "gfxContext.h" +#include "gfxImageSurface.h" +#include "nsLayoutUtils.h" + +using namespace mozilla::ipc; + +DocumentRendererChild::DocumentRendererChild() +{} + +DocumentRendererChild::~DocumentRendererChild() +{} + +static void +FlushLayoutForTree(nsIDOMWindow* aWindow) +{ + nsCOMPtr piWin = do_QueryInterface(aWindow); + if (!piWin) + return; + + // Note that because FlushPendingNotifications flushes parents, this + // is O(N^2) in docshell tree depth. However, the docshell tree is + // usually pretty shallow. + + nsCOMPtr domDoc; + aWindow->GetDocument(getter_AddRefs(domDoc)); + nsCOMPtr doc = do_QueryInterface(domDoc); + if (doc) { + doc->FlushPendingNotifications(Flush_Layout); + } + + nsCOMPtr node = + do_QueryInterface(piWin->GetDocShell()); + if (node) { + PRInt32 i = 0, i_end; + node->GetChildCount(&i_end); + for (; i < i_end; ++i) { + nsCOMPtr item; + node->GetChildAt(i, getter_AddRefs(item)); + nsCOMPtr win = do_GetInterface(item); + if (win) { + FlushLayoutForTree(win); + } + } + } +} + +bool +DocumentRendererChild::RenderDocument(nsIDOMWindow *window, const PRInt32& x, const PRInt32& y, const PRInt32& w, const PRInt32& h, + const nsString& aBGColor, const PRUint32& flags, const PRBool& flush, + PRUint32& _width, PRUint32& _height, nsCString& data) +{ + if (flush) + FlushLayoutForTree(window); + + nsCOMPtr presContext; + nsCOMPtr win = do_QueryInterface(window); + if (win) { + nsIDocShell* docshell = win->GetDocShell(); + if (docshell) { + docshell->GetPresContext(getter_AddRefs(presContext)); + } + } + if (!presContext) + return NS_ERROR_FAILURE; + + nscolor bgColor; + nsCOMPtr parser = do_CreateInstance("@mozilla.org/content/css-parser;1"); + nsresult rv = parser->ParseColorString(PromiseFlatString(aBGColor), + nsnull, 0, &bgColor); + if (NS_FAILED(rv)) + return false; + + nsIPresShell* presShell = presContext->PresShell(); + + nsRect r(x, y, w, h); + + _width = nsPresContext::AppUnitsToIntCSSPixels(w); + _height = nsPresContext::AppUnitsToIntCSSPixels(h); + + // Draw directly into the output array. + data.SetLength(_width * _height * 4); + nsRefPtr surf = new gfxImageSurface(reinterpret_cast(const_cast(data.get())), + gfxIntSize(_width, _height), + 4 * _width, gfxASurface::ImageFormatARGB32); + nsRefPtr ctx = new gfxContext(surf); + + PRBool oldDisableValue = nsLayoutUtils::sDisableGetUsedXAssertions; + nsLayoutUtils::sDisableGetUsedXAssertions = oldDisableValue || !flush; + presShell->RenderDocument(r, flags, bgColor, ctx); + nsLayoutUtils::sDisableGetUsedXAssertions = oldDisableValue; + + return true; +} diff --git a/content/canvas/src/DocumentRendererParent.cpp b/content/canvas/src/DocumentRendererParent.cpp new file mode 100644 index 00000000000..a4c7e91bf55 --- /dev/null +++ b/content/canvas/src/DocumentRendererParent.cpp @@ -0,0 +1,77 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Fennec Electrolysis. + * + * The Initial Developer of the Original Code is + * The Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "mozilla/ipc/DocumentRendererParent.h" +#include "gfxImageSurface.h" +#include "gfxPattern.h" + +using namespace mozilla::ipc; + +DocumentRendererParent::DocumentRendererParent() +{} + +DocumentRendererParent::~DocumentRendererParent() +{} + +void DocumentRendererParent::SetCanvasContext(nsICanvasRenderingContextInternal* aCanvas, + gfxContext* ctx) +{ + mCanvas = aCanvas; + mCanvasContext = ctx; +} + +void DocumentRendererParent::DrawToCanvas(PRUint32 aWidth, PRUint32 aHeight, + const nsCString& aData) +{ + if (!mCanvas || !mCanvasContext) + return; + + nsRefPtr surf = new gfxImageSurface(reinterpret_cast(const_cast(aData.Data())), + gfxIntSize(aWidth, aHeight), + aWidth * 4, + gfxASurface::ImageFormatARGB32); + nsRefPtr pat = new gfxPattern(surf); + + mCanvasContext->NewPath(); + mCanvasContext->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, aWidth, aHeight), pat); + mCanvasContext->Fill(); + + // get rid of the pattern surface ref, because aData is very likely to go away shortly + mCanvasContext->SetColor(gfxRGBA(1,1,1,1)); + + gfxRect damageRect = mCanvasContext->UserToDevice(gfxRect(0, 0, aWidth, aHeight)); + mCanvas->Redraw(damageRect); +} diff --git a/content/canvas/src/Makefile.in b/content/canvas/src/Makefile.in index 0512de3c72c..8d0bd976bfe 100644 --- a/content/canvas/src/Makefile.in +++ b/content/canvas/src/Makefile.in @@ -53,6 +53,13 @@ CPPSRCS = \ nsCanvasRenderingContext2D.cpp \ $(NULL) +ifdef MOZ_IPC +CPPSRCS += \ + DocumentRendererParent.cpp \ + DocumentRendererChild.cpp \ + $(NULL) +endif + # Canvas 3D Pieces ifdef MOZ_WEBGL @@ -100,6 +107,7 @@ endif FORCE_STATIC_LIB = 1 include $(topsrcdir)/config/rules.mk +include $(topsrcdir)/ipc/chromium/chromium-config.mk CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(TK_CFLAGS) diff --git a/content/canvas/src/WebGLContext.h b/content/canvas/src/WebGLContext.h index b9cab76e98a..956d6732e8f 100644 --- a/content/canvas/src/WebGLContext.h +++ b/content/canvas/src/WebGLContext.h @@ -243,6 +243,7 @@ public: nsIInputStream **aStream); NS_IMETHOD GetThebesSurface(gfxASurface **surface); NS_IMETHOD SetIsOpaque(PRBool b) { return NS_OK; }; + NS_IMETHOD Redraw(const gfxRect&) { return NS_ERROR_NOT_IMPLEMENTED; } protected: GLES20Wrap *gl; diff --git a/content/canvas/src/nsCanvasRenderingContext2D.cpp b/content/canvas/src/nsCanvasRenderingContext2D.cpp index 91bbf25a9f0..e6ff6f71663 100644 --- a/content/canvas/src/nsCanvasRenderingContext2D.cpp +++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp @@ -37,6 +37,13 @@ * * ***** END LICENSE BLOCK ***** */ +#ifdef MOZ_IPC +#include "mozilla/ipc/PDocumentRendererParent.h" +#include "mozilla/dom/PIFrameEmbeddingParent.h" +#include "mozilla/ipc/DocumentRendererParent.h" +#endif +#include "nsIDOMXULElement.h" + #ifdef _MSC_VER #define _USE_MATH_DEFINES #endif @@ -103,6 +110,8 @@ #include "nsFrameManager.h" +#include "nsFrameLoader.h" + #include "nsBidiPresUtils.h" #include "CanvasUtils.h" @@ -311,8 +320,6 @@ public: virtual ~nsCanvasRenderingContext2D(); nsresult Redraw(); - // this rect is in CSS pixels - nsresult Redraw(const gfxRect& r); // nsICanvasRenderingContextInternal NS_IMETHOD SetCanvasElement(nsICanvasElement* aParentCanvas); @@ -324,6 +331,8 @@ public: nsIInputStream **aStream); NS_IMETHOD GetThebesSurface(gfxASurface **surface); NS_IMETHOD SetIsOpaque(PRBool isOpaque); + // this rect is in CSS pixels + NS_IMETHOD Redraw(const gfxRect &r); // nsISupports interface NS_DECL_ISUPPORTS @@ -848,7 +857,7 @@ nsCanvasRenderingContext2D::Redraw() return mCanvasElement->InvalidateFrame(); } -nsresult +NS_IMETHODIMP nsCanvasRenderingContext2D::Redraw(const gfxRect& r) { if (!mCanvasElement) @@ -3305,6 +3314,68 @@ nsCanvasRenderingContext2D::DrawWindow(nsIDOMWindow* aWindow, float aX, float aY return rv; } +NS_IMETHODIMP +nsCanvasRenderingContext2D::AsyncDrawXULElement(nsIDOMXULElement* aElem, float aX, float aY, + float aW, float aH, + const nsAString& aBGColor, + PRUint32 flags) +{ + NS_ENSURE_ARG(aElem != nsnull); + + // We can't allow web apps to call this until we fix at least the + // following potential security issues: + // -- rendering cross-domain IFRAMEs and then extracting the results + // -- rendering the user's theme and then extracting the results + // -- rendering native anonymous content (e.g., file input paths; + // scrollbars should be allowed) + if (!nsContentUtils::IsCallerTrustedForRead()) { + // not permitted to use DrawWindow + // XXX ERRMSG we need to report an error to developers here! (bug 329026) + return NS_ERROR_DOM_SECURITY_ERR; + } + + nsCOMPtr loaderOwner = do_QueryInterface(aElem); + if (!loaderOwner) + return NS_ERROR_FAILURE; + + nsCOMPtr frameloader = loaderOwner->GetFrameLoader(); + if (!frameloader) + return NS_ERROR_FAILURE; + + mozilla::dom::PIFrameEmbeddingParent *child = frameloader->GetChildProcess(); + if (!child) + return NS_ERROR_FAILURE; + + // protect against too-large surfaces that will cause allocation + // or overflow issues + if (!gfxASurface::CheckSurfaceSize(gfxIntSize(aW, aH), 0xffff)) + return NS_ERROR_FAILURE; + + PRBool flush = + (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DO_NOT_FLUSH) == 0; + + PRUint32 renderDocFlags = nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING; + if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_CARET) { + renderDocFlags |= nsIPresShell::RENDER_CARET; + } + if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_VIEW) { + renderDocFlags &= ~nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING; + } + + PRInt32 x = nsPresContext::CSSPixelsToAppUnits(aX), + y = nsPresContext::CSSPixelsToAppUnits(aY), + w = nsPresContext::CSSPixelsToAppUnits(aW), + h = nsPresContext::CSSPixelsToAppUnits(aH); + + mozilla::ipc::PDocumentRendererParent *pdocrender = + child->SendPDocumentRendererConstructor(x, y, w, h, nsString(aBGColor), renderDocFlags, flush); + mozilla::ipc::DocumentRendererParent *docrender = static_cast(pdocrender); + + docrender->SetCanvasContext(this, mThebes); + + return NS_OK; +} + // // device pixel getting/setting // diff --git a/dom/interfaces/canvas/nsIDOMCanvasRenderingContext2D.idl b/dom/interfaces/canvas/nsIDOMCanvasRenderingContext2D.idl index 29c58d7937d..3167c4cde61 100644 --- a/dom/interfaces/canvas/nsIDOMCanvasRenderingContext2D.idl +++ b/dom/interfaces/canvas/nsIDOMCanvasRenderingContext2D.idl @@ -43,6 +43,7 @@ interface nsIDOMElement; interface nsIDOMHTMLElement; interface nsIDOMHTMLImageElement; interface nsIDOMHTMLCanvasElement; +interface nsIDOMXULElement; [scriptable, uuid(bbb20a59-524e-4662-981e-5e142814b20c)] interface nsIDOMCanvasGradient : nsISupports @@ -61,7 +62,7 @@ interface nsIDOMTextMetrics : nsISupports readonly attribute float width; }; -[scriptable, uuid(72635fb6-0c1c-47d7-bf69-49388d5980fc)] +[scriptable, uuid(408be1b9-4d75-4873-b50b-9b651626e41d)] interface nsIDOMCanvasRenderingContext2D : nsISupports { // back-reference to the canvas element for which @@ -222,4 +223,7 @@ interface nsIDOMCanvasRenderingContext2D : nsISupports void drawWindow(in nsIDOMWindow window, in float x, in float y, in float w, in float h, in DOMString bgColor, [optional] in unsigned long flags); + void asyncDrawXULElement(in nsIDOMXULElement elem, in float x, in float y, + in float w, in float h, in DOMString bgColor, + [optional] in unsigned long flags); }; diff --git a/dom/ipc/PDocumentRenderer.ipdl b/dom/ipc/PDocumentRenderer.ipdl new file mode 100644 index 00000000000..cdb52433513 --- /dev/null +++ b/dom/ipc/PDocumentRenderer.ipdl @@ -0,0 +1,49 @@ +/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Fenntrolysis. + * + * The Initial Developer of the Original Code is + * The Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +include protocol "PIFrameEmbedding.ipdl"; + +namespace mozilla { +namespace ipc { + +protocol PDocumentRenderer +{ + manager PIFrameEmbedding; +}; + +} // namespace ipc +} // namespace mozilla diff --git a/dom/ipc/PIFrameEmbedding.ipdl b/dom/ipc/PIFrameEmbedding.ipdl index 31dbf72bf91..6966f41cf05 100644 --- a/dom/ipc/PIFrameEmbedding.ipdl +++ b/dom/ipc/PIFrameEmbedding.ipdl @@ -38,8 +38,10 @@ * ***** END LICENSE BLOCK ***** */ include protocol "PContentProcess.ipdl"; +include protocol "PDocumentRenderer.ipdl"; using PRUint32; +using PRInt32; namespace mozilla { namespace dom { @@ -47,6 +49,7 @@ namespace dom { async protocol PIFrameEmbedding { manager PContentProcess; + manages PDocumentRenderer; child: loadURL(nsCString uri); @@ -55,6 +58,12 @@ child: PRUint32 y, PRUint32 width, PRUint32 height); + + PDocumentRenderer(PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h, nsString bgcolor, PRUint32 flags, bool flush); + +parent: + + ~PDocumentRenderer(PRUint32 w, PRUint32 h, nsCString data); }; } diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 1ed7a34fc18..56b60aea6bc 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -42,8 +42,11 @@ #include "nsEmbedCID.h" #include "nsComponentManagerUtils.h" #include "nsIBaseWindow.h" +#include "nsIDOMWindow.h" #include "nsIDocShellTreeItem.h" #include "nsThreadUtils.h" +#include "nsIInterfaceRequestorUtils.h" +#include "mozilla/ipc/DocumentRendererChild.h" #ifdef MOZ_WIDGET_GTK2 #include @@ -115,3 +118,61 @@ TabChild::Recvmove(const PRUint32& x, baseWin->SetPositionAndSize(x, y, width, height, PR_TRUE); return true; } + +mozilla::ipc::PDocumentRendererChild* +TabChild::AllocPDocumentRenderer( + const PRInt32& x, + const PRInt32& y, + const PRInt32& w, + const PRInt32& h, + const nsString& bgcolor, + const PRUint32& flags, + const bool& flush) +{ + return new mozilla::ipc::DocumentRendererChild(); +} + +bool +TabChild::DeallocPDocumentRenderer( + mozilla::ipc::PDocumentRendererChild* __a, + const PRUint32& w, + const PRUint32& h, + const nsCString& data) +{ + delete __a; + return true; +} + +bool +TabChild::RecvPDocumentRendererConstructor( + mozilla::ipc::PDocumentRendererChild *__a, + const PRInt32& aX, + const PRInt32& aY, + const PRInt32& aW, + const PRInt32& aH, + const nsString& bgcolor, + const PRUint32& flags, + const bool& flush) +{ + mozilla::ipc::DocumentRendererChild *render = + static_cast(__a); + + nsCOMPtr browser = do_QueryInterface(mWebNav); + if (!browser) + return true; // silently ignore + nsCOMPtr window; + if (NS_FAILED(browser->GetContentDOMWindow(getter_AddRefs(window))) || + !window) + { + return true; // silently ignore + } + + PRUint32 width, height; + nsCString data; + nsresult rv = render->RenderDocument(window, aX, aY, aW, aH, bgcolor, flags, flush, + width, height, data); + if (NS_FAILED(rv)) + return true; // silently ignore + + return SendPDocumentRendererDestructor(__a, width, height, data); +} diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index 6333f10475c..a3614a78cc8 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -57,6 +57,28 @@ public: const PRUint32& y, const PRUint32& width, const PRUint32& height); + virtual mozilla::ipc::PDocumentRendererChild* AllocPDocumentRenderer( + const PRInt32& x, + const PRInt32& y, + const PRInt32& w, + const PRInt32& h, + const nsString& bgcolor, + const PRUint32& flags, + const bool& flush); + virtual bool DeallocPDocumentRenderer( + mozilla::ipc::PDocumentRendererChild* __a, + const PRUint32& w, + const PRUint32& h, + const nsCString& data); + virtual bool RecvPDocumentRendererConstructor( + mozilla::ipc::PDocumentRendererChild *__a, + const PRInt32& x, + const PRInt32& y, + const PRInt32& w, + const PRInt32& h, + const nsString& bgcolor, + const PRUint32& flags, + const bool& flush); private: nsCOMPtr mWebNav; diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 9f5eafac985..5882297bf79 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -39,10 +39,12 @@ #include "TabParent.h" #include "mozilla/ipc/GeckoThread.h" +#include "mozilla/ipc/DocumentRendererParent.h" #include "nsIURI.h" using mozilla::ipc::BrowserProcessSubThread; +using mozilla::ipc::DocumentRendererParent; namespace mozilla { namespace dom { @@ -70,5 +72,33 @@ TabParent::Move(PRUint32 x, PRUint32 y, PRUint32 width, PRUint32 height) Sendmove(x, y, width, height); } +mozilla::ipc::PDocumentRendererParent* +TabParent::AllocPDocumentRenderer(const PRInt32& x, + const PRInt32& y, const PRInt32& w, const PRInt32& h, const nsString& bgcolor, + const PRUint32& flags, const bool& flush) +{ + return new DocumentRendererParent(); +} + +bool +TabParent::DeallocPDocumentRenderer(mozilla::ipc::PDocumentRendererParent* __a, + const PRUint32& w, const PRUint32& h, const nsCString& data) +{ + NS_ENSURE_ARG_POINTER(__a); + delete __a; + return true; +} + +bool +TabParent::RecvPDocumentRendererDestructor(PDocumentRendererParent* __a, + const PRUint32& w, const PRUint32& h, const nsCString& data) +{ + NS_ENSURE_ARG_POINTER(__a); + DocumentRendererParent *renderer = static_cast(__a); + renderer->DrawToCanvas(w, h, data); + + return true; +} + } // namespace tabs } // namespace mozilla diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 36a0030bd6b..eb541f1c3b6 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -56,6 +56,25 @@ public: void LoadURL(nsIURI* aURI); void Move(PRUint32 x, PRUint32 y, PRUint32 width, PRUint32 height); + + virtual mozilla::ipc::PDocumentRendererParent* AllocPDocumentRenderer( + const PRInt32& x, + const PRInt32& y, + const PRInt32& w, + const PRInt32& h, + const nsString& bgcolor, + const PRUint32& flags, + const bool& flush); + virtual bool DeallocPDocumentRenderer( + mozilla::ipc::PDocumentRendererParent* __a, + const PRUint32& w, + const PRUint32& h, + const nsCString& data); + virtual bool RecvPDocumentRendererDestructor( + mozilla::ipc::PDocumentRendererParent* __a, + const PRUint32& w, + const PRUint32& h, + const nsCString& data); }; } // namespace dom diff --git a/dom/ipc/ipdl.mk b/dom/ipc/ipdl.mk index 7201feeb588..e833901fe0f 100644 --- a/dom/ipc/ipdl.mk +++ b/dom/ipc/ipdl.mk @@ -37,4 +37,5 @@ IPDLSRCS = \ PContentProcess.ipdl \ PIFrameEmbedding.ipdl \ + PDocumentRenderer.ipdl \ $(NULL) diff --git a/toolkit/content/tests/fennec-tile-testapp/application.ini b/toolkit/content/tests/fennec-tile-testapp/application.ini index 6da1d196fba..510d481809a 100644 --- a/toolkit/content/tests/fennec-tile-testapp/application.ini +++ b/toolkit/content/tests/fennec-tile-testapp/application.ini @@ -8,4 +8,4 @@ ID=xulapp@starkravingfinkle.org [Gecko] MinVersion=1.8 -MaxVersion=1.9.2.* +MaxVersion=2.0 diff --git a/toolkit/content/tests/fennec-tile-testapp/chrome/content/BrowserView.js b/toolkit/content/tests/fennec-tile-testapp/chrome/content/BrowserView.js index 96902846122..3fd6ef6d8d5 100644 --- a/toolkit/content/tests/fennec-tile-testapp/chrome/content/BrowserView.js +++ b/toolkit/content/tests/fennec-tile-testapp/chrome/content/BrowserView.js @@ -184,15 +184,7 @@ function() { } function getBrowserDimensions(browser) { - let cdoc = browser.contentDocument; - - // These might not exist yet depending on page load state - let body = cdoc.body || {}; - let html = cdoc.documentElement || {}; - let w = Math.max(body.scrollWidth || 0, html.scrollWidth); - let h = Math.max(body.scrollHeight || 0, html.scrollHeight); - - return [w, h]; + return [browser.scrollWidth, browser.scrollHeight]; } function getContentScrollValues(browser) { diff --git a/toolkit/content/tests/fennec-tile-testapp/chrome/content/TileManager.js b/toolkit/content/tests/fennec-tile-testapp/chrome/content/TileManager.js index b6b169123b1..c7f79830146 100644 --- a/toolkit/content/tests/fennec-tile-testapp/chrome/content/TileManager.js +++ b/toolkit/content/tests/fennec-tile-testapp/chrome/content/TileManager.js @@ -854,7 +854,8 @@ TileManager.Tile.prototype = { let x = rect.left - this.boundRect.left; let y = rect.top - this.boundRect.top; - browserView.viewportToBrowserRect(rect); + // content process is not being scaled, so don't scale our rect either + //browserView.viewportToBrowserRect(rect); //rect.round(); // snap outward to get whole "pixel" (in browser coords) let ctx = this._canvas.getContext("2d"); @@ -866,7 +867,7 @@ TileManager.Tile.prototype = { let cw = browserView._contentWindow; //let cw = browser.contentWindow; - ctx.drawWindow(cw, + ctx.asyncDrawXULElement(browserView._browser, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, "grey", diff --git a/toolkit/content/tests/fennec-tile-testapp/chrome/content/foo.xul b/toolkit/content/tests/fennec-tile-testapp/chrome/content/foo.xul index f5903266e83..bdfcc113bdf 100644 --- a/toolkit/content/tests/fennec-tile-testapp/chrome/content/foo.xul +++ b/toolkit/content/tests/fennec-tile-testapp/chrome/content/foo.xul @@ -461,7 +461,7 @@ function getVisibleRect() { - +