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
--- 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;