Bug 1397426 - Make TabParent's assume they're rendering layers by default on construction. r=billm
authorMike Conley <mconley@mozilla.com>
Mon, 20 Nov 2017 11:41:11 -0500
changeset 446483 b9b2895b11a32f3da0f4c8fe364bf3bdfc7defb6
parent 446482 53bb2bc2b67673572dafc3093280fa72973b3d32
child 446484 78073667ddc6e932408f49076b74c448a74bb710
push id8527
push userCallek@gmail.com
push dateThu, 11 Jan 2018 21:05:50 +0000
treeherdermozilla-beta@95342d212a7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs1397426
milestone59.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
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
browser/base/content/tabbrowser.xml
dom/ipc/TabChild.cpp
dom/ipc/TabParent.cpp
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -4433,18 +4433,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);
@@ -4856,16 +4855,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.