author | Chris Jones <jones.chris.g@gmail.com> |
Tue, 17 Jul 2012 16:59:45 -0700 | |
changeset 105604 | 4a58089672882ca7f22e9866d2becf90afced9d5 |
parent 105603 | aeafc64692a5f965917ba07b1f7bf2d99413047e |
child 105605 | fcba8ae674df875450cf3c94a527e775949d970f |
push id | 214 |
push user | akeybl@mozilla.com |
push date | Wed, 14 Nov 2012 20:38:59 +0000 |
treeherder | mozilla-release@c8b08ec8e1aa [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | roc |
bugs | 745148 |
milestone | 17.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
|
--- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -240,17 +240,17 @@ pref("editor.singleLine.pasteNewlines", // threshold where a tap becomes a drag, in 1/240" reference pixels // The names of the preferences are to be in sync with nsEventStateManager.cpp pref("ui.dragThresholdX", 25); 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 pref("notification.feature.enabled", true); // IndexedDB pref("indexedDB.feature.enabled", true); pref("dom.indexedDB.warningQuota", 5);
--- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -15,16 +15,17 @@ include protocol PIndexedDB; include "mozilla/dom/TabMessageUtils.h"; include "gfxMatrix.h"; include "mozilla/net/NeckoMessageUtils.h"; include "IPC/nsGUIEventIPC.h"; using IPC::URI; using gfxMatrix; +using mozilla::LayersBackend; using mozilla::WindowsHandle; using nscolor; using nsCompositionEvent; using nsIMEUpdatePreference; using nsIntSize; using nsKeyEvent; using nsMouseEvent; using nsMouseScrollEvent; @@ -169,17 +170,18 @@ parent: PContentDialog(PRUint32 aType, nsCString aName, nsCString aFeatures, PRInt32[] aIntParams, nsString[] aStringParams); /** * Create a layout frame (encapsulating a remote layer tree) for * the page that is currently loaded in the <browser>. */ - async PRenderFrame(); + sync PRenderFrame() + returns (LayersBackend backend, int32_t maxTextureSize, uint64_t layersId); /** * Starts an offline application cache update. * @param manifestURI * URI of the manifest to fetch, the application cache group ID * @param documentURI * URI of the document that referred the manifest * @param clientID
--- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -1,67 +1,69 @@ /* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */ /* vim: set sw=2 sts=2 ts=8 et tw=80 : */ /* This Source Code Form is subject to the terms of the Mozilla Public * 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 "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 "nsIView.h" +#include "nsIWebBrowser.h" #include "nsIWebBrowserFocus.h" -#include "nsIDOMEvent.h" -#include "nsIComponentManager.h" -#include "nsIServiceManager.h" -#include "nsIJSRuntimeService.h" -#include "nsContentUtils.h" -#include "nsIDOMClassInfo.h" +#include "nsIWebBrowserSetup.h" +#include "nsIWebProgress.h" #include "nsIXPCSecurityManager.h" -#include "nsIJSContextStack.h" -#include "nsComponentManagerUtils.h" -#include "nsIScriptSecurityManager.h" -#include "nsScriptLoader.h" +#include "nsInterfaceHashtable.h" +#include "nsPIDOMWindow.h" #include "nsPIWindowRoot.h" -#include "nsIScriptContext.h" -#include "nsInterfaceHashtable.h" #include "nsPresContext.h" -#include "nsIScriptGlobalObject.h" +#include "nsScriptLoader.h" +#include "nsSerializationHelper.h" +#include "nsThreadUtils.h" #include "nsWeakReference.h" -#include "nsISecureBrowserUI.h" -#include "nsISSLStatusProvider.h" -#include "nsSerializationHelper.h" -#include "nsIFrame.h" -#include "nsIView.h" -#include "nsEventListenerManager.h" #include "PCOMContentPermissionRequestChild.h" +#include "TabChild.h" #include "xpcpublic.h" -#include "IndexedDBChild.h" using namespace mozilla::dom; using namespace mozilla::ipc; using namespace mozilla::layers; using namespace mozilla::layout; using namespace mozilla::docshell; using namespace mozilla::dom::indexedDB; @@ -491,16 +493,22 @@ TabChild::DestroyWindow() } if (mRemoteFrame) { mRemoteFrame->Destroy(); mRemoteFrame = nsnull; } } +bool +TabChild::UseDirectCompositor() +{ + return !!CompositorChild::Get(); +} + void TabChild::ActorDestroy(ActorDestroyReason why) { if (mTabChildGlobal) { // The messageManager relays messages via the TabChild which // no longer exists. static_cast<nsFrameMessageManager*> (mTabChildGlobal->mMessageManager.get())->Disconnect(); @@ -949,17 +957,19 @@ TabChild::RecvDestroy() // XXX what other code in ~TabChild() should we be running here? DestroyWindow(); return Send__delete__(this); } PRenderFrameChild* -TabChild::AllocPRenderFrame() +TabChild::AllocPRenderFrame(LayersBackend* aBackend, + int32_t* aMaxTextureSize, + uint64_t* aLayersId) { return new RenderFrameChild(); } bool TabChild::DeallocPRenderFrame(PRenderFrameChild* aFrame) { delete aFrame; @@ -1015,29 +1025,40 @@ TabChild::InitWidget(const nsIntSize& si } mWidget->Create( nsnull, 0, // no parents nsIntRect(nsIntPoint(0, 0), size), nsnull, // HandleWidgetEvent nsnull // nsDeviceContext ); + LayerManager::LayersBackend be; + uint64_t id; + int32_t maxTextureSize; RenderFrameChild* remoteFrame = - static_cast<RenderFrameChild*>(SendPRenderFrameConstructor()); + static_cast<RenderFrameChild*>(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. PRenderFrameChild::Send__delete__(remoteFrame); return false; } ShadowLayerForwarder* lf = @@ -1055,16 +1076,33 @@ void TabChild::SetBackgroundColor(const nscolor& aColor) { if (mLastBackgroundColor != aColor) { mLastBackgroundColor = aColor; SendSetBackgroundColor(mLastBackgroundColor); } } +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) { if (mTabChildGlobal) { NS_ADDREF(*aResult = mTabChildGlobal); return NS_OK; } *aResult = nsnull;
--- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -227,32 +227,38 @@ public: nsIWebNavigation* WebNavigation() { return mWebNav; } JSContext* GetJSContext() { return mCx; } 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 virtual bool RecvDestroy(); nsEventStatus DispatchWidgetEvent(nsGUIEvent& event); virtual PIndexedDBChild* AllocPIndexedDB(const nsCString& aASCIIOrigin, bool* /* aAllowed */); virtual bool DeallocPIndexedDB(PIndexedDBChild* aActor); private: + bool UseDirectCompositor(); + void ActorDestroy(ActorDestroyReason why); bool InitTabChildGlobal(); bool InitWidget(const nsIntSize& size); void DestroyWindow(); // Call RecvShow(nsIntSize(0, 0)) and block future calls to RecvShow(). void DoFakeShow();
--- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -841,20 +841,23 @@ TabParent::HandleDelayedDialogs() if (ShouldDelayDialogs() && mDelayedDialogs.Length()) { nsContentUtils::DispatchTrustedEvent(frame->OwnerDoc(), frame, NS_LITERAL_STRING("MozDelayedModalDialog"), true, true); } } PRenderFrameParent* -TabParent::AllocPRenderFrame() +TabParent::AllocPRenderFrame(LayersBackend* aBackend, + int32_t* aMaxTextureSize, + uint64_t* aLayersId) { nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader(); - return new RenderFrameParent(frameLoader); + return new RenderFrameParent(frameLoader, + aBackend, aMaxTextureSize, aLayersId); } bool TabParent::DeallocPRenderFrame(PRenderFrameParent* aFrame) { delete aFrame; return true; }
--- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -198,17 +198,19 @@ protected: nsCOMPtr<nsIDialogParamBlock> mParams; }; InfallibleTArray<DelayedDialogData*> mDelayedDialogs; bool ShouldDelayDialogs(); 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); // IME static TabParent *mIMETabParent; nsString mIMECacheText; PRUint32 mIMESelectionAnchor; PRUint32 mIMESelectionFocus;
--- a/gfx/layers/ipc/CompositorChild.cpp +++ b/gfx/layers/ipc/CompositorChild.cpp @@ -65,17 +65,20 @@ CompositorChild::Create(Transport* aTran CompositorChild::Get() { // This is only expected to be used in child processes. MOZ_ASSERT(XRE_GetProcessType() != GeckoProcessType_Default); return sCompositor; } 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(); } bool CompositorChild::DeallocPLayers(PLayersChild* actor) { delete actor;
--- a/gfx/layers/ipc/CompositorChild.h +++ b/gfx/layers/ipc/CompositorChild.h @@ -31,17 +31,20 @@ public: * the compositor's context. */ static PCompositorChild* Create(Transport* aTransport, ProcessId aOtherProcess); 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; private: nsRefPtr<LayerManager> mLayerManager; // When we're in a child process, this is the process-global
--- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -619,30 +619,33 @@ CompositorParent::ShadowLayersUpdated(Sh mLayerManager->SetRoot(root); if (root) { SetShadowProperties(root); } ScheduleComposition(); } PLayersParent* -CompositorParent::AllocPLayers(const LayersBackend& aBackendType, +CompositorParent::AllocPLayers(const LayersBackend& aBackendHint, const uint64_t& aId, + LayersBackend* aBackend, int32_t* aMaxTextureSize) { MOZ_ASSERT(aId == 0); // mWidget doesn't belong to the compositor thread, so it should be set to // NULL before returning from this method, to avoid accessing it elsewhere. nsIntRect rect; mWidget->GetBounds(rect); mWidgetSize.width = rect.width; mWidgetSize.height = rect.height; - if (aBackendType == LayerManager::LAYERS_OPENGL) { + *aBackend = aBackendHint; + + if (aBackendHint == LayerManager::LAYERS_OPENGL) { nsRefPtr<LayerManagerOGL> layerManager; layerManager = new LayerManagerOGL(mWidget, mEGLSurfaceSize.width, mEGLSurfaceSize.height, mRenderToEGLSurface); mWidget = NULL; mLayerManager = layerManager; ShadowLayerManager* shadowManager = layerManager->AsShadowManager(); if (shadowManager) { shadowManager->SetCompositorID(mCompositorID); @@ -654,17 +657,17 @@ CompositorParent::AllocPLayers(const Lay } ShadowLayerManager* slm = layerManager->AsShadowManager(); if (!slm) { return NULL; } *aMaxTextureSize = layerManager->GetMaxTextureSize(); return new ShadowLayersParent(slm, this, 0); - } else if (aBackendType == LayerManager::LAYERS_BASIC) { + } else if (aBackendHint == LayerManager::LAYERS_BASIC) { nsRefPtr<LayerManager> layerManager = new BasicShadowLayerManager(mWidget); mWidget = NULL; mLayerManager = layerManager; ShadowLayerManager* slm = layerManager->AsShadowManager(); if (!slm) { return NULL; } *aMaxTextureSize = layerManager->GetMaxTextureSize(); @@ -763,16 +766,17 @@ public: // FIXME/bug 774388: work out what shutdown protocol we need. virtual bool RecvWillStop() MOZ_OVERRIDE { return true; } virtual bool RecvStop() MOZ_OVERRIDE { return true; } virtual bool RecvPause() MOZ_OVERRIDE { return true; } virtual bool RecvResume() MOZ_OVERRIDE { return true; } virtual PLayersParent* AllocPLayers(const LayersBackend& aBackendType, const uint64_t& aId, + LayersBackend* aBackend, int32_t* aMaxTextureSize) MOZ_OVERRIDE; virtual bool DeallocPLayers(PLayersParent* aLayers) MOZ_OVERRIDE; virtual void ShadowLayersUpdated(ShadowLayersParent* aLayerTree, bool isFirstPaint) MOZ_OVERRIDE; private: void DeferredDestroy(); @@ -841,26 +845,26 @@ CrossProcessCompositorParent::ActorDestr MessageLoop::current()->PostTask( FROM_HERE, NewRunnableMethod(this, &CrossProcessCompositorParent::DeferredDestroy)); } PLayersParent* CrossProcessCompositorParent::AllocPLayers(const LayersBackend& aBackendType, const uint64_t& aId, + LayersBackend* aBackend, int32_t* aMaxTextureSize) { MOZ_ASSERT(aId != 0); nsRefPtr<LayerManager> lm = sCurrentCompositor->GetLayerManager(); + *aBackend = lm->GetBackendType(); *aMaxTextureSize = lm->GetMaxTextureSize(); return new ShadowLayersParent(lm->AsShadowManager(), this, aId); - - return nsnull; - } +} bool CrossProcessCompositorParent::DeallocPLayers(PLayersParent* aLayers) { ShadowLayersParent* slp = static_cast<ShadowLayersParent*>(aLayers); RemoveIndirectTree(slp->GetId()); delete aLayers; return true;
--- a/gfx/layers/ipc/CompositorParent.h +++ b/gfx/layers/ipc/CompositorParent.h @@ -112,17 +112,20 @@ public: /** * A new child process has been configured to push transactions * directly to us. Transport is to its thread context. */ static PCompositorParent* 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(); virtual void SetFirstPaintViewport(const nsIntPoint& aOffset, float aZoom, const nsIntRect& aPageRect, const gfx::Rect& aCssPageRect); virtual void SetPageRect(const gfx::Rect& aCssPageRect); virtual void SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated, nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY); void SetEGLSurfaceSize(int width, int height);
--- a/gfx/layers/ipc/PCompositor.ipdl +++ b/gfx/layers/ipc/PCompositor.ipdl @@ -33,14 +33,14 @@ parent: // Clean up in preparation for own destruction. sync Stop(); // Pause/resume the compositor. These are intended to be used on mobile, when // the compositor needs to pause/resume in lockstep with the application. 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 } // mozilla
--- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -255,25 +255,16 @@ gfxPlatform::Init() #ifdef MOZ_X11 // On X11 platforms only use OMTC if firefox was initalized with thread-safe // X11 (else it would crash). useOffMainThreadCompositing = (PR_GetEnv("MOZ_USE_OMTC") != NULL); #else 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() == GeckoProcessType_Default)) { CompositorParent::StartUp(); if (Preferences::GetBool("layers.async-video.enabled",false)) { ImageBridgeChild::StartUp(); }
--- a/layout/ipc/PRenderFrame.ipdl +++ b/layout/ipc/PRenderFrame.ipdl @@ -34,21 +34,26 @@ parent: * - direct shadow tree: updates are sent to parent * - indirect: the parent holds a reference (ID) to a shadow tree * that's managed by the compositor. During composition, the * shadow tree is looked up and grafted appropriately * * |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__; }; } // namespace layout } // namespace mozilla
--- a/layout/ipc/RenderFrameChild.cpp +++ b/layout/ipc/RenderFrameChild.cpp @@ -28,18 +28,17 @@ RenderFrameChild::Destroy() // |layers| was just deleted, take care } Send__delete__(this); // WARNING: |this| is dead, hands off } PLayersChild* -RenderFrameChild::AllocPLayers(LayerManager::LayersBackend* aBackendType, - int* aMaxTextureSize, uint64_t* aId) +RenderFrameChild::AllocPLayers() { return new ShadowLayersChild(); } bool RenderFrameChild::DeallocPLayers(PLayersChild* aLayers) { delete aLayers;
--- a/layout/ipc/RenderFrameChild.h +++ b/layout/ipc/RenderFrameChild.h @@ -18,18 +18,17 @@ class RenderFrameChild : public PRenderF public: RenderFrameChild() {} virtual ~RenderFrameChild() {} void Destroy(); protected: NS_OVERRIDE - virtual PLayersChild* AllocPLayers(LayerManager::LayersBackend* aBackendType, - int* aMaxTextureSize, uint64_t* aId); + virtual PLayersChild* AllocPLayers(); NS_OVERRIDE virtual bool DeallocPLayers(PLayersChild* aLayers); }; } // namespace layout } // namespace mozilla #endif // mozilla_dom_RenderFrameChild_h
--- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -1,31 +1,32 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: sw=2 ts=8 et : */ /* This Source Code Form is subject to the terms of the Mozilla Public * 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 "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" -#include "gfx3DMatrix.h" -#include "nsFrameLoader.h" -#include "nsViewportFrame.h" -#include "nsSubDocumentFrame.h" -#include "nsIObserver.h" -#include "nsContentUtils.h" - typedef nsContentView::ViewConfig ViewConfig; using namespace mozilla::layers; namespace mozilla { namespace layout { typedef FrameMetrics::ViewID ViewID; typedef RenderFrameParent::ViewMap ViewMap; @@ -439,24 +440,47 @@ BuildBackgroundPatternFor(ContainerLayer nsIntRegion bgRgn(frameRect); bgRgn.Sub(bgRgn, localIntContentVis); bgRgn.MoveBy(-frameRect.TopLeft()); layer->SetVisibleRegion(bgRgn); aContainer->InsertAfter(layer, nsnull); } -RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader) - : mFrameLoader(aFrameLoader) +already_AddRefed<LayerManager> +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<LayerManager> 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(); } } RenderFrameParent::~RenderFrameParent() {} void RenderFrameParent::Destroy() @@ -487,44 +511,22 @@ RenderFrameParent::ContentViewScaleChang // shadow-space attributes updated. It's easiest to rebuild the view map. BuildViewMap(); } 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 <browser> 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<Layer> RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, LayerManager* aManager, const nsIntRect& aVisibleRect) { @@ -540,16 +542,35 @@ RenderFrameParent::BuildLayer(nsDisplayL // widget's layer manager changed out from under us. We need to // FIXME handle the former case somehow, probably with an API to // draw a manager's subtree. The latter is bad bad bad, but the // the NS_ABORT_IF_FALSE() above will flag it. Returning NULL // here will just cause the shadow subtree not to be rendered. return nsnull; } + uint64_t id = GetLayerTreeId(); + if (0 != id) { + MOZ_ASSERT(!GetRootLayer()); + + nsRefPtr<RefLayer> 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); } ContainerLayer* shadowRoot = GetRootLayer(); if (!shadowRoot) { mContainer = nsnull; return nsnull; @@ -603,45 +624,31 @@ RenderFrameParent::ActorDestroy(ActorDes // why==NormalShutdown, we'll definitely want to do something // better, especially as nothing guarantees another Update() from // the "next" remote layer tree. mFrameLoader->SetCurrentRemoteFrame(nsnull); } 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<LayerManager> 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<LayerManager> lm = GetFrom(mFrameLoader); + return new ShadowLayersParent(lm->AsShadowManager(), this, 0); } bool RenderFrameParent::DeallocPLayers(PLayersParent* aLayers) { delete aLayers; return true; } @@ -675,31 +682,58 @@ RenderFrameParent::BuildViewMap() if (newContentViews.empty()) { newContentViews[FrameMetrics::ROOT_SCROLL_ID] = FindViewForId(mContentViews, FrameMetrics::ROOT_SCROLL_ID); } 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 <browser> 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 { const nsTArray<PLayersParent*>& shadowParents = ManagedPLayersParent(); NS_ABORT_IF_FALSE(shadowParents.Length() <= 1, "can only support at most 1 ShadowLayersParent"); return (shadowParents.Length() == 1) ? static_cast<ShadowLayersParent*>(shadowParents[0]) : nsnull; } uint64_t RenderFrameParent::GetLayerTreeId() const { - ShadowLayersParent* shadowLayers = GetShadowLayers(); - return shadowLayers ? shadowLayers->GetId() : 0; + return mLayersId; } ContainerLayer* RenderFrameParent::GetRootLayer() const { ShadowLayersParent* shadowLayers = GetShadowLayers(); return shadowLayers ? shadowLayers->GetRoot() : nsnull; }
--- a/layout/ipc/RenderFrameParent.h +++ b/layout/ipc/RenderFrameParent.h @@ -35,17 +35,20 @@ class RenderFrameParent : public PRender typedef mozilla::layers::Layer Layer; typedef mozilla::layers::LayerManager LayerManager; typedef mozilla::layers::ShadowLayersParent ShadowLayersParent; typedef FrameMetrics::ViewID ViewID; public: typedef std::map<ViewID, nsRefPtr<nsContentView> > ViewMap; - RenderFrameParent(nsFrameLoader* aFrameLoader); + RenderFrameParent(nsFrameLoader* aFrameLoader, + LayerManager::LayersBackend* aBackendType, + int* aMaxTextureSize, + uint64_t* aId); virtual ~RenderFrameParent(); void Destroy(); /** * Helper function for getting a non-owning reference to a scrollable. * @param aId The ID of the frame. */ @@ -68,28 +71,34 @@ public: void OwnerContentChanged(nsIContent* aContent); void SetBackgroundColor(nscolor aColor) { mBackgroundColor = gfxRGBA(aColor); }; 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<nsFrameLoader> mFrameLoader; nsRefPtr<ContainerLayer> mContainer; // This contains the views for all the scrollable frames currently in the // painted region of our remote content. ViewMap mContentViews; // True after Destroy() has been called, which is triggered
--- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -33,17 +33,17 @@ class nsIRollupListener; class nsGUIEvent; class imgIContainer; class gfxASurface; class nsIContent; class ViewWrapper; namespace mozilla { namespace dom { -class PBrowserChild; +class TabChild; } namespace layers { class PLayersChild; } } /** * Callback function that processes events. @@ -354,17 +354,17 @@ struct InputContextAction { } // namespace mozilla /** * The base class for all the widgets. It provides the interface for * all basic and necessary functionality. */ class nsIWidget : public nsISupports { protected: - typedef mozilla::dom::PBrowserChild PBrowserChild; + typedef mozilla::dom::TabChild TabChild; public: typedef mozilla::layers::LayerManager LayerManager; typedef LayerManager::LayersBackend LayersBackend; typedef mozilla::layers::PLayersChild PLayersChild; typedef mozilla::widget::IMEState IMEState; typedef mozilla::widget::InputContext InputContext; typedef mozilla::widget::InputContextAction InputContextAction; @@ -1538,17 +1538,17 @@ class nsIWidget : public nsISupports { * be fed to it. Currently used in content processes. NULL is * returned if puppet widgets aren't supported in this build * config, on this platform, or for this process type. * * This function is called "Create" to match CreateInstance(). * The returned widget must still be nsIWidget::Create()d. */ static already_AddRefed<nsIWidget> - CreatePuppetWidget(PBrowserChild *aTabChild); + CreatePuppetWidget(TabChild* aTabChild); /** * Reparent this widget's native widget. * @param aNewParent the native widget of aNewParent is the new native * parent widget */ NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent) = 0;
--- a/widget/xpwidgets/PuppetWidget.cpp +++ b/widget/xpwidgets/PuppetWidget.cpp @@ -1,23 +1,26 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: sw=2 ts=8 et : */ /* This Source Code Form is subject to the terms of the Mozilla Public * 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; using namespace mozilla::hal; using namespace mozilla::layers; using namespace mozilla::widget; static void @@ -25,17 +28,17 @@ InvalidateRegion(nsIWidget* aWidget, con { nsIntRegionRectIterator it(aRegion); while(const nsIntRect* r = it.Next()) { aWidget->Invalidate(*r); } } /*static*/ already_AddRefed<nsIWidget> -nsIWidget::CreatePuppetWidget(PBrowserChild *aTabChild) +nsIWidget::CreatePuppetWidget(TabChild* aTabChild) { NS_ABORT_IF_FALSE(nsIWidget::UsePuppetWidgets(), "PuppetWidgets not allowed in this configuration"); nsCOMPtr<nsIWidget> widget = new PuppetWidget(aTabChild); return widget.forget(); } @@ -58,17 +61,17 @@ MightNeedIMEFocus(const nsWidgetInitData // Arbitrary, fungible. 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) { MOZ_COUNT_CTOR(PuppetWidget); } PuppetWidget::~PuppetWidget() { @@ -498,17 +501,18 @@ PuppetWidget::DispatchPaintEvent() if (LayerManager::LAYERS_D3D10 == mLayerManager->GetBackendType()) { DispatchEvent(&event, status); } else { nsRefPtr<gfxContext> ctx = new gfxContext(mSurface); ctx->Rectangle(gfxRect(0,0,0,0)); ctx->Clip(); AutoLayerManagerSetup setupLayerManager(this, ctx, BasicLayerManager::BUFFER_NONE); - DispatchEvent(&event, status); + DispatchEvent(&event, status); + mTabChild->NotifyPainted(); } } nsPaintEvent didPaintEvent(true, NS_DID_PAINT, this); DispatchEvent(&didPaintEvent, status); return NS_OK; }
--- a/widget/xpwidgets/PuppetWidget.h +++ b/widget/xpwidgets/PuppetWidget.h @@ -20,27 +20,33 @@ #include "nsIScreenManager.h" #include "nsThreadUtils.h" #include "nsWeakReference.h" #include "mozilla/Attributes.h" 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 NS_IMETHOD Create(nsIWidget* aParent, nsNativeWidget aNativeParent, const nsIntRect& aRect, EVENT_CALLBACK aHandleEventFunction, @@ -171,22 +177,22 @@ private: NS_DECL_NSIRUNNABLE PaintTask(PuppetWidget* widget) : mWidget(widget) {} void Revoke() { mWidget = nsnull; } private: PuppetWidget* mWidget; }; // 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<PuppetWidget> mChild; nsIntRegion mDirtyRegion; nsRevocableEventPtr<PaintTask> mPaintTask; bool mEnabled; bool mVisible; // XXX/cjones: keeping this around until we teach LayerManager to do
--- a/widget/xpwidgets/nsBaseWidget.cpp +++ b/widget/xpwidgets/nsBaseWidget.cpp @@ -873,34 +873,31 @@ void nsBaseWidget::CreateCompositor() LayerManager* lm = CreateBasicLayerManager(); MessageLoop *childMessageLoop = CompositorParent::CompositorLoop(); mCompositorChild = new CompositorChild(lm); AsyncChannel *parentChannel = mCompositorParent->GetIPCChannel(); AsyncChannel::Side childSide = mozilla::ipc::AsyncChannel::Child; 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(); if (!lf) { delete lm; mCompositorChild = nsnull; 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; } else { // We don't currently want to support not having a LayersChild NS_RUNTIMEABORT("failed to construct LayersChild"); delete lm; mCompositorChild = nsnull;