Bug 1315974 - When creating the widget layer manager, don't assume it will always be a ClientLayerManager. r?mattwoodrow
MozReview-Commit-ID: 8r037jdHJ0E
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -2408,18 +2408,19 @@ TabChild::RecvSetDocShellIsActive(const
if (aIsActive) {
ProcessHangMonitor::ClearForcePaint();
}
});
// We send the current layer observer epoch to the compositor so that
// TabParent knows whether a layer update notification corresponds to the
// latest SetDocShellIsActive request that was made.
- ClientLayerManager *manager = mPuppetWidget->GetLayerManager()->AsClientLayerManager();
- manager->SetLayerObserverEpoch(aLayerObserverEpoch);
+ if (ClientLayerManager* clm = mPuppetWidget->GetLayerManager()->AsClientLayerManager()) {
+ clm->SetLayerObserverEpoch(aLayerObserverEpoch);
+ }
// docshell is consider prerendered only if not active yet
mIsPrerendered &= !aIsActive;
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
if (docShell) {
bool wasActive;
docShell->GetIsActive(&wasActive);
if (aIsActive && wasActive) {
@@ -2583,44 +2584,50 @@ TabChild::InitRenderingState(const Textu
// Pushing layers transactions directly to a separate
// compositor context.
PCompositorBridgeChild* compositorChild = CompositorBridgeChild::Get();
if (!compositorChild) {
NS_WARNING("failed to get CompositorBridgeChild instance");
PRenderFrameChild::Send__delete__(remoteFrame);
return false;
}
- nsTArray<LayersBackend> backends;
- backends.AppendElement(mTextureFactoryIdentifier.mParentBackend);
- bool success;
- PLayerTransactionChild* shadowManager =
- compositorChild->SendPLayerTransactionConstructor(backends,
- aLayersId, &mTextureFactoryIdentifier, &success);
- if (!success) {
- NS_WARNING("failed to properly allocate layer transaction");
- PRenderFrameChild::Send__delete__(remoteFrame);
- return false;
- }
-
- if (!shadowManager) {
- NS_WARNING("failed to construct LayersChild");
- // This results in |remoteFrame| being deleted.
- PRenderFrameChild::Send__delete__(remoteFrame);
- return false;
- }
ShadowLayerForwarder* lf =
mPuppetWidget->GetLayerManager(
- shadowManager, mTextureFactoryIdentifier.mParentBackend)
+ nullptr, mTextureFactoryIdentifier.mParentBackend)
->AsShadowForwarder();
- MOZ_ASSERT(lf && lf->HasShadowManager(),
- "PuppetWidget should have shadow manager");
- lf->IdentifyTextureHost(mTextureFactoryIdentifier);
- ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
- gfx::VRManagerChild::IdentifyTextureHost(mTextureFactoryIdentifier);
+ // As long as we are creating a ClientLayerManager for the puppet widget,
+ // lf must be non-null here.
+ MOZ_ASSERT(lf);
+
+ if (lf) {
+ nsTArray<LayersBackend> backends;
+ backends.AppendElement(mTextureFactoryIdentifier.mParentBackend);
+ bool success;
+ PLayerTransactionChild* shadowManager =
+ compositorChild->SendPLayerTransactionConstructor(backends,
+ aLayersId, &mTextureFactoryIdentifier, &success);
+ if (!success) {
+ NS_WARNING("failed to properly allocate layer transaction");
+ PRenderFrameChild::Send__delete__(remoteFrame);
+ return false;
+ }
+
+ if (!shadowManager) {
+ NS_WARNING("failed to construct LayersChild");
+ // This results in |remoteFrame| being deleted.
+ PRenderFrameChild::Send__delete__(remoteFrame);
+ return false;
+ }
+
+ lf->SetShadowManager(shadowManager);
+ lf->IdentifyTextureHost(mTextureFactoryIdentifier);
+ ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
+ gfx::VRManagerChild::IdentifyTextureHost(mTextureFactoryIdentifier);
+ }
mRemoteFrame = remoteFrame;
if (aLayersId != 0) {
if (!sTabChildren) {
sTabChildren = new TabChildMap;
}
MOZ_ASSERT(!sTabChildren->Get(aLayersId));
sTabChildren->Put(aLayersId, this);
@@ -2992,16 +2999,17 @@ TabChild::ReinitRendering()
void
TabChild::CompositorUpdated(const TextureFactoryIdentifier& aNewIdentifier)
{
gfxPlatform::GetPlatform()->CompositorUpdated();
RefPtr<LayerManager> lm = mPuppetWidget->GetLayerManager();
ClientLayerManager* clm = lm->AsClientLayerManager();
+ MOZ_ASSERT(clm);
mTextureFactoryIdentifier = aNewIdentifier;
clm->UpdateTextureFactoryIdentifier(aNewIdentifier);
FrameLayerBuilder::InvalidateAllLayers(clm);
}
NS_IMETHODIMP
TabChild::OnShowTooltip(int32_t aXCoords, int32_t aYCoords, const char16_t *aTipText,
--- a/widget/PuppetWidget.cpp
+++ b/widget/PuppetWidget.cpp
@@ -579,27 +579,29 @@ LayerManager*
PuppetWidget::GetLayerManager(PLayerTransactionChild* aShadowManager,
LayersBackend aBackendHint,
LayerManagerPersistence aPersistence)
{
if (!mLayerManager) {
mLayerManager = new ClientLayerManager(this);
}
ShadowLayerForwarder* lf = mLayerManager->AsShadowForwarder();
- if (!lf->HasShadowManager() && aShadowManager) {
+ if (lf && !lf->HasShadowManager() && aShadowManager) {
lf->SetShadowManager(aShadowManager);
}
return mLayerManager;
}
LayerManager*
PuppetWidget::RecreateLayerManager(PLayerTransactionChild* aShadowManager)
{
mLayerManager = new ClientLayerManager(this);
- mLayerManager->AsShadowForwarder()->SetShadowManager(aShadowManager);
+ if (ShadowLayerForwarder* lf = mLayerManager->AsShadowForwarder()) {
+ lf->SetShadowManager(aShadowManager);
+ }
return mLayerManager;
}
nsresult
PuppetWidget::RequestIMEToCommitComposition(bool aCancel)
{
#ifdef MOZ_CROSS_PROCESS_IME
if (!mTabChild) {
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -1324,45 +1324,52 @@ void nsBaseWidget::CreateCompositor(int
if (mInitialZoomConstraints) {
UpdateZoomConstraints(mInitialZoomConstraints->mPresShellID,
mInitialZoomConstraints->mViewID,
Some(mInitialZoomConstraints->mConstraints));
mInitialZoomConstraints.reset();
}
- TextureFactoryIdentifier textureFactoryIdentifier;
- PLayerTransactionChild* shadowManager = nullptr;
-
- nsTArray<LayersBackend> backendHints;
- gfxPlatform::GetPlatform()->GetCompositorBackends(ComputeShouldAccelerate(), backendHints);
-
- bool success = false;
- if (!backendHints.IsEmpty()) {
- shadowManager = mCompositorBridgeChild->SendPLayerTransactionConstructor(
- backendHints, 0, &textureFactoryIdentifier, &success);
+ ShadowLayerForwarder* lf = lm->AsShadowForwarder();
+ // As long as we are creating a ClientLayerManager above lf must be non-null.
+ MOZ_ASSERT(lf);
+
+ if (lf) {
+ TextureFactoryIdentifier textureFactoryIdentifier;
+ PLayerTransactionChild* shadowManager = nullptr;
+
+ nsTArray<LayersBackend> backendHints;
+ gfxPlatform::GetPlatform()->GetCompositorBackends(ComputeShouldAccelerate(), backendHints);
+
+ bool success = false;
+ if (!backendHints.IsEmpty()) {
+ shadowManager = mCompositorBridgeChild->SendPLayerTransactionConstructor(
+ backendHints, 0, &textureFactoryIdentifier, &success);
+ }
+
+ if (!success) {
+ NS_WARNING("Failed to create an OMT compositor.");
+ DestroyCompositor();
+ mLayerManager = nullptr;
+ return;
+ }
+
+ lf->SetShadowManager(shadowManager);
+ if (ClientLayerManager* clm = lm->AsClientLayerManager()) {
+ clm->UpdateTextureFactoryIdentifier(textureFactoryIdentifier);
+ }
+ // Some popup or transparent widgets may use a different backend than the
+ // compositors used with ImageBridge and VR (and more generally web content).
+ if (WidgetTypeSupportsAcceleration()) {
+ ImageBridgeChild::IdentifyCompositorTextureHost(textureFactoryIdentifier);
+ gfx::VRManagerChild::IdentifyTextureHost(textureFactoryIdentifier);
+ }
}
- ShadowLayerForwarder* lf = lm->AsShadowForwarder();
-
- if (!success || !lf) {
- NS_WARNING("Failed to create an OMT compositor.");
- DestroyCompositor();
- mLayerManager = nullptr;
- return;
- }
-
- lf->SetShadowManager(shadowManager);
- lm->UpdateTextureFactoryIdentifier(textureFactoryIdentifier);
- // Some popup or transparent widgets may use a different backend than the
- // compositors used with ImageBridge and VR (and more generally web content).
- if (WidgetTypeSupportsAcceleration()) {
- ImageBridgeChild::IdentifyCompositorTextureHost(textureFactoryIdentifier);
- gfx::VRManagerChild::IdentifyTextureHost(textureFactoryIdentifier);
- }
WindowUsesOMTC();
mLayerManager = lm.forget();
// Only track compositors for top-level windows, since other window types
// may use the basic compositor. Except on the OS X - see bug 1306383
#if defined(XP_MACOSX)
bool getCompositorFromThisWindow = true;