diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 5a6997474909..88c81aa8e3a1 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -4178,7 +4178,7 @@ NS_IMETHODIMP nsDOMWindowUtils::RespectDisplayPortSuppression(bool aEnabled) { nsCOMPtr shell(GetPresShell()); - APZCCallbackHelper::RespectDisplayPortSuppression(aEnabled, shell); + shell->RespectDisplayportSuppression(aEnabled); return NS_OK; } diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index c7f809c96892..88efc9256ec8 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -402,7 +402,6 @@ TabChild::TabChild(nsIContentChild* aManager, , mManager(aManager) , mChromeFlags(aChromeFlags) , mMaxTouchPoints(0) - , mActiveSuppressDisplayport(0) , mLayersId{0} , mBeforeUnloadListeners(0) , mDidFakeShow(false) @@ -1343,14 +1342,9 @@ TabChild::UpdateFrame(const FrameMetrics& aFrameMetrics) mozilla::ipc::IPCResult TabChild::RecvSuppressDisplayport(const bool& aEnabled) { - if (aEnabled) { - mActiveSuppressDisplayport++; - } else { - mActiveSuppressDisplayport--; + if (nsCOMPtr shell = GetPresShell()) { + shell->SuppressDisplayport(aEnabled); } - - MOZ_ASSERT(mActiveSuppressDisplayport >= 0); - APZCCallbackHelper::SuppressDisplayport(aEnabled, GetPresShell()); return IPC_OK(); } @@ -2503,11 +2497,6 @@ TabChild::RecvDestroy() child->Destroy(); } - while (mActiveSuppressDisplayport > 0) { - APZCCallbackHelper::SuppressDisplayport(false, nullptr); - mActiveSuppressDisplayport--; - } - if (mTabChildGlobal) { // Message handlers are called from the event loop, so it better be safe to // run script. @@ -2665,7 +2654,7 @@ TabChild::RecvRenderLayers(const bool& aEnabled, const bool& aForceRepaint, cons // we get back to the event loop again. We suppress the display port so that // we only paint what's visible. This ensures that the tab we're switching // to paints as quickly as possible. - APZCCallbackHelper::SuppressDisplayport(true, presShell); + presShell->SuppressDisplayport(true); if (nsContentUtils::IsSafeToRunScript()) { WebWidget()->PaintNowIfNeeded(); } else { @@ -2675,7 +2664,7 @@ TabChild::RecvRenderLayers(const bool& aEnabled, const bool& aForceRepaint, cons nsIPresShell::PAINT_LAYERS); } } - APZCCallbackHelper::SuppressDisplayport(false, presShell); + presShell->SuppressDisplayport(false); } } else { if (sVisibleTabs) { diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index e46304464c81..3b4612e521b7 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -828,7 +828,6 @@ private: RefPtr mManager; uint32_t mChromeFlags; uint32_t mMaxTouchPoints; - int32_t mActiveSuppressDisplayport; layers::LayersId mLayersId; int64_t mBeforeUnloadListeners; CSSRect mUnscaledOuterRect; diff --git a/gfx/layers/apz/util/APZCCallbackHelper.cpp b/gfx/layers/apz/util/APZCCallbackHelper.cpp index ca56bf26f9f4..4d0cdb0c5edf 100644 --- a/gfx/layers/apz/util/APZCCallbackHelper.cpp +++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp @@ -884,48 +884,6 @@ APZCCallbackHelper::NotifyFlushComplete(nsIPresShell* aShell) observerService->NotifyObservers(nullptr, "apz-repaints-flushed", nullptr); } -static int32_t sActiveSuppressDisplayport = 0; -static bool sDisplayPortSuppressionRespected = true; - -void -APZCCallbackHelper::SuppressDisplayport(const bool& aEnabled, - const nsCOMPtr& aShell) -{ - if (aEnabled) { - sActiveSuppressDisplayport++; - } else { - bool isSuppressed = IsDisplayportSuppressed(); - sActiveSuppressDisplayport--; - if (isSuppressed && !IsDisplayportSuppressed() && - aShell && aShell->GetRootFrame()) { - // We unsuppressed the displayport, trigger a paint - aShell->GetRootFrame()->SchedulePaint(); - } - } - - MOZ_ASSERT(sActiveSuppressDisplayport >= 0); -} - -void -APZCCallbackHelper::RespectDisplayPortSuppression(bool aEnabled, - const nsCOMPtr& aShell) -{ - bool isSuppressed = IsDisplayportSuppressed(); - sDisplayPortSuppressionRespected = aEnabled; - if (isSuppressed && !IsDisplayportSuppressed() && - aShell && aShell->GetRootFrame()) { - // We unsuppressed the displayport, trigger a paint - aShell->GetRootFrame()->SchedulePaint(); - } -} - -bool -APZCCallbackHelper::IsDisplayportSuppressed() -{ - return sDisplayPortSuppressionRespected - && sActiveSuppressDisplayport > 0; -} - /* static */ bool APZCCallbackHelper::IsScrollInProgress(nsIScrollableFrame* aFrame) { diff --git a/gfx/layers/apz/util/APZCCallbackHelper.h b/gfx/layers/apz/util/APZCCallbackHelper.h index 30befef7b923..41aa16ff35b1 100644 --- a/gfx/layers/apz/util/APZCCallbackHelper.h +++ b/gfx/layers/apz/util/APZCCallbackHelper.h @@ -194,27 +194,6 @@ public: static void CancelAutoscroll(const FrameMetrics::ViewID& aScrollId); - /* Temporarily ignore the Displayport for better paint performance. If at - * all possible, pass in a presShell if you have one at the call site, we - * use it to trigger a repaint once suppression is disabled. Without that - * the displayport may get left at the suppressed size for an extended - * period of time and result in unnecessary checkerboarding (see bug - * 1255054). */ - static void SuppressDisplayport(const bool& aEnabled, - const nsCOMPtr& aShell); - - /* Whether or not displayport suppression should be turned on. Note that - * this only affects the return value of |IsDisplayportSuppressed()|, and - * doesn't change the value of the internal counter. As with - * SuppressDisplayport, this function should be passed a presShell to trigger - * a repaint if suppression is being turned off. - */ - static void RespectDisplayPortSuppression(bool aEnabled, - const nsCOMPtr& aShell); - - /* Whether or not the displayport is currently suppressed. */ - static bool IsDisplayportSuppressed(); - static void AdjustDisplayPortForScrollDelta(mozilla::layers::FrameMetrics& aFrameMetrics, const CSSPoint& aActualScrollOffset); diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp index 6fff7dfb82be..94181770ba05 100644 --- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -809,6 +809,7 @@ PresShell::PresShell() , mLastCallbackEventRequest(nullptr) , mLastReflowStart(0.0) , mLastAnchorScrollPositionY(0) + , mActiveSuppressDisplayport(0) , mAPZFocusSequenceNumber(0) , mDocumentLoading(false) , mIgnoreFrameDestruction(false) @@ -8555,6 +8556,47 @@ PresShell::IsVisible() return frame->IsVisibleConsideringAncestors(nsIFrame::VISIBILITY_CROSS_CHROME_CONTENT_BOUNDARY); } +void +PresShell::SuppressDisplayport(bool aEnabled) +{ + if (aEnabled) { + mActiveSuppressDisplayport++; + } else { + bool isSuppressed = IsDisplayportSuppressed(); + mActiveSuppressDisplayport--; + if (isSuppressed && !IsDisplayportSuppressed()) { + // We unsuppressed the displayport, trigger a paint + if (nsIFrame* rootFrame = mFrameConstructor->GetRootFrame()) { + rootFrame->SchedulePaint(); + } + } + } + + MOZ_ASSERT(mActiveSuppressDisplayport >= 0); +} + +static bool sDisplayPortSuppressionRespected = true; + +void +PresShell::RespectDisplayportSuppression(bool aEnabled) +{ + bool isSuppressed = IsDisplayportSuppressed(); + sDisplayPortSuppressionRespected = aEnabled; + if (isSuppressed && !IsDisplayportSuppressed()) { + // We unsuppressed the displayport, trigger a paint + if (nsIFrame* rootFrame = mFrameConstructor->GetRootFrame()) { + rootFrame->SchedulePaint(); + } + } +} + +bool +PresShell::IsDisplayportSuppressed() +{ + return sDisplayPortSuppressionRespected && + mActiveSuppressDisplayport > 0; +} + nsresult PresShell::GetAgentStyleSheets(nsTArray>& aSheets) { diff --git a/layout/base/PresShell.h b/layout/base/PresShell.h index 9039e4766c7c..662d533824b6 100644 --- a/layout/base/PresShell.h +++ b/layout/base/PresShell.h @@ -245,6 +245,9 @@ public: void ScheduleViewManagerFlush(PaintType aType = PAINT_DEFAULT) override; void ClearMouseCaptureOnView(nsView* aView) override; bool IsVisible() override; + void SuppressDisplayport(bool aEnabled) override; + void RespectDisplayportSuppression(bool aEnabled) override; + bool IsDisplayportSuppressed() override; already_AddRefed GetAccessibleCaretEventHub() const override; @@ -830,6 +833,8 @@ private: // when target of pointer event was deleted during executing user handlers. nsCOMPtr mPointerEventTarget; + int32_t mActiveSuppressDisplayport; + // The focus sequence number of the last processed input event uint64_t mAPZFocusSequenceNumber; // The focus information needed for async keyboard scrolling diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index 54892a5e60b5..801605f150ca 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -1505,6 +1505,22 @@ public: virtual bool IsVisible() = 0; void DispatchSynthMouseMove(mozilla::WidgetGUIEvent* aEvent); + /* Temporarily ignore the Displayport for better paint performance. We + * trigger a repaint once suppression is disabled. Without that + * the displayport may get left at the suppressed size for an extended + * period of time and result in unnecessary checkerboarding (see bug + * 1255054). */ + virtual void SuppressDisplayport(bool aEnabled) = 0; + + /* Whether or not displayport suppression should be turned on. Note that + * this only affects the return value of |IsDisplayportSuppressed()|, and + * doesn't change the value of the internal counter. + */ + virtual void RespectDisplayportSuppression(bool aEnabled) = 0; + + /* Whether or not the displayport is currently suppressed. */ + virtual bool IsDisplayportSuppressed() = 0; + virtual void AddSizeOfIncludingThis(nsWindowSizes& aWindowSizes) const = 0; /** diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 340b3099caa7..723dba10d185 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -877,7 +877,10 @@ GetDisplayPortFromMarginsData(nsIContent* aContent, // the choosing of the resolution to display-list building time. ScreenSize alignment; - if (APZCCallbackHelper::IsDisplayportSuppressed()) { + nsIPresShell* presShell = presContext->PresShell(); + MOZ_ASSERT(presShell); + + if (presShell->IsDisplayportSuppressed()) { alignment = ScreenSize(1, 1); } else if (gfxPrefs::LayersTilesEnabled()) { // Don't align to tiles if they are too large, because we could expand @@ -1098,10 +1101,21 @@ GetDisplayPortImpl(nsIContent* aContent, nsRect* aResult, float aMultiplier, return true; } + bool isDisplayportSuppressed = false; + + nsIFrame* frame = aContent->GetPrimaryFrame(); + if (frame) { + nsPresContext* presContext = frame->PresContext(); + MOZ_ASSERT(presContext); + nsIPresShell* presShell = presContext->PresShell(); + MOZ_ASSERT(presShell); + isDisplayportSuppressed = presShell->IsDisplayportSuppressed(); + } + nsRect result; if (rectData) { result = GetDisplayPortFromRectData(aContent, rectData, aMultiplier); - } else if (APZCCallbackHelper::IsDisplayportSuppressed() || + } else if (isDisplayportSuppressed || nsLayoutUtils::ShouldDisableApzForElement(aContent)) { DisplayPortMarginsPropertyData noMargins(ScreenMargin(), 1); result = GetDisplayPortFromMarginsData(aContent, &noMargins, aMultiplier); diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 31d5a3b6c230..71e467412b96 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -1913,7 +1913,9 @@ public: } mCallee = aCallee; - APZCCallbackHelper::SuppressDisplayport(true, mCallee->mOuter->PresShell()); + if (nsIPresShell* shell = mCallee->mOuter->PresShell()) { + shell->SuppressDisplayport(true); + } return true; } @@ -1938,7 +1940,9 @@ private: void RemoveObserver() { if (mCallee) { RefreshDriver(mCallee)->RemoveRefreshObserver(this, FlushType::Style); - APZCCallbackHelper::SuppressDisplayport(false, mCallee->mOuter->PresShell()); + if (nsIPresShell* shell = mCallee->mOuter->PresShell()) { + shell->SuppressDisplayport(false); + } } } }; diff --git a/layout/xul/nsSliderFrame.cpp b/layout/xul/nsSliderFrame.cpp index e12b954c2aa1..cc3fe4a36504 100644 --- a/layout/xul/nsSliderFrame.cpp +++ b/layout/xul/nsSliderFrame.cpp @@ -99,9 +99,9 @@ nsSliderFrame::nsSliderFrame(ComputedStyle* aStyle) nsSliderFrame::~nsSliderFrame() { if (mSuppressionActive) { - APZCCallbackHelper::SuppressDisplayport(false, PresContext() ? - PresShell() : - nullptr); + if (nsIPresShell* shell = PresShell()) { + shell->SuppressDisplayport(false); + } } } @@ -1618,8 +1618,9 @@ void nsSliderFrame::SuppressDisplayport() { if (!mSuppressionActive) { - MOZ_ASSERT(PresShell()); - APZCCallbackHelper::SuppressDisplayport(true, PresShell()); + nsIPresShell* shell = PresShell(); + MOZ_ASSERT(shell); + shell->SuppressDisplayport(true); mSuppressionActive = true; } } @@ -1628,8 +1629,9 @@ void nsSliderFrame::UnsuppressDisplayport() { if (mSuppressionActive) { - MOZ_ASSERT(PresShell()); - APZCCallbackHelper::SuppressDisplayport(false, PresShell()); + nsIPresShell* shell = PresShell(); + MOZ_ASSERT(shell); + shell->SuppressDisplayport(false); mSuppressionActive = false; } }