Bug 1397426 - Make TabParent's assume they're rendering layers by default on construction. r=billm
This assumption also mirrors how non-remote browsers have their docShells active by default.
In order to do this, I also have to increase the initial epoch's for the TabParent and TabChild,
as if a RenderLayers has been called. Originally, since the epochs initted at 0, and the epochs
stored by the [Layer|WebRender]TransactionParent were also initted at 0, we'd hit this branch:
https://searchfox.org/mozilla-central/rev/c633ffa4c4611f202ca11270dcddb7b29edddff8/gfx/layers/ipc/LayerTransactionParent.cpp#703
and then we'd never alert the TabParent about the layer upload.
MozReview-Commit-ID: 6PP1eCnisYK
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -4452,18 +4452,17 @@
window.addEventListener("TabRemotenessChange", this);
window.addEventListener("sizemodechange", this);
window.addEventListener("occlusionstatechange", this);
window.addEventListener("SwapDocShells", this, true);
window.addEventListener("EndSwapDocShells", this, true);
let tab = this.requestedTab;
let browser = tab.linkedBrowser;
- let tabIsLoaded = !browser.isRemoteBrowser ||
- browser.frameLoader.tabParent.hasPresented;
+ let tabIsLoaded = browser.renderingLayers;
if (!this.minimizedOrFullyOccluded) {
this.log("Initial tab is loaded?: " + tabIsLoaded);
this.setTabState(tab, tabIsLoaded ? this.STATE_LOADED
: this.STATE_LOADING);
}
for (let ppBrowser of this.tabbrowser._printPreviewBrowsers) {
let ppTab = this.tabbrowser.getTabForBrowser(ppBrowser);
@@ -4867,16 +4866,23 @@
this.loadTimer = null;
this.loadingTab = null;
this.postActions();
},
// Fires when the layers become available for a tab.
onLayersReady(browser) {
let tab = this.tabbrowser.getTabForBrowser(browser);
+ if (!tab) {
+ // We probably got a layer update from a tab that got before
+ // the switcher was created, or for browser that's not being
+ // tracked by the async tab switcher (like the preloaded about:newtab).
+ return;
+ }
+
this.logState(`onLayersReady(${tab._tPos}, ${browser.isRemoteBrowser})`);
this.assert(this.getTabState(tab) == this.STATE_LOADING ||
this.getTabState(tab) == this.STATE_LOADED);
this.setTabState(tab, this.STATE_LOADED);
if (this.loadingTab === tab) {
this.clearTimer(this.loadTimer);
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -423,17 +423,17 @@ TabChild::TabChild(nsIContentChild* aMan
, mUniqueId(aTabId)
, mIsTransparent(false)
, mIPCOpen(false)
, mParentIsActive(false)
, mDidSetRealShowInfo(false)
, mDidLoadURLInit(false)
, mAwaitingLA(false)
, mSkipKeyPress(false)
- , mLayerObserverEpoch(0)
+ , mLayerObserverEpoch(1)
#if defined(XP_WIN) && defined(ACCESSIBILITY)
, mNativeWindowHandle(0)
#endif
#if defined(ACCESSIBILITY)
, mTopLevelDocAccessibleChild(nullptr)
#endif
, mPendingDocShellIsActive(false)
, mPendingDocShellReceivedMessage(false)
@@ -2932,16 +2932,19 @@ TabChild::InitRenderingState(const Textu
}
if (success) {
MOZ_ASSERT(mLayersConnected == Some(true));
// Succeeded to create "remote" layer manager
ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
gfx::VRManagerChild::IdentifyTextureHost(mTextureFactoryIdentifier);
InitAPZState();
+ RefPtr<LayerManager> lm = mPuppetWidget->GetLayerManager();
+ MOZ_ASSERT(lm);
+ lm->SetLayerObserverEpoch(mLayerObserverEpoch);
} else {
NS_WARNING("Fallback to BasicLayerManager");
mLayersConnected = Some(false);
}
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
@@ -3045,17 +3048,24 @@ TabChild::MakeVisible()
void
TabChild::MakeHidden()
{
if (!IsVisible()) {
return;
}
- ClearCachedResources();
+ // Due to the nested event loop in ContentChild::ProvideWindowCommon,
+ // it's possible to be told to become hidden before we're finished
+ // setting up a layer manager. We should skip clearing cached layers
+ // in that case, since doing so might accidentally put is into
+ // BasicLayers mode.
+ if (mPuppetWidget && mPuppetWidget->HasLayerManager()) {
+ ClearCachedResources();
+ }
// Hide all plugins in this tab.
if (nsCOMPtr<nsIPresShell> shell = GetPresShell()) {
if (nsPresContext* presContext = shell->GetPresContext()) {
nsRootPresContext* rootPresContext = presContext->GetRootPresContext();
nsIFrame* rootFrame = shell->FrameConstructor()->GetRootFrame();
rootPresContext->ComputePluginGeometryUpdates(rootFrame, nullptr, nullptr);
rootPresContext->ApplyPluginGeometryUpdates();
@@ -3550,17 +3560,17 @@ TabChild::GetOuterRect()
LayoutDeviceIntRect outerRect =
RoundedToInt(mUnscaledOuterRect * mPuppetWidget->GetDefaultScale());
return ViewAs<ScreenPixel>(outerRect, PixelCastJustification::LayoutDeviceIsScreenForTabDims);
}
void
TabChild::ForcePaint(uint64_t aLayerObserverEpoch)
{
- if (!IPCOpen()) {
+ if (!IPCOpen() || !mPuppetWidget || !mPuppetWidget->HasLayerManager()) {
// Don't bother doing anything now. Better to wait until we receive the
// message on the PContent channel.
return;
}
nsAutoScriptBlocker scriptBlocker;
RecvRenderLayers(true, aLayerObserverEpoch);
}
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -166,19 +166,19 @@ TabParent::TabParent(nsIContentParent* a
, mTabId(aTabId)
, mCreatingWindow(false)
, mCursor(eCursorInvalid)
, mTabSetsCursor(false)
, mHasContentOpener(false)
#ifdef DEBUG
, mActiveSupressDisplayportCount(0)
#endif
- , mLayerTreeEpoch(0)
+ , mLayerTreeEpoch(1)
, mPreserveLayers(false)
- , mRenderLayers(false)
+ , mRenderLayers(true)
, mHasLayers(false)
, mHasPresented(false)
, mHasBeforeUnload(false)
, mIsMouseEnterIntoWidgetEventSuppressed(false)
{
MOZ_ASSERT(aManager);
// When the input event queue is disabled, we don't need to handle the case
// that some input events are dispatched before PBrowserConstructor.