From fc7795425731017765af898ef9ef1b072bcecf47 Mon Sep 17 00:00:00 2001 From: Doug Thayer Date: Mon, 14 May 2018 23:45:00 -0700 Subject: [PATCH] Bug 1176019 - Force a paint when switching to a loaded tab r=mconley This is fairly straightforward, other than the fact that the nomenclature gets a bit awkward with the aForce parameter on the ForcePaint methods. I'm not sure which direction to go with this - "aForce" seems a fairly intuitive name for what we want, and I'm kind of inclined to say the existing ForcePaint mechanic should be renamed to something like PaintWithInterrupt, or PaintWithPriority. MozReview-Commit-ID: Bj9DROug1pC --HG-- extra : rebase_source : a3d91fec940d83325d36bafb13fe892e9c9530e8 --- browser/modules/AsyncTabSwitcher.jsm | 3 + dom/interfaces/base/nsITabParent.idl | 7 ++ dom/ipc/ContentParent.cpp | 9 +- dom/ipc/ContentParent.h | 2 +- dom/ipc/PBrowser.ipdl | 10 +- dom/ipc/PProcessHangMonitor.ipdl | 2 +- dom/ipc/ProcessHangMonitor.cpp | 119 ++++++++++++--------- dom/ipc/ProcessHangMonitor.h | 11 +- dom/ipc/TabChild.cpp | 23 ++-- dom/ipc/TabChild.h | 5 +- dom/ipc/TabParent.cpp | 43 +++++--- dom/ipc/TabParent.h | 4 +- toolkit/content/widgets/remote-browser.xml | 11 ++ 13 files changed, 159 insertions(+), 90 deletions(-) diff --git a/browser/modules/AsyncTabSwitcher.jsm b/browser/modules/AsyncTabSwitcher.jsm index d7b7b2a201ac..37c93b77e52c 100644 --- a/browser/modules/AsyncTabSwitcher.jsm +++ b/browser/modules/AsyncTabSwitcher.jsm @@ -979,6 +979,9 @@ class AsyncTabSwitcher { this.requestedTab = tab; if (tabState == this.STATE_LOADED) { this.maybeVisibleTabs.clear(); + if (tab.linkedBrowser.isRemoteBrowser) { + tab.linkedBrowser.forceRepaint(); + } } tab.linkedBrowser.setAttribute("primary", "true"); diff --git a/dom/interfaces/base/nsITabParent.idl b/dom/interfaces/base/nsITabParent.idl index c58944692545..8fe49e0ad9cd 100644 --- a/dom/interfaces/base/nsITabParent.idl +++ b/dom/interfaces/base/nsITabParent.idl @@ -35,6 +35,13 @@ interface nsITabParent : nsISupports */ readonly attribute boolean hasLayers; + /** + * Sends a message to the child ensuring that they paint as early as + * possible. This will send the message to paint even if renderLayers + * is already true. + */ + void forceRepaint(); + /** * As an optimisation, setting the docshell's active state to * inactive also triggers a layer invalidation to free up some diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index f9129550fc4a..cf065915dc23 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -5318,12 +5318,17 @@ ContentParent::SendGetFilesResponseAndForget(const nsID& aUUID, } void -ContentParent::ForceTabPaint(TabParent* aTabParent, uint64_t aLayerObserverEpoch) +ContentParent::PaintTabWhileInterruptingJS(TabParent* aTabParent, + bool aForceRepaint, + uint64_t aLayerObserverEpoch) { if (!mHangMonitorActor) { return; } - ProcessHangMonitor::ForcePaint(mHangMonitorActor, aTabParent, aLayerObserverEpoch); + ProcessHangMonitor::PaintWhileInterruptingJS(mHangMonitorActor, + aTabParent, + aForceRepaint, + aLayerObserverEpoch); } void diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index 2ec8407f4b73..eefb372175ab 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -639,7 +639,7 @@ public: nsTArray* aResults) override; // Use the PHangMonitor channel to ask the child to repaint a tab. - void ForceTabPaint(TabParent* aTabParent, uint64_t aLayerObserverEpoch); + void PaintTabWhileInterruptingJS(TabParent* aTabParent, bool aForceRepaint, uint64_t aLayerObserverEpoch); // This function is called when we are about to load a document from an // HTTP(S), FTP or wyciwyg channel for a content process. It is a useful diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index bcc88eaf88ed..84a832dc21a8 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -560,7 +560,7 @@ parent: /** * Child informs the parent that the layer tree is already available. */ - async ForcePaintNoOp(uint64_t aLayerObserverEpoch); + async PaintWhileInterruptingJSNoOp(uint64_t aLayerObserverEpoch); /** * Sent by the child to the parent to inform it that an update to the @@ -767,11 +767,15 @@ child: * @param aEnabled * True if the child should render and upload layers, false if the * child should clear layers. + * @param aForceRepaint + * True if the child should force a paint even if it's already + * visible. * @param aLayerObserverEpoch * The layer observer epoch for this activation. This message should be - * ignored if this epoch has already been observed (via ForcePaint). + * ignored if this epoch has already been observed (via + * PaintWhileInterruptingJS). */ - async RenderLayers(bool aEnabled, uint64_t aLayerObserverEpoch); + async RenderLayers(bool aEnabled, bool aForceRepaint, uint64_t aLayerObserverEpoch); /** * Notify the child that it shouldn't paint the offscreen displayport. diff --git a/dom/ipc/PProcessHangMonitor.ipdl b/dom/ipc/PProcessHangMonitor.ipdl index 26f4535448cd..e2a454aaf0a3 100644 --- a/dom/ipc/PProcessHangMonitor.ipdl +++ b/dom/ipc/PProcessHangMonitor.ipdl @@ -41,7 +41,7 @@ child: async BeginStartingDebugger(); async EndStartingDebugger(); - async ForcePaint(TabId tabId, uint64_t aLayerObserverEpoch); + async PaintWhileInterruptingJS(TabId tabId, bool forceRepaint, uint64_t aLayerObserverEpoch); }; } // namespace mozilla diff --git a/dom/ipc/ProcessHangMonitor.cpp b/dom/ipc/ProcessHangMonitor.cpp index 9069b6cb0dfa..d7febaad1c8f 100644 --- a/dom/ipc/ProcessHangMonitor.cpp +++ b/dom/ipc/ProcessHangMonitor.cpp @@ -96,19 +96,21 @@ class HangMonitorChild void ClearHang(); void ClearHangAsync(); - void ClearForcePaint(uint64_t aLayerObserverEpoch); + void ClearPaintWhileInterruptingJS(uint64_t aLayerObserverEpoch); - // MaybeStartForcePaint will notify the background hang monitor of activity - // if this is the first time calling it since ClearForcePaint. It should be + // MaybeStartPaintWhileInterruptingJS will notify the background hang monitor of activity + // if this is the first time calling it since ClearPaintWhileInterruptingJS. It should be // callable from any thread, but you must be holding mMonitor if using it off - // the main thread, since it could race with ClearForcePaint. - void MaybeStartForcePaint(); + // the main thread, since it could race with ClearPaintWhileInterruptingJS. + void MaybeStartPaintWhileInterruptingJS(); mozilla::ipc::IPCResult RecvTerminateScript(const bool& aTerminateGlobal) override; mozilla::ipc::IPCResult RecvBeginStartingDebugger() override; mozilla::ipc::IPCResult RecvEndStartingDebugger() override; - mozilla::ipc::IPCResult RecvForcePaint(const TabId& aTabId, const uint64_t& aLayerObserverEpoch) override; + mozilla::ipc::IPCResult RecvPaintWhileInterruptingJS(const TabId& aTabId, + const bool& aForceRepaint, + const uint64_t& aLayerObserverEpoch) override; void ActorDestroy(ActorDestroyReason aWhy) override; @@ -127,7 +129,7 @@ class HangMonitorChild void ShutdownOnThread(); static Atomic sInstance; - UniquePtr mForcePaintMonitor; + UniquePtr mPaintWhileInterruptingJSMonitor; const RefPtr mHangMonitor; Monitor mMonitor; @@ -140,9 +142,10 @@ class HangMonitorChild bool mTerminateGlobal; bool mStartDebugger; bool mFinishedStartingDebugger; - bool mForcePaint; - TabId mForcePaintTab; - MOZ_INIT_OUTSIDE_CTOR uint64_t mForcePaintEpoch; + bool mPaintWhileInterruptingJS; + bool mPaintWhileInterruptingJSForce; + TabId mPaintWhileInterruptingJSTab; + MOZ_INIT_OUTSIDE_CTOR uint64_t mPaintWhileInterruptingJSEpoch; JSContext* mContext; bool mShutdownDone; @@ -227,7 +230,9 @@ public: void Shutdown(); - void ForcePaint(dom::TabParent* aTabParent, uint64_t aLayerObserverEpoch); + void PaintWhileInterruptingJS(dom::TabParent* aTabParent, + bool aForceRepaint, + uint64_t aLayerObserverEpoch); void TerminateScript(bool aTerminateGlobal); void BeginStartingDebugger(); @@ -258,7 +263,7 @@ private: void ClearHangNotification(); - void ForcePaintOnThread(TabId aTabId, uint64_t aLayerObserverEpoch); + void PaintWhileInterruptingJSOnThread(TabId aTabId, bool aForceRepaint, uint64_t aLayerObserverEpoch); void ShutdownOnThread(); @@ -280,10 +285,10 @@ private: Mutex mBrowserCrashDumpHashLock; mozilla::ipc::TaskFactory mMainThreadTaskFactory; - static bool sShouldForcePaint; + static bool sShouldPaintWhileInterruptingJS; }; -bool HangMonitorParent::sShouldForcePaint = true; +bool HangMonitorParent::sShouldPaintWhileInterruptingJS = true; } // namespace @@ -297,13 +302,14 @@ HangMonitorChild::HangMonitorChild(ProcessHangMonitor* aMonitor) mTerminateGlobal(false), mStartDebugger(false), mFinishedStartingDebugger(false), - mForcePaint(false), + mPaintWhileInterruptingJS(false), + mPaintWhileInterruptingJSForce(false), mShutdownDone(false), mIPCOpen(true) { MOZ_RELEASE_ASSERT(NS_IsMainThread()); mContext = danger::GetJSContext(); - mForcePaintMonitor = + mPaintWhileInterruptingJSMonitor = MakeUnique("Gecko_Child_ForcePaint", 128, /* ms timeout for microhangs */ 1024, /* ms timeout for permahangs */ @@ -314,7 +320,7 @@ HangMonitorChild::~HangMonitorChild() { MOZ_RELEASE_ASSERT(NS_IsMainThread()); MOZ_ASSERT(sInstance == this); - mForcePaintMonitor = nullptr; + mPaintWhileInterruptingJSMonitor = nullptr; sInstance = nullptr; } @@ -323,24 +329,27 @@ HangMonitorChild::InterruptCallback() { MOZ_RELEASE_ASSERT(NS_IsMainThread()); - bool forcePaint; - TabId forcePaintTab; - uint64_t forcePaintEpoch; + bool paintWhileInterruptingJS; + bool paintWhileInterruptingJSForce; + TabId paintWhileInterruptingJSTab; + uint64_t paintWhileInterruptingJSEpoch; { MonitorAutoLock lock(mMonitor); - forcePaint = mForcePaint; - forcePaintTab = mForcePaintTab; - forcePaintEpoch = mForcePaintEpoch; + paintWhileInterruptingJS = mPaintWhileInterruptingJS; + paintWhileInterruptingJSForce = mPaintWhileInterruptingJSForce; + paintWhileInterruptingJSTab = mPaintWhileInterruptingJSTab; + paintWhileInterruptingJSEpoch = mPaintWhileInterruptingJSEpoch; - mForcePaint = false; + mPaintWhileInterruptingJS = false; } - if (forcePaint) { - RefPtr tabChild = TabChild::FindTabChild(forcePaintTab); + if (paintWhileInterruptingJS) { + RefPtr tabChild = TabChild::FindTabChild(paintWhileInterruptingJSTab); if (tabChild) { js::AutoAssertNoContentJS nojs(mContext); - tabChild->ForcePaint(forcePaintEpoch); + tabChild->PaintWhileInterruptingJS(paintWhileInterruptingJSEpoch, + paintWhileInterruptingJSForce); } } } @@ -415,16 +424,19 @@ HangMonitorChild::RecvEndStartingDebugger() } mozilla::ipc::IPCResult -HangMonitorChild::RecvForcePaint(const TabId& aTabId, const uint64_t& aLayerObserverEpoch) +HangMonitorChild::RecvPaintWhileInterruptingJS(const TabId& aTabId, + const bool& aForceRepaint, + const uint64_t& aLayerObserverEpoch) { MOZ_RELEASE_ASSERT(IsOnThread()); { MonitorAutoLock lock(mMonitor); - MaybeStartForcePaint(); - mForcePaint = true; - mForcePaintTab = aTabId; - mForcePaintEpoch = aLayerObserverEpoch; + MaybeStartPaintWhileInterruptingJS(); + mPaintWhileInterruptingJS = true; + mPaintWhileInterruptingJSForce = aForceRepaint; + mPaintWhileInterruptingJSTab = aTabId; + mPaintWhileInterruptingJSEpoch = aLayerObserverEpoch; } JS_RequestInterruptCallback(mContext); @@ -433,7 +445,7 @@ HangMonitorChild::RecvForcePaint(const TabId& aTabId, const uint64_t& aLayerObse } void -HangMonitorChild::MaybeStartForcePaint() +HangMonitorChild::MaybeStartPaintWhileInterruptingJS() { // See Bug 1449662. The body of this function other than assertions // has been temporarily removed to diagnose a tab switch spinner @@ -444,7 +456,7 @@ HangMonitorChild::MaybeStartForcePaint() } void -HangMonitorChild::ClearForcePaint(uint64_t aLayerObserverEpoch) +HangMonitorChild::ClearPaintWhileInterruptingJS(uint64_t aLayerObserverEpoch) { // See Bug 1449662. The body of this function other than assertions // has been temporarily removed to diagnose a tab switch spinner @@ -609,7 +621,7 @@ HangMonitorParent::HangMonitorParent(ProcessHangMonitor* aMonitor) static bool sInited = false; if (!sInited) { sInited = true; - Preferences::AddBoolVarCache(&sShouldForcePaint, + Preferences::AddBoolVarCache(&sShouldPaintWhileInterruptingJS, "browser.tabs.remote.force-paint", true); } } @@ -665,27 +677,33 @@ HangMonitorParent::ShutdownOnThread() } void -HangMonitorParent::ForcePaint(dom::TabParent* aTab, uint64_t aLayerObserverEpoch) +HangMonitorParent::PaintWhileInterruptingJS(dom::TabParent* aTab, + bool aForceRepaint, + uint64_t aLayerObserverEpoch) { MOZ_RELEASE_ASSERT(NS_IsMainThread()); - if (sShouldForcePaint) { + if (sShouldPaintWhileInterruptingJS) { TabId id = aTab->GetTabId(); - Dispatch(NewNonOwningRunnableMethod( - "HangMonitorParent::ForcePaintOnThread", + Dispatch(NewNonOwningRunnableMethod( + "HangMonitorParent::PaintWhileInterruptingJSOnThread", this, - &HangMonitorParent::ForcePaintOnThread, + &HangMonitorParent::PaintWhileInterruptingJSOnThread, id, + aForceRepaint, aLayerObserverEpoch)); } } void -HangMonitorParent::ForcePaintOnThread(TabId aTabId, uint64_t aLayerObserverEpoch) +HangMonitorParent::PaintWhileInterruptingJSOnThread(TabId aTabId, + bool aForceRepaint, + uint64_t aLayerObserverEpoch) { MOZ_RELEASE_ASSERT(IsOnThread()); if (mIPCOpen) { - Unused << SendForcePaint(aTabId, aLayerObserverEpoch); + Unused << SendPaintWhileInterruptingJS(aTabId, aForceRepaint, + aLayerObserverEpoch); } } @@ -1357,33 +1375,34 @@ ProcessHangMonitor::ClearHang() } /* static */ void -ProcessHangMonitor::ForcePaint(PProcessHangMonitorParent* aParent, - dom::TabParent* aTabParent, - uint64_t aLayerObserverEpoch) +ProcessHangMonitor::PaintWhileInterruptingJS(PProcessHangMonitorParent* aParent, + dom::TabParent* aTabParent, + bool aForceRepaint, + uint64_t aLayerObserverEpoch) { MOZ_RELEASE_ASSERT(NS_IsMainThread()); auto parent = static_cast(aParent); - parent->ForcePaint(aTabParent, aLayerObserverEpoch); + parent->PaintWhileInterruptingJS(aTabParent, aForceRepaint, aLayerObserverEpoch); } /* static */ void -ProcessHangMonitor::ClearForcePaint(uint64_t aLayerObserverEpoch) +ProcessHangMonitor::ClearPaintWhileInterruptingJS(uint64_t aLayerObserverEpoch) { MOZ_RELEASE_ASSERT(NS_IsMainThread()); MOZ_RELEASE_ASSERT(XRE_IsContentProcess()); if (HangMonitorChild* child = HangMonitorChild::Get()) { - child->ClearForcePaint(aLayerObserverEpoch); + child->ClearPaintWhileInterruptingJS(aLayerObserverEpoch); } } /* static */ void -ProcessHangMonitor::MaybeStartForcePaint() +ProcessHangMonitor::MaybeStartPaintWhileInterruptingJS() { MOZ_RELEASE_ASSERT(NS_IsMainThread()); MOZ_RELEASE_ASSERT(XRE_IsContentProcess()); if (HangMonitorChild* child = HangMonitorChild::Get()) { - child->MaybeStartForcePaint(); + child->MaybeStartPaintWhileInterruptingJS(); } } diff --git a/dom/ipc/ProcessHangMonitor.h b/dom/ipc/ProcessHangMonitor.h index e595fe87ccd0..d4903e414592 100644 --- a/dom/ipc/ProcessHangMonitor.h +++ b/dom/ipc/ProcessHangMonitor.h @@ -45,11 +45,12 @@ class ProcessHangMonitor final static void ClearHang(); - static void ForcePaint(PProcessHangMonitorParent* aParent, - dom::TabParent* aTab, - uint64_t aLayerObserverEpoch); - static void ClearForcePaint(uint64_t aLayerObserverEpoch); - static void MaybeStartForcePaint(); + static void PaintWhileInterruptingJS(PProcessHangMonitorParent* aParent, + dom::TabParent* aTab, + bool aForceRepaint, + uint64_t aLayerObserverEpoch); + static void ClearPaintWhileInterruptingJS(uint64_t aLayerObserverEpoch); + static void MaybeStartPaintWhileInterruptingJS(); enum SlowScriptAction { Continue, diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index e5b772013f41..a70a1e79c6e2 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -2536,7 +2536,9 @@ TabChild::RemovePendingDocShellBlocker() } if (!mPendingDocShellBlockers && mPendingRenderLayersReceivedMessage) { mPendingRenderLayersReceivedMessage = false; - RecvRenderLayers(mPendingRenderLayers, mPendingLayerObserverEpoch); + RecvRenderLayers(mPendingRenderLayers, + false /* aForceRepaint */, + mPendingLayerObserverEpoch); } } @@ -2567,7 +2569,7 @@ TabChild::RecvSetDocShellIsActive(const bool& aIsActive) } mozilla::ipc::IPCResult -TabChild::RecvRenderLayers(const bool& aEnabled, const uint64_t& aLayerObserverEpoch) +TabChild::RecvRenderLayers(const bool& aEnabled, const bool& aForceRepaint, const uint64_t& aLayerObserverEpoch) { if (mPendingDocShellBlockers > 0) { mPendingRenderLayersReceivedMessage = true; @@ -2585,19 +2587,19 @@ TabChild::RecvRenderLayers(const bool& aEnabled, const uint64_t& aLayerObserverE } mLayerObserverEpoch = aLayerObserverEpoch; - auto clearForcePaint = MakeScopeExit([&] { + auto clearPaintWhileInterruptingJS = MakeScopeExit([&] { // We might force a paint, or we might already have painted and this is a // no-op. In either case, once we exit this scope, we need to alert the // ProcessHangMonitor that we've finished responding to what might have // been a request to force paint. This is so that the BackgroundHangMonitor // for force painting can be made to wait again. if (aEnabled) { - ProcessHangMonitor::ClearForcePaint(mLayerObserverEpoch); + ProcessHangMonitor::ClearPaintWhileInterruptingJS(mLayerObserverEpoch); } }); if (aEnabled) { - ProcessHangMonitor::MaybeStartForcePaint(); + ProcessHangMonitor::MaybeStartPaintWhileInterruptingJS(); } if (mCompositorOptions) { @@ -2612,12 +2614,12 @@ TabChild::RecvRenderLayers(const bool& aEnabled, const uint64_t& aLayerObserverE } if (aEnabled) { - if (IsVisible()) { + if (!aForceRepaint && IsVisible()) { // This request is a no-op. In this case, we still want a MozLayerTreeReady // notification to fire in the parent (so that it knows that the child has - // updated its epoch). ForcePaintNoOp does that. + // updated its epoch). PaintWhileInterruptingJSNoOp does that. if (IPCOpen()) { - Unused << SendForcePaintNoOp(mLayerObserverEpoch); + Unused << SendPaintWhileInterruptingJSNoOp(mLayerObserverEpoch); return IPC_OK(); } } @@ -3446,7 +3448,8 @@ TabChild::GetOuterRect() } void -TabChild::ForcePaint(uint64_t aLayerObserverEpoch) +TabChild::PaintWhileInterruptingJS(uint64_t aLayerObserverEpoch, + bool aForceRepaint) { if (!IPCOpen() || !mPuppetWidget || !mPuppetWidget->HasLayerManager()) { // Don't bother doing anything now. Better to wait until we receive the @@ -3455,7 +3458,7 @@ TabChild::ForcePaint(uint64_t aLayerObserverEpoch) } nsAutoScriptBlocker scriptBlocker; - RecvRenderLayers(true, aLayerObserverEpoch); + RecvRenderLayers(true /* aEnabled */, aForceRepaint, aLayerObserverEpoch); } void diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index f2a4e481c49d..e46304464c81 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -655,7 +655,8 @@ public: const uint32_t& aFlags); // Request that the docshell be marked as active. - void ForcePaint(uint64_t aLayerObserverEpoch); + void PaintWhileInterruptingJS(uint64_t aLayerObserverEpoch, + bool aForceRepaint); #if defined(XP_WIN) && defined(ACCESSIBILITY) uintptr_t GetNativeWindowHandle() const { return mNativeWindowHandle; } @@ -728,7 +729,7 @@ protected: virtual mozilla::ipc::IPCResult RecvSetDocShellIsActive(const bool& aIsActive) override; - virtual mozilla::ipc::IPCResult RecvRenderLayers(const bool& aEnabled, const uint64_t& aLayerObserverEpoch) override; + virtual mozilla::ipc::IPCResult RecvRenderLayers(const bool& aEnabled, const bool& aForce, const uint64_t& aLayerObserverEpoch) override; virtual mozilla::ipc::IPCResult RecvNavigateByKey(const bool& aForward, const bool& aForDocumentNavigation) override; diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index a4a87628038b..8c1b2caadfb5 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -2931,19 +2931,7 @@ TabParent::SetRenderLayers(bool aEnabled) mRenderLayers = aEnabled; - // Increment the epoch so that layer tree updates from previous - // RenderLayers requests are ignored. - mLayerTreeEpoch++; - - Unused << SendRenderLayers(aEnabled, mLayerTreeEpoch); - - // Ask the child to repaint using the PHangMonitor channel/thread (which may - // be less congested). - if (aEnabled) { - ContentParent* cp = Manager()->AsContentParent(); - cp->ForceTabPaint(this, mLayerTreeEpoch); - } - + SetRenderLayersInternal(aEnabled, false /* aForceRepaint */); return NS_OK; } @@ -2961,6 +2949,31 @@ TabParent::GetHasLayers(bool* aResult) return NS_OK; } +NS_IMETHODIMP +TabParent::ForceRepaint() +{ + SetRenderLayersInternal(true /* aEnabled */, + true /* aForceRepaint */); + return NS_OK; +} + +void +TabParent::SetRenderLayersInternal(bool aEnabled, bool aForceRepaint) +{ + // Increment the epoch so that layer tree updates from previous + // RenderLayers requests are ignored. + mLayerTreeEpoch++; + + Unused << SendRenderLayers(aEnabled, aForceRepaint, mLayerTreeEpoch); + + // Ask the child to repaint using the PHangMonitor channel/thread (which may + // be less congested). + if (aEnabled) { + ContentParent* cp = Manager()->AsContentParent(); + cp->PaintTabWhileInterruptingJS(this, aForceRepaint, mLayerTreeEpoch); + } +} + NS_IMETHODIMP TabParent::PreserveLayers(bool aPreserveLayers) { @@ -3079,9 +3092,9 @@ TabParent::LayerTreeUpdate(uint64_t aEpoch, bool aActive) } mozilla::ipc::IPCResult -TabParent::RecvForcePaintNoOp(const uint64_t& aLayerObserverEpoch) +TabParent::RecvPaintWhileInterruptingJSNoOp(const uint64_t& aLayerObserverEpoch) { - // We sent a ForcePaint message when layers were already visible. In this + // We sent a PaintWhileInterruptingJS message when layers were already visible. In this // case, we should act as if an update occurred even though we already have // the layers. LayerTreeUpdate(aLayerObserverEpoch, true); diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 762ebbf637ae..ce7f2b9edc94 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -625,7 +625,7 @@ protected: virtual mozilla::ipc::IPCResult RecvRemoteIsReadyToHandleInputEvents() override; - virtual mozilla::ipc::IPCResult RecvForcePaintNoOp(const uint64_t& aLayerObserverEpoch) override; + virtual mozilla::ipc::IPCResult RecvPaintWhileInterruptingJSNoOp(const uint64_t& aLayerObserverEpoch) override; virtual mozilla::ipc::IPCResult RecvSetDimensions(const uint32_t& aFlags, const int32_t& aX, const int32_t& aY, @@ -651,6 +651,8 @@ protected: private: void DestroyInternal(); + void SetRenderLayersInternal(bool aEnabled, bool aForceRepaint); + already_AddRefed GetFrameLoader(bool aUseCachedFrameLoaderAfterDestroy = false) const; diff --git a/toolkit/content/widgets/remote-browser.xml b/toolkit/content/widgets/remote-browser.xml index 9138e129a87a..2052fd5227f9 100644 --- a/toolkit/content/widgets/remote-browser.xml +++ b/toolkit/content/widgets/remote-browser.xml @@ -266,6 +266,17 @@ + + + + + +