From 161b9050f9043a95d27d33486de4ea8f463f8898 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Tue, 17 Jul 2012 16:59:45 -0700 Subject: [PATCH] Bug 745148, part 9: Hook up the pieces and enable direct compositor. r=roc --- b2g/app/b2g.js | 2 +- dom/ipc/PBrowser.ipdl | 4 +- dom/ipc/TabChild.cpp | 132 +++++++++++++++-------- dom/ipc/TabChild.h | 8 +- dom/ipc/TabParent.cpp | 7 +- dom/ipc/TabParent.h | 4 +- gfx/layers/ipc/CompositorChild.cpp | 5 +- gfx/layers/ipc/CompositorChild.h | 5 +- gfx/layers/ipc/CompositorParent.cpp | 16 +-- gfx/layers/ipc/CompositorParent.h | 5 +- gfx/layers/ipc/PCompositor.ipdl | 4 +- gfx/thebes/gfxPlatform.cpp | 9 -- layout/ipc/PRenderFrame.ipdl | 11 +- layout/ipc/RenderFrameChild.cpp | 3 +- layout/ipc/RenderFrameChild.h | 3 +- layout/ipc/RenderFrameParent.cpp | 160 +++++++++++++++++----------- layout/ipc/RenderFrameParent.h | 17 ++- widget/nsIWidget.h | 6 +- widget/xpwidgets/PuppetWidget.cpp | 16 +-- widget/xpwidgets/PuppetWidget.h | 20 ++-- widget/xpwidgets/nsBaseWidget.cpp | 15 ++- 21 files changed, 280 insertions(+), 172 deletions(-) diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js index 103284010f55..629765d82b75 100644 --- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -245,7 +245,7 @@ pref("ui.dragThresholdY", 25); // Layers Acceleration pref("layers.acceleration.disabled", false); -pref("layers.offmainthreadcomposition.enabled", false); +pref("layers.offmainthreadcomposition.enabled", true); pref("layers.async-video.enabled", true); // Web Notifications diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 93d86a6bcd71..7890d6ec02d3 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -20,6 +20,7 @@ include "IPC/nsGUIEventIPC.h"; using IPC::URI; using gfxMatrix; +using mozilla::LayersBackend; using mozilla::WindowsHandle; using nscolor; using nsCompositionEvent; @@ -174,7 +175,8 @@ parent: * Create a layout frame (encapsulating a remote layer tree) for * the page that is currently loaded in the . */ - async PRenderFrame(); + sync PRenderFrame() + returns (LayersBackend backend, int32_t maxTextureSize, uint64_t layersId); /** * Starts an offline application cache update. diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index da726217ab3a..40711451df62 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -4,59 +4,61 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "TabChild.h" -#include "mozilla/IntentionalCrash.h" -#include "mozilla/dom/PContentChild.h" -#include "mozilla/dom/PContentDialogChild.h" -#include "mozilla/layers/PLayersChild.h" -#include "mozilla/layout/RenderFrameChild.h" -#include "mozilla/docshell/OfflineCacheUpdateChild.h" +#include "base/basictypes.h" #include "BasicLayers.h" -#include "nsIWebBrowser.h" -#include "nsIWebBrowserSetup.h" -#include "nsEmbedCID.h" +#include "IndexedDBChild.h" +#include "mozilla/IntentionalCrash.h" +#include "mozilla/docshell/OfflineCacheUpdateChild.h" +#include "mozilla/dom/PContentChild.h" +#include "mozilla/dom/PContentDialogChild.h" +#include "mozilla/ipc/DocumentRendererChild.h" +#include "mozilla/layers/CompositorChild.h" +#include "mozilla/layers/PLayersChild.h" +#include "mozilla/layout/RenderFrameChild.h" #include "nsComponentManagerUtils.h" +#include "nsComponentManagerUtils.h" +#include "nsContentUtils.h" +#include "nsEmbedCID.h" +#include "nsEventListenerManager.h" #include "nsIBaseWindow.h" +#include "nsIComponentManager.h" +#include "nsIDOMClassInfo.h" +#include "nsIDOMEvent.h" #include "nsIDOMWindow.h" -#include "nsIWebProgress.h" +#include "nsIDOMWindowUtils.h" #include "nsIDocShell.h" #include "nsIDocShellTreeItem.h" -#include "nsThreadUtils.h" +#include "nsIFrame.h" #include "nsIInterfaceRequestorUtils.h" -#include "mozilla/ipc/DocumentRendererChild.h" #include "nsIInterfaceRequestorUtils.h" -#include "nsPIDOMWindow.h" -#include "nsIDOMWindowUtils.h" +#include "nsIJSContextStack.h" +#include "nsIJSRuntimeService.h" +#include "nsISSLStatusProvider.h" +#include "nsIScriptContext.h" +#include "nsIScriptGlobalObject.h" +#include "nsIScriptSecurityManager.h" +#include "nsISecureBrowserUI.h" +#include "nsIServiceManager.h" #include "nsISupportsImpl.h" #include "nsIURI.h" -#include "nsIWebBrowserFocus.h" -#include "nsIDOMEvent.h" -#include "nsIComponentManager.h" -#include "nsIServiceManager.h" -#include "nsIJSRuntimeService.h" -#include "nsContentUtils.h" -#include "nsIDOMClassInfo.h" -#include "nsIXPCSecurityManager.h" -#include "nsIJSContextStack.h" -#include "nsComponentManagerUtils.h" -#include "nsIScriptSecurityManager.h" -#include "nsScriptLoader.h" -#include "nsPIWindowRoot.h" -#include "nsIScriptContext.h" -#include "nsInterfaceHashtable.h" -#include "nsPresContext.h" -#include "nsIScriptGlobalObject.h" -#include "nsWeakReference.h" -#include "nsISecureBrowserUI.h" -#include "nsISSLStatusProvider.h" -#include "nsSerializationHelper.h" -#include "nsIFrame.h" #include "nsIView.h" -#include "nsEventListenerManager.h" +#include "nsIWebBrowser.h" +#include "nsIWebBrowserFocus.h" +#include "nsIWebBrowserSetup.h" +#include "nsIWebProgress.h" +#include "nsIXPCSecurityManager.h" +#include "nsInterfaceHashtable.h" +#include "nsPIDOMWindow.h" +#include "nsPIWindowRoot.h" +#include "nsPresContext.h" +#include "nsScriptLoader.h" +#include "nsSerializationHelper.h" +#include "nsThreadUtils.h" +#include "nsWeakReference.h" #include "PCOMContentPermissionRequestChild.h" +#include "TabChild.h" #include "xpcpublic.h" -#include "IndexedDBChild.h" using namespace mozilla::dom; using namespace mozilla::ipc; @@ -496,6 +498,12 @@ TabChild::DestroyWindow() } } +bool +TabChild::UseDirectCompositor() +{ + return !!CompositorChild::Get(); +} + void TabChild::ActorDestroy(ActorDestroyReason why) { @@ -954,7 +962,9 @@ TabChild::RecvDestroy() } PRenderFrameChild* -TabChild::AllocPRenderFrame() +TabChild::AllocPRenderFrame(LayersBackend* aBackend, + int32_t* aMaxTextureSize, + uint64_t* aLayersId) { return new RenderFrameChild(); } @@ -1020,19 +1030,30 @@ TabChild::InitWidget(const nsIntSize& size) nsnull // nsDeviceContext ); + LayerManager::LayersBackend be; + uint64_t id; + int32_t maxTextureSize; RenderFrameChild* remoteFrame = - static_cast(SendPRenderFrameConstructor()); + static_cast(SendPRenderFrameConstructor( + &be, &maxTextureSize, &id)); if (!remoteFrame) { NS_WARNING("failed to construct RenderFrame"); return false; } - NS_ABORT_IF_FALSE(0 == remoteFrame->ManagedPLayersChild().Length(), - "shouldn't have a shadow manager yet"); - LayerManager::LayersBackend be; - PRInt32 maxTextureSize; - uint64_t id; - PLayersChild* shadowManager = remoteFrame->SendPLayersConstructor(&be, &maxTextureSize, &id); + PLayersChild* shadowManager = nsnull; + if (id != 0) { + // Pushing layers transactions directly to a separate + // compositor context. + shadowManager = + CompositorChild::Get()->SendPLayersConstructor(be, id, + &be, + &maxTextureSize); + } else { + // Pushing transactions to the parent content. + shadowManager = remoteFrame->SendPLayersConstructor(); + } + if (!shadowManager) { NS_WARNING("failed to construct LayersChild"); // This results in |remoteFrame| being deleted. @@ -1060,6 +1081,23 @@ TabChild::SetBackgroundColor(const nscolor& aColor) } } +void +TabChild::NotifyPainted() +{ + if (UseDirectCompositor()) { + // FIXME/bug XXXXXX: in theory, we should only have to push a + // txn to our remote frame once, and the + // display-list/FrameLayerBuilder code there will manage the + // tree from there on. But in practice, that doesn't work for + // some unknown reason. So for now, always notify the content + // thread in the parent process. It's wasteful but won't + // result in unnecessary repainting or even composites + // (usually, unless timing is unlucky), since they're + // throttled. + mRemoteFrame->SendNotifyCompositorTransaction(); + } +} + NS_IMETHODIMP TabChild::GetMessageManager(nsIContentFrameMessageManager** aResult) { diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index e8babe1f482b..d41f0df9dff1 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -232,9 +232,13 @@ public: nsIPrincipal* GetPrincipal() { return mPrincipal; } void SetBackgroundColor(const nscolor& aColor); + + void NotifyPainted(); protected: NS_OVERRIDE - virtual PRenderFrameChild* AllocPRenderFrame(); + virtual PRenderFrameChild* AllocPRenderFrame(LayersBackend* aBackend, + int32_t* aMaxTextureSize, + uint64_t* aLayersId); NS_OVERRIDE virtual bool DeallocPRenderFrame(PRenderFrameChild* aFrame); NS_OVERRIDE @@ -248,6 +252,8 @@ protected: virtual bool DeallocPIndexedDB(PIndexedDBChild* aActor); private: + bool UseDirectCompositor(); + void ActorDestroy(ActorDestroyReason why); bool InitTabChildGlobal(); diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index aff5f7e82adb..4149c2cce00f 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -846,10 +846,13 @@ TabParent::HandleDelayedDialogs() } PRenderFrameParent* -TabParent::AllocPRenderFrame() +TabParent::AllocPRenderFrame(LayersBackend* aBackend, + int32_t* aMaxTextureSize, + uint64_t* aLayersId) { nsRefPtr frameLoader = GetFrameLoader(); - return new RenderFrameParent(frameLoader); + return new RenderFrameParent(frameLoader, + aBackend, aMaxTextureSize, aLayersId); } bool diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index d84020048d1e..1d1072461e4c 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -203,7 +203,9 @@ protected: bool AllowContentIME(); NS_OVERRIDE - virtual PRenderFrameParent* AllocPRenderFrame(); + virtual PRenderFrameParent* AllocPRenderFrame(LayersBackend* aBackend, + int32_t* aMaxTextureSize, + uint64_t* aLayersId); NS_OVERRIDE virtual bool DeallocPRenderFrame(PRenderFrameParent* aFrame); diff --git a/gfx/layers/ipc/CompositorChild.cpp b/gfx/layers/ipc/CompositorChild.cpp index fa9257873dd3..1c359941bc20 100644 --- a/gfx/layers/ipc/CompositorChild.cpp +++ b/gfx/layers/ipc/CompositorChild.cpp @@ -70,7 +70,10 @@ CompositorChild::Get() } PLayersChild* -CompositorChild::AllocPLayers(const LayersBackend &aBackend, const uint64_t& aId, int* aMaxTextureSize) +CompositorChild::AllocPLayers(const LayersBackend& aBackendHint, + const uint64_t& aId, + LayersBackend* aBackend, + int* aMaxTextureSize) { return new ShadowLayersChild(); } diff --git a/gfx/layers/ipc/CompositorChild.h b/gfx/layers/ipc/CompositorChild.h index a26fa60eea04..d789a1b87512 100644 --- a/gfx/layers/ipc/CompositorChild.h +++ b/gfx/layers/ipc/CompositorChild.h @@ -36,7 +36,10 @@ public: static PCompositorChild* Get(); protected: - virtual PLayersChild* AllocPLayers(const LayersBackend &aBackend, const uint64_t& aId, int* aMaxTextureSize); + virtual PLayersChild* AllocPLayers(const LayersBackend& aBackendHint, + const uint64_t& aId, + LayersBackend* aBackend, + int* aMaxTextureSize); virtual bool DeallocPLayers(PLayersChild *aChild); virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index e2f7d3c17aed..3474fef569e3 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -624,8 +624,9 @@ CompositorParent::ShadowLayersUpdated(ShadowLayersParent* aLayerTree, } PLayersParent* -CompositorParent::AllocPLayers(const LayersBackend& aBackendType, +CompositorParent::AllocPLayers(const LayersBackend& aBackendHint, const uint64_t& aId, + LayersBackend* aBackend, int32_t* aMaxTextureSize) { MOZ_ASSERT(aId == 0); @@ -637,7 +638,9 @@ CompositorParent::AllocPLayers(const LayersBackend& aBackendType, mWidgetSize.width = rect.width; mWidgetSize.height = rect.height; - if (aBackendType == LayerManager::LAYERS_OPENGL) { + *aBackend = aBackendHint; + + if (aBackendHint == LayerManager::LAYERS_OPENGL) { nsRefPtr layerManager; layerManager = new LayerManagerOGL(mWidget, mEGLSurfaceSize.width, mEGLSurfaceSize.height, mRenderToEGLSurface); @@ -659,7 +662,7 @@ CompositorParent::AllocPLayers(const LayersBackend& aBackendType, } *aMaxTextureSize = layerManager->GetMaxTextureSize(); return new ShadowLayersParent(slm, this, 0); - } else if (aBackendType == LayerManager::LAYERS_BASIC) { + } else if (aBackendHint == LayerManager::LAYERS_BASIC) { nsRefPtr layerManager = new BasicShadowLayerManager(mWidget); mWidget = NULL; mLayerManager = layerManager; @@ -768,6 +771,7 @@ public: virtual PLayersParent* AllocPLayers(const LayersBackend& aBackendType, const uint64_t& aId, + LayersBackend* aBackend, int32_t* aMaxTextureSize) MOZ_OVERRIDE; virtual bool DeallocPLayers(PLayersParent* aLayers) MOZ_OVERRIDE; @@ -846,16 +850,16 @@ CrossProcessCompositorParent::ActorDestroy(ActorDestroyReason aWhy) PLayersParent* CrossProcessCompositorParent::AllocPLayers(const LayersBackend& aBackendType, const uint64_t& aId, + LayersBackend* aBackend, int32_t* aMaxTextureSize) { MOZ_ASSERT(aId != 0); nsRefPtr lm = sCurrentCompositor->GetLayerManager(); + *aBackend = lm->GetBackendType(); *aMaxTextureSize = lm->GetMaxTextureSize(); return new ShadowLayersParent(lm->AsShadowManager(), this, aId); - - return nsnull; - } +} bool CrossProcessCompositorParent::DeallocPLayers(PLayersParent* aLayers) diff --git a/gfx/layers/ipc/CompositorParent.h b/gfx/layers/ipc/CompositorParent.h index 6ecc8f10e36a..1b682acd5a42 100644 --- a/gfx/layers/ipc/CompositorParent.h +++ b/gfx/layers/ipc/CompositorParent.h @@ -117,7 +117,10 @@ public: Create(Transport* aTransport, ProcessId aOtherProcess); protected: - virtual PLayersParent* AllocPLayers(const LayersBackend& aBackendType, const uint64_t& aId, int32_t* aMaxTextureSize); + virtual PLayersParent* AllocPLayers(const LayersBackend& aBackendHint, + const uint64_t& aId, + LayersBackend* aBackend, + int32_t* aMaxTextureSize); virtual bool DeallocPLayers(PLayersParent* aLayers); virtual void ScheduleTask(CancelableTask*, int); virtual void Composite(); diff --git a/gfx/layers/ipc/PCompositor.ipdl b/gfx/layers/ipc/PCompositor.ipdl index 3ecd0ed57f3a..70d9dcffa666 100644 --- a/gfx/layers/ipc/PCompositor.ipdl +++ b/gfx/layers/ipc/PCompositor.ipdl @@ -38,8 +38,8 @@ parent: sync Pause(); sync Resume(); - sync PLayers(LayersBackend backend, uint64_t id) - returns (int32_t maxTextureSize); + sync PLayers(LayersBackend backendHint, uint64_t id) + returns (LayersBackend backend, int32_t maxTextureSize); }; } // layers diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index c6a8a47dfe68..af8d99442d78 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -260,15 +260,6 @@ gfxPlatform::Init() useOffMainThreadCompositing = Preferences::GetBool( "layers.offmainthreadcomposition.enabled", false); - // Until https://bugzilla.mozilla.org/show_bug.cgi?id=745148 lands, - // we use either omtc or content processes, but not both. Prefer - // OOP content to omtc. (Currently, this only affects b2g.) - // - // See https://bugzilla.mozilla.org/show_bug.cgi?id=761962 . - if (!Preferences::GetBool("dom.ipc.tabs.disabled", true)) { - // Disable omtc if OOP content isn't force-disabled. - useOffMainThreadCompositing = false; - } #endif if (useOffMainThreadCompositing && (XRE_GetProcessType() == diff --git a/layout/ipc/PRenderFrame.ipdl b/layout/ipc/PRenderFrame.ipdl index bf13943e0ac8..bcac7c18a9f6 100644 --- a/layout/ipc/PRenderFrame.ipdl +++ b/layout/ipc/PRenderFrame.ipdl @@ -39,14 +39,19 @@ parent: * |id| is set to 0 in the "direct" case, and to a whole number * in the "indirect" case. */ - sync PLayers() - returns (LayersBackend backend, int32_t maxTextureSize, uint64_t layersId); + async PLayers(); + + async NotifyCompositorTransaction(); async __delete__(); -state EMPTY: +state EMPTY_OR_DIRECT_COMPOSITOR: recv PLayers goto HAVE_CONTENT; + recv NotifyCompositorTransaction goto EMPTY_OR_DIRECT_COMPOSITOR; + recv __delete__; + state HAVE_CONTENT: + recv NotifyCompositorTransaction goto HAVE_CONTENT; recv __delete__; }; diff --git a/layout/ipc/RenderFrameChild.cpp b/layout/ipc/RenderFrameChild.cpp index 8eb960f7e0f2..9c3c6fe3fe22 100644 --- a/layout/ipc/RenderFrameChild.cpp +++ b/layout/ipc/RenderFrameChild.cpp @@ -33,8 +33,7 @@ RenderFrameChild::Destroy() } PLayersChild* -RenderFrameChild::AllocPLayers(LayerManager::LayersBackend* aBackendType, - int* aMaxTextureSize, uint64_t* aId) +RenderFrameChild::AllocPLayers() { return new ShadowLayersChild(); } diff --git a/layout/ipc/RenderFrameChild.h b/layout/ipc/RenderFrameChild.h index f89f34505ffe..6ba1ed0449b9 100644 --- a/layout/ipc/RenderFrameChild.h +++ b/layout/ipc/RenderFrameChild.h @@ -23,8 +23,7 @@ public: protected: NS_OVERRIDE - virtual PLayersChild* AllocPLayers(LayerManager::LayersBackend* aBackendType, - int* aMaxTextureSize, uint64_t* aId); + virtual PLayersChild* AllocPLayers(); NS_OVERRIDE virtual bool DeallocPLayers(PLayersChild* aLayers); }; diff --git a/layout/ipc/RenderFrameParent.cpp b/layout/ipc/RenderFrameParent.cpp index 1058793a8c9a..1360aefeb470 100644 --- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -5,21 +5,22 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "mozilla/layers/ShadowLayersParent.h" +#include "base/basictypes.h" #include "BasicLayers.h" +#include "gfx3DMatrix.h" #include "LayerManagerOGL.h" #ifdef MOZ_ENABLE_D3D9_LAYER -#include "LayerManagerD3D9.h" +# include "LayerManagerD3D9.h" #endif //MOZ_ENABLE_D3D9_LAYER -#include "RenderFrameParent.h" - -#include "gfx3DMatrix.h" -#include "nsFrameLoader.h" -#include "nsViewportFrame.h" -#include "nsSubDocumentFrame.h" -#include "nsIObserver.h" +#include "mozilla/layers/CompositorParent.h" +#include "mozilla/layers/ShadowLayersParent.h" #include "nsContentUtils.h" +#include "nsFrameLoader.h" +#include "nsIObserver.h" +#include "nsSubDocumentFrame.h" +#include "nsViewportFrame.h" +#include "RenderFrameParent.h" typedef nsContentView::ViewConfig ViewConfig; using namespace mozilla::layers; @@ -444,14 +445,37 @@ BuildBackgroundPatternFor(ContainerLayer* aContainer, aContainer->InsertAfter(layer, nsnull); } -RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader) - : mFrameLoader(aFrameLoader) +already_AddRefed +GetFrom(nsFrameLoader* aFrameLoader) +{ + nsIDocument* doc = aFrameLoader->GetOwnerDoc(); + return nsContentUtils::LayerManagerForDocument(doc); +} + +RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader, + LayerManager::LayersBackend* aBackendType, + int* aMaxTextureSize, + uint64_t* aId) + : mLayersId(0) + , mFrameLoader(aFrameLoader) , mFrameLoaderDestroyed(false) , mBackgroundColor(gfxRGBA(1, 1, 1)) { - if (aFrameLoader) { - mContentViews[FrameMetrics::ROOT_SCROLL_ID] = - new nsContentView(aFrameLoader, FrameMetrics::ROOT_SCROLL_ID); + mContentViews[FrameMetrics::ROOT_SCROLL_ID] = + new nsContentView(aFrameLoader, FrameMetrics::ROOT_SCROLL_ID); + + *aBackendType = LayerManager::LAYERS_NONE; + *aMaxTextureSize = 0; + *aId = 0; + + nsRefPtr lm = GetFrom(mFrameLoader); + *aBackendType = lm->GetBackendType(); + *aMaxTextureSize = lm->GetMaxTextureSize(); + + if (CompositorParent::CompositorLoop()) { + // Our remote frame will push layers updates to the compositor, + // and we'll keep an indirect reference to that tree. + *aId = mLayersId = CompositorParent::AllocateLayerTreeId(); } } @@ -492,34 +516,12 @@ void RenderFrameParent::ShadowLayersUpdated(ShadowLayersParent* aLayerTree, bool isFirstPaint) { - mFrameLoader->SetCurrentRemoteFrame(this); - // View map must only contain views that are associated with the current // shadow layer tree. We must always update the map when shadow layers // are updated. BuildViewMap(); - nsIFrame* docFrame = mFrameLoader->GetPrimaryFrameOfOwningContent(); - if (!docFrame) { - // Bad, but nothing we can do about it (XXX/cjones: or is there? - // maybe bug 589337?). When the new frame is created, we'll - // probably still be the current render frame and will get to draw - // our content then. Or, we're shutting down and this update goes - // to /dev/null. - return; - } - - // FIXME/cjones: we should collect the rects/regions updated for - // Painted*Layer() calls and pass that region to here, then only - // invalidate that rect - // - // We pass INVALIDATE_NO_THEBES_LAYERS here because we're - // invalidating the on behalf of its counterpart in the - // content process. Not only do we not need to invalidate the - // shadow layers, things would just break if we did --- we have no - // way to repaint shadow layers from this process. - nsRect rect = nsRect(nsPoint(0, 0), docFrame->GetRect().Size()); - docFrame->InvalidateWithFlags(rect, nsIFrame::INVALIDATE_NO_THEBES_LAYERS); + TriggerRepaint(); } already_AddRefed @@ -545,6 +547,25 @@ RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder, return nsnull; } + uint64_t id = GetLayerTreeId(); + if (0 != id) { + MOZ_ASSERT(!GetRootLayer()); + + nsRefPtr layer = aManager->CreateRefLayer(); + if (!layer) { + // Probably a temporary layer manager that doesn't know how to + // use ref layers. + return nsnull; + } + layer->SetReferentId(id); + layer->SetVisibleRegion(aVisibleRect); + nsIntPoint rootFrameOffset = GetRootFrameOffset(aFrame, aBuilder); + layer->SetTransform( + gfx3DMatrix::Translation(rootFrameOffset.x, rootFrameOffset.y, 0.0)); + + return layer.forget(); + } + if (mContainer) { ClearContainer(mContainer); } @@ -608,35 +629,21 @@ RenderFrameParent::ActorDestroy(ActorDestroyReason why) mFrameLoader = nsnull; } -PLayersParent* -RenderFrameParent::AllocPLayers(LayerManager::LayersBackend* aBackendType, - int* aMaxTextureSize, - uint64_t* aId) +bool +RenderFrameParent::RecvNotifyCompositorTransaction() { - *aBackendType = LayerManager::LAYERS_NONE; - *aMaxTextureSize = 0; - *aId = 0; + TriggerRepaint(); + return true; +} +PLayersParent* +RenderFrameParent::AllocPLayers() +{ if (!mFrameLoader || mFrameLoaderDestroyed) { return nsnull; } - - nsIDocument* doc = mFrameLoader->GetOwnerDoc(); - nsRefPtr lm = nsContentUtils::LayerManagerForDocument(doc); - ShadowLayerManager* slm = lm->AsShadowManager(); - if (!slm) { - return nsnull; - } - *aBackendType = lm->GetBackendType(); - *aMaxTextureSize = lm->GetMaxTextureSize(); -#if 0 // Enabled in later patch - if (CompositorParent::CompositorLoop()) { - // Our remote frame will push layers updates to the compositor, - // and we'll keep an indirect reference to that tree. - *aId = CompositorParent::AllocateLayerTreeId(); - } -#endif - return new ShadowLayersParent(slm, this, *aId); + nsRefPtr lm = GetFrom(mFrameLoader); + return new ShadowLayersParent(lm->AsShadowManager(), this, 0); } bool @@ -680,6 +687,34 @@ RenderFrameParent::BuildViewMap() mContentViews = newContentViews; } +void +RenderFrameParent::TriggerRepaint() +{ + mFrameLoader->SetCurrentRemoteFrame(this); + + nsIFrame* docFrame = mFrameLoader->GetPrimaryFrameOfOwningContent(); + if (!docFrame) { + // Bad, but nothing we can do about it (XXX/cjones: or is there? + // maybe bug 589337?). When the new frame is created, we'll + // probably still be the current render frame and will get to draw + // our content then. Or, we're shutting down and this update goes + // to /dev/null. + return; + } + + // FIXME/cjones: we should collect the rects/regions updated for + // Painted*Layer() calls and pass that region to here, then only + // invalidate that rect + // + // We pass INVALIDATE_NO_THEBES_LAYERS here because we're + // invalidating the on behalf of its counterpart in the + // content process. Not only do we not need to invalidate the + // shadow layers, things would just break if we did --- we have no + // way to repaint shadow layers from this process. + nsRect rect = nsRect(nsPoint(0, 0), docFrame->GetRect().Size()); + docFrame->InvalidateWithFlags(rect, nsIFrame::INVALIDATE_NO_THEBES_LAYERS); +} + ShadowLayersParent* RenderFrameParent::GetShadowLayers() const { @@ -693,8 +728,7 @@ RenderFrameParent::GetShadowLayers() const uint64_t RenderFrameParent::GetLayerTreeId() const { - ShadowLayersParent* shadowLayers = GetShadowLayers(); - return shadowLayers ? shadowLayers->GetId() : 0; + return mLayersId; } ContainerLayer* diff --git a/layout/ipc/RenderFrameParent.h b/layout/ipc/RenderFrameParent.h index 74e67d6a86b4..97c1f16341c7 100644 --- a/layout/ipc/RenderFrameParent.h +++ b/layout/ipc/RenderFrameParent.h @@ -40,7 +40,10 @@ class RenderFrameParent : public PRenderFrameParent, public: typedef std::map > ViewMap; - RenderFrameParent(nsFrameLoader* aFrameLoader); + RenderFrameParent(nsFrameLoader* aFrameLoader, + LayerManager::LayersBackend* aBackendType, + int* aMaxTextureSize, + uint64_t* aId); virtual ~RenderFrameParent(); void Destroy(); @@ -73,18 +76,24 @@ public: protected: void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE; - virtual PLayersParent* - AllocPLayers(LayerManager::LayersBackend* aBackendType, - int* aMaxTextureSize, uint64_t* aLayersId) MOZ_OVERRIDE; + virtual bool RecvNotifyCompositorTransaction() MOZ_OVERRIDE; + + virtual PLayersParent* AllocPLayers() MOZ_OVERRIDE; virtual bool DeallocPLayers(PLayersParent* aLayers) MOZ_OVERRIDE; private: void BuildViewMap(); + void TriggerRepaint(); ShadowLayersParent* GetShadowLayers() const; uint64_t GetLayerTreeId() const; ContainerLayer* GetRootLayer() const; + // When our child frame is pushing transactions directly to the + // compositor, this is the ID of its layer tree in the compositor's + // context. + uint64_t mLayersId; + nsRefPtr mFrameLoader; nsRefPtr mContainer; diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index f7a4a60dd1db..9bc62dca9e20 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -38,7 +38,7 @@ class ViewWrapper; namespace mozilla { namespace dom { -class PBrowserChild; +class TabChild; } namespace layers { class PLayersChild; @@ -359,7 +359,7 @@ struct InputContextAction { */ class nsIWidget : public nsISupports { protected: - typedef mozilla::dom::PBrowserChild PBrowserChild; + typedef mozilla::dom::TabChild TabChild; public: typedef mozilla::layers::LayerManager LayerManager; @@ -1543,7 +1543,7 @@ class nsIWidget : public nsISupports { * The returned widget must still be nsIWidget::Create()d. */ static already_AddRefed - CreatePuppetWidget(PBrowserChild *aTabChild); + CreatePuppetWidget(TabChild* aTabChild); /** * Reparent this widget's native widget. diff --git a/widget/xpwidgets/PuppetWidget.cpp b/widget/xpwidgets/PuppetWidget.cpp index ba7f366e949e..9b96181a11be 100644 --- a/widget/xpwidgets/PuppetWidget.cpp +++ b/widget/xpwidgets/PuppetWidget.cpp @@ -5,14 +5,17 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "mozilla/dom/PBrowserChild.h" +#include "base/basictypes.h" + #include "BasicLayers.h" +#include "gfxPlatform.h" #if defined(MOZ_ENABLE_D3D10_LAYER) # include "LayerManagerD3D10.h" #endif - -#include "gfxPlatform.h" +#include "mozilla/dom/TabChild.h" #include "mozilla/Hal.h" +#include "mozilla/layers/CompositorChild.h" +#include "mozilla/layers/PLayersChild.h" #include "PuppetWidget.h" using namespace mozilla::dom; @@ -30,7 +33,7 @@ InvalidateRegion(nsIWidget* aWidget, const nsIntRegion& aRegion) } /*static*/ already_AddRefed -nsIWidget::CreatePuppetWidget(PBrowserChild *aTabChild) +nsIWidget::CreatePuppetWidget(TabChild* aTabChild) { NS_ABORT_IF_FALSE(nsIWidget::UsePuppetWidgets(), "PuppetWidgets not allowed in this configuration"); @@ -63,7 +66,7 @@ const size_t PuppetWidget::kMaxDimension = 4000; NS_IMPL_ISUPPORTS_INHERITED1(PuppetWidget, nsBaseWidget, nsISupportsWeakReference) -PuppetWidget::PuppetWidget(PBrowserChild *aTabChild) +PuppetWidget::PuppetWidget(TabChild* aTabChild) : mTabChild(aTabChild) , mDPI(-1) { @@ -503,7 +506,8 @@ PuppetWidget::DispatchPaintEvent() ctx->Clip(); AutoLayerManagerSetup setupLayerManager(this, ctx, BasicLayerManager::BUFFER_NONE); - DispatchEvent(&event, status); + DispatchEvent(&event, status); + mTabChild->NotifyPainted(); } } diff --git a/widget/xpwidgets/PuppetWidget.h b/widget/xpwidgets/PuppetWidget.h index 3e768cfe0582..d6fa70de54ee 100644 --- a/widget/xpwidgets/PuppetWidget.h +++ b/widget/xpwidgets/PuppetWidget.h @@ -25,17 +25,23 @@ class gfxASurface; namespace mozilla { + +namespace dom { +class TabChild; +} + namespace widget { class PuppetWidget : public nsBaseWidget, public nsSupportsWeakReference { + typedef mozilla::dom::TabChild TabChild; typedef nsBaseWidget Base; // The width and height of the "widget" are clamped to this. static const size_t kMaxDimension; public: - PuppetWidget(PBrowserChild *aTabChild); + PuppetWidget(TabChild* aTabChild); virtual ~PuppetWidget(); NS_DECL_ISUPPORTS_INHERITED @@ -176,12 +182,12 @@ private: }; // TabChild normally holds a strong reference to this PuppetWidget - // or its root ancestor, but each PuppetWidget also needs a reference - // back to TabChild (e.g. to delegate nsIWidget IME calls to chrome) - // So we hold a weak reference to TabChild (PBrowserChild) here. - // Since it's possible for TabChild to outlive the PuppetWidget, - // we clear this weak reference in Destroy() - PBrowserChild *mTabChild; + // or its root ancestor, but each PuppetWidget also needs a + // reference back to TabChild (e.g. to delegate nsIWidget IME calls + // to chrome) So we hold a weak reference to TabChild here. Since + // it's possible for TabChild to outlive the PuppetWidget, we clear + // this weak reference in Destroy() + TabChild* mTabChild; // The "widget" to which we delegate events if we don't have an // event handler. nsRefPtr mChild; diff --git a/widget/xpwidgets/nsBaseWidget.cpp b/widget/xpwidgets/nsBaseWidget.cpp index 98903fd29d38..6ee14d13e178 100644 --- a/widget/xpwidgets/nsBaseWidget.cpp +++ b/widget/xpwidgets/nsBaseWidget.cpp @@ -878,11 +878,11 @@ void nsBaseWidget::CreateCompositor() mCompositorChild->Open(parentChannel, childMessageLoop, childSide); PRInt32 maxTextureSize; PLayersChild* shadowManager; - if (mUseAcceleratedRendering) { - shadowManager = mCompositorChild->SendPLayersConstructor(LayerManager::LAYERS_OPENGL, 0, &maxTextureSize); - } else { - shadowManager = mCompositorChild->SendPLayersConstructor(LayerManager::LAYERS_BASIC, 0, &maxTextureSize); - } + LayerManager::LayersBackend backendHint = + mUseAcceleratedRendering ? LayerManager::LAYERS_OPENGL : LayerManager::LAYERS_BASIC; + LayerManager::LayersBackend parentBackend; + shadowManager = mCompositorChild->SendPLayersConstructor( + backendHint, 0, &parentBackend, &maxTextureSize); if (shadowManager) { ShadowLayerForwarder* lf = lm->AsShadowForwarder(); @@ -892,10 +892,7 @@ void nsBaseWidget::CreateCompositor() return; } lf->SetShadowManager(shadowManager); - if (mUseAcceleratedRendering) - lf->SetParentBackendType(LayerManager::LAYERS_OPENGL); - else - lf->SetParentBackendType(LayerManager::LAYERS_BASIC); + lf->SetParentBackendType(parentBackend); lf->SetMaxTextureSize(maxTextureSize); mLayerManager = lm;