From 94ea7b082036bbfa3797e85aa6d5e2fde7dedf7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 5 Jun 2022 23:20:45 +0000 Subject: [PATCH] Bug 1772692 - AnimationInfo::EnumerateGenerationOnFrame shouldn't need to create a window renderer. r=hiro There's no need to lazily create a renderer here. We already avoided this in content processes, but there's no need to do so in the parent process either. This shouldn't change behavior, but might help with bug 1772691, and generally seems cleaner. Differential Revision: https://phabricator.services.mozilla.com/D148337 --- gfx/layers/AnimationInfo.cpp | 80 ++++++++++++++++-------------------- widget/PuppetWidget.h | 2 - widget/nsBaseWidget.h | 1 + widget/nsIWidget.h | 11 ++++- 4 files changed, 46 insertions(+), 48 deletions(-) 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.