diff --git a/gfx/layers/AnimationInfo.cpp b/gfx/layers/AnimationInfo.cpp index 826746fc3dd4..e6e142fec0b1 100644 --- a/gfx/layers/AnimationInfo.cpp +++ b/gfx/layers/AnimationInfo.cpp @@ -171,55 +171,47 @@ void AnimationInfo::EnumerateGenerationOnFrame( const nsIFrame* aFrame, const nsIContent* aContent, const CompositorAnimatableDisplayItemTypes& aDisplayItemTypes, AnimationGenerationCallback aCallback) { - if (XRE_IsContentProcess()) { - if (nsIWidget* widget = nsContentUtils::WidgetForContent(aContent)) { - // In case of child processes, we might not have yet created the layer - // manager. That means there is no animation generation we have, thus - // we call the callback function with |Nothing()| for the generation. - // - // Note that we need to use nsContentUtils::WidgetForContent() instead of - // BrowserChild::GetFrom(aFrame->PresShell())->WebWidget() because in the - // case of child popup content PuppetWidget::mBrowserChild is the same as - // the parent's one, which means mBrowserChild->IsLayersConnected() check - // in PuppetWidget::GetLayerManager queries the parent state, it results - // the assertion in the function failure. - if (widget->GetOwningBrowserChild() && - !static_cast(widget)->HasWindowRenderer()) { - for (auto displayItem : LayerAnimationInfo::sDisplayItemTypes) { - aCallback(Nothing(), displayItem); - } - return; - } - } + nsIWidget* widget = nsContentUtils::WidgetForContent(aContent); + if (!widget) { + return; } - - WindowRenderer* renderer = nsContentUtils::WindowRendererForContent(aContent); - - if (renderer && renderer->AsWebRender()) { - // In case of continuation, nsDisplayItem uses its last continuation, so we - // have to use the last continuation frame here. - if (nsLayoutUtils::IsFirstContinuationOrIBSplitSibling(aFrame)) { - aFrame = nsLayoutUtils::LastContinuationOrIBSplitSibling(aFrame); - } - + // If we haven't created a window renderer there's no animation generation + // that we can have, thus we call the callback function with |Nothing()| for + // the generation. + if (!widget->HasWindowRenderer()) { for (auto displayItem : LayerAnimationInfo::sDisplayItemTypes) { - // For transform animations, the animation is on the primary frame but - // |aFrame| is the style frame. - const nsIFrame* frameToQuery = - displayItem == DisplayItemType::TYPE_TRANSFORM - ? nsLayoutUtils::GetPrimaryFrameFromStyleFrame(aFrame) - : aFrame; - RefPtr animationData = - GetWebRenderUserData(frameToQuery, - (uint32_t)displayItem); - Maybe generation; - if (animationData) { - generation = animationData->GetAnimationInfo().GetAnimationGeneration(); - } - aCallback(generation, displayItem); + aCallback(Nothing(), displayItem); } return; } + WindowRenderer* renderer = widget->GetWindowRenderer(); + MOZ_ASSERT(renderer); + if (!renderer->AsWebRender()) { + return; + } + + // In case of continuation, nsDisplayItem uses its last continuation, so we + // have to use the last continuation frame here. + if (nsLayoutUtils::IsFirstContinuationOrIBSplitSibling(aFrame)) { + aFrame = nsLayoutUtils::LastContinuationOrIBSplitSibling(aFrame); + } + + for (auto displayItem : LayerAnimationInfo::sDisplayItemTypes) { + // For transform animations, the animation is on the primary frame but + // |aFrame| is the style frame. + const nsIFrame* frameToQuery = + displayItem == DisplayItemType::TYPE_TRANSFORM + ? nsLayoutUtils::GetPrimaryFrameFromStyleFrame(aFrame) + : aFrame; + RefPtr animationData = + GetWebRenderUserData(frameToQuery, + (uint32_t)displayItem); + Maybe generation; + if (animationData) { + generation = animationData->GetAnimationInfo().GetAnimationGeneration(); + } + aCallback(generation, displayItem); + } } static StyleTransformOperation ResolveTranslate( diff --git a/widget/PuppetWidget.h b/widget/PuppetWidget.h index 03dcb1132519..134db026e30b 100644 --- a/widget/PuppetWidget.h +++ b/widget/PuppetWidget.h @@ -185,8 +185,6 @@ class PuppetWidget : public nsBaseWidget, bool CreateRemoteLayerManager( const std::function& aInitializeFunc); - bool HasWindowRenderer() { return !!mWindowRenderer; } - virtual void SetInputContext(const InputContext& aContext, const InputContextAction& aAction) override; virtual InputContext GetInputContext() override; diff --git a/widget/nsBaseWidget.h b/widget/nsBaseWidget.h index bb66fe165003..87599b8ca498 100644 --- a/widget/nsBaseWidget.h +++ b/widget/nsBaseWidget.h @@ -212,6 +212,7 @@ class nsBaseWidget : public nsIWidget, public nsSupportsWeakReference { void InfallibleMakeFullScreen(bool aFullScreen); WindowRenderer* GetWindowRenderer() override; + bool HasWindowRenderer() const final { return !!mWindowRenderer; } // A remote compositor session tied to this window has been lost and IPC // messages will no longer work. The widget must clean up any lingering diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index bd689cc8997d..19c397d91c6f 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -1199,11 +1199,18 @@ class nsIWidget : public nsISupports { }; /** - * Return the widget's LayerManager. The layer tree for that - * LayerManager is what gets rendered to the widget. + * Return the widget's LayerManager. The layer tree for that LayerManager is + * what gets rendered to the widget. + * + * Note that this tries to create a renderer if it doesn't exist. */ virtual WindowRenderer* GetWindowRenderer() = 0; + /** + * Returns whether there's an existing window renderer. + */ + virtual bool HasWindowRenderer() const = 0; + /** * Called before each layer manager transaction to allow any preparation * for DrawWindowUnderlay/Overlay that needs to be on the main thread.