Bug 1378203 - Add nsITabParent.canPresent. r?billm draft
authorMike Conley <mconley@mozilla.com>
Fri, 25 Aug 2017 14:31:34 -0700
changeset 653366 beb5417f807758eb9b21f260cc164cf1f9c98bac
parent 653365 03d7b6dd65b93afaa6981269f69e9f7cd34224bc
child 653367 3ff002dac721366fc66e2150e14f3fc18a3cca88
push id76311
push userbmo:mconley@mozilla.com
push dateFri, 25 Aug 2017 21:46:47 +0000
reviewersbillm
bugs1378203
milestone57.0a1
Bug 1378203 - Add nsITabParent.canPresent. r?billm This read-only property returns true when rendering has been successfully initialized in the TabChild. MozReview-Commit-ID: EgOohWURv03
dom/interfaces/base/nsITabParent.idl
dom/ipc/PBrowser.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
--- a/dom/interfaces/base/nsITabParent.idl
+++ b/dom/interfaces/base/nsITabParent.idl
@@ -55,16 +55,22 @@ interface nsITabParent : nsISupports
    * If aForDocumentNavigation is false, navigate by element.
    *
    * If aForward is true, navigate to the first focusable element or document.
    * If aForward is false, navigate to the last focusable element or document.
    */
   void navigateByKey(in bool aForward, in bool aForDocumentNavigation);
 
   readonly attribute boolean hasContentOpener;
+
+  /**
+   * True if the TabChild has set up enough to paint and upload layers.
+   */
+  readonly attribute boolean canPresent;
+
   /**
    * True if we've previously received layers for this tab when switching to
    * it.
    */
   readonly attribute boolean hasPresented;
 
   /**
    * Ensures that the content process which has this tab parent has all of the
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -609,17 +609,17 @@ child:
                ShowInfo info,
                bool parentIsActive,
                nsSizeMode sizeMode);
 
     async InitRendering(TextureFactoryIdentifier textureFactoryIdentifier,
                         uint64_t layersId,
                         CompositorOptions compositorOptions,
                         bool layersConnected,
-                        nullable PRenderFrame renderFrame);
+                        nullable PRenderFrame renderFrame) returns (bool canPresent);
 
     async LoadURL(nsCString uri, ShowInfo info);
 
     async UpdateDimensions(DimensionInfo dimensions) compressall;
 
     async SizeModeChanged(nsSizeMode sizeMode);
 
     async ParentActivated(bool aActivated);
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -1253,22 +1253,25 @@ TabChild::RecvShow(const ScreenIntSize& 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 TabChild::RecvInitRendering(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
                             const uint64_t& aLayersId,
                             const CompositorOptions& aCompositorOptions,
                             const bool& aLayersConnected,
-                            PRenderFrameChild* aRenderFrame)
+                            PRenderFrameChild* aRenderFrame,
+                            InitRenderingResolver&& aResolve)
 {
   MOZ_ASSERT((!mDidFakeShow && aRenderFrame) || (mDidFakeShow && !aRenderFrame));
 
   mLayersConnected = aLayersConnected;
   InitRenderingState(aTextureFactoryIdentifier, aLayersId, aCompositorOptions, aRenderFrame);
+  aResolve(true /* canPresent */);
+
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 TabChild::RecvUpdateDimensions(const DimensionInfo& aDimensionInfo)
 {
     if (!mRemoteFrame) {
         return IPC_OK();
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -357,17 +357,18 @@ public:
            const bool& aParentIsActive,
            const nsSizeMode& aSizeMode) override;
 
   virtual mozilla::ipc::IPCResult
   RecvInitRendering(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
                     const uint64_t& aLayersId,
                     const mozilla::layers::CompositorOptions& aCompositorOptions,
                     const bool& aLayersConnected,
-                    PRenderFrameChild* aRenderFrame) override;
+                    PRenderFrameChild* aRenderFrame,
+                    InitRenderingResolver&& aResolve) override;
 
   virtual mozilla::ipc::IPCResult
   RecvUpdateDimensions(const mozilla::dom::DimensionInfo& aDimensionInfo) override;
   virtual mozilla::ipc::IPCResult
   RecvSizeModeChanged(const nsSizeMode& aSizeMode) override;
 
   mozilla::ipc::IPCResult RecvActivate();
 
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -3,16 +3,17 @@
 /* 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 "base/basictypes.h"
 
 #include "TabParent.h"
 
+#include "mozilla/AbstractThread.h"
 #ifdef ACCESSIBILITY
 #include "mozilla/a11y/DocAccessibleParent.h"
 #include "nsAccessibilityService.h"
 #endif
 #include "mozilla/BrowserElementParent.h"
 #include "mozilla/dom/ContentBridgeParent.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/DataTransfer.h"
@@ -167,16 +168,17 @@ TabParent::TabParent(nsIContentParent* a
   , mCursor(nsCursor(-1))
   , mTabSetsCursor(false)
   , mHasContentOpener(false)
 #ifdef DEBUG
   , mActiveSupressDisplayportCount(0)
 #endif
   , mLayerTreeEpoch(0)
   , mPreserveLayers(false)
+  , mCanPresent(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.
   mIsReadyToHandleInputEvents = !ContentParent::IsInputEventQueueSupported();
@@ -636,19 +638,31 @@ TabParent::InitRenderFrame()
       uint64_t layersId = renderFrame->GetLayersId();
       AddTabParentToTable(layersId, this);
       if (!SendPRenderFrameConstructor(renderFrame)) {
         return;
       }
 
       TextureFactoryIdentifier textureFactoryIdentifier;
       renderFrame->GetTextureFactoryIdentifier(&textureFactoryIdentifier);
-      Unused << SendInitRendering(textureFactoryIdentifier, layersId,
+
+      RefPtr<TabParent> self(this);
+
+      SendInitRendering(textureFactoryIdentifier, layersId,
         renderFrame->GetCompositorOptions(),
-        renderFrame->IsLayersConnected(), renderFrame);
+        renderFrame->IsLayersConnected(), renderFrame)->Then(
+          AbstractThread::MainThread(), __func__,
+          [self] (const bool& canPresent) {
+            MOZ_ASSERT(canPresent, "We should have been told that presenting is possible.");
+            self->mCanPresent = canPresent;
+          },
+          [self] (const mozilla::ipc::PromiseRejectReason) {
+            // Nothing to do, I guess. Maybe assert? I dunno.
+          }
+        );
     }
   } else {
     // Otherwise, the child should have constructed the RenderFrame,
     // and we should already know about it.
     MOZ_ASSERT(GetRenderFrame());
   }
 }
 
@@ -2975,16 +2989,23 @@ TabParent::GetHasContentOpener(bool* aRe
 
 void
 TabParent::SetHasContentOpener(bool aHasContentOpener)
 {
   mHasContentOpener = aHasContentOpener;
 }
 
 NS_IMETHODIMP
+TabParent::GetCanPresent(bool* aResult)
+{
+  *aResult = mCanPresent;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 TabParent::GetHasPresented(bool* aResult)
 {
   *aResult = mHasPresented;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TabParent::NavigateByKey(bool aForward, bool aForDocumentNavigation)
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -776,16 +776,21 @@ private:
   static void RemoveTabParentFromTable(uint64_t aLayersId);
 
   uint64_t mLayerTreeEpoch;
 
   // If this flag is set, then the tab's layers will be preserved even when
   // the tab's docshell is inactive.
   bool mPreserveLayers;
 
+  // True if the TabParent has initialized rendering in the content process
+  // and the content process has acknowledged. This means that it's possible
+  // for the TabChild to paint things and upload layer trees.
+  bool mCanPresent;
+
   // True if this TabParent has had its layer tree sent to the compositor
   // at least once.
   bool mHasPresented;
 
   // True if at least one window hosted in the TabChild has added a
   // beforeunload event listener.
   bool mHasBeforeUnload;