Bug 1449756 - Make DisplayPort suppression PresShell specific and not process global. r=kats

Originally, DisplayPort suppression was a process-global static. This change makes it possible
to control DisplayPort suppression on a per-PresShell basis.

Differential Revision: https://phabricator.services.mozilla.com/D1759
This commit is contained in:
Mike Conley 2018-06-25 21:42:25 +00:00
Родитель 047b517cdd
Коммит f88719f6e0
11 изменённых файлов: 99 добавлений и 91 удалений

Просмотреть файл

@ -4178,7 +4178,7 @@ NS_IMETHODIMP
nsDOMWindowUtils::RespectDisplayPortSuppression(bool aEnabled) nsDOMWindowUtils::RespectDisplayPortSuppression(bool aEnabled)
{ {
nsCOMPtr<nsIPresShell> shell(GetPresShell()); nsCOMPtr<nsIPresShell> shell(GetPresShell());
APZCCallbackHelper::RespectDisplayPortSuppression(aEnabled, shell); shell->RespectDisplayportSuppression(aEnabled);
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -402,7 +402,6 @@ TabChild::TabChild(nsIContentChild* aManager,
, mManager(aManager) , mManager(aManager)
, mChromeFlags(aChromeFlags) , mChromeFlags(aChromeFlags)
, mMaxTouchPoints(0) , mMaxTouchPoints(0)
, mActiveSuppressDisplayport(0)
, mLayersId{0} , mLayersId{0}
, mBeforeUnloadListeners(0) , mBeforeUnloadListeners(0)
, mDidFakeShow(false) , mDidFakeShow(false)
@ -1343,14 +1342,9 @@ TabChild::UpdateFrame(const FrameMetrics& aFrameMetrics)
mozilla::ipc::IPCResult mozilla::ipc::IPCResult
TabChild::RecvSuppressDisplayport(const bool& aEnabled) TabChild::RecvSuppressDisplayport(const bool& aEnabled)
{ {
if (aEnabled) { if (nsCOMPtr<nsIPresShell> shell = GetPresShell()) {
mActiveSuppressDisplayport++; shell->SuppressDisplayport(aEnabled);
} else {
mActiveSuppressDisplayport--;
} }
MOZ_ASSERT(mActiveSuppressDisplayport >= 0);
APZCCallbackHelper::SuppressDisplayport(aEnabled, GetPresShell());
return IPC_OK(); return IPC_OK();
} }
@ -2503,11 +2497,6 @@ TabChild::RecvDestroy()
child->Destroy(); child->Destroy();
} }
while (mActiveSuppressDisplayport > 0) {
APZCCallbackHelper::SuppressDisplayport(false, nullptr);
mActiveSuppressDisplayport--;
}
if (mTabChildGlobal) { if (mTabChildGlobal) {
// Message handlers are called from the event loop, so it better be safe to // Message handlers are called from the event loop, so it better be safe to
// run script. // 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 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 // we only paint what's visible. This ensures that the tab we're switching
// to paints as quickly as possible. // to paints as quickly as possible.
APZCCallbackHelper::SuppressDisplayport(true, presShell); presShell->SuppressDisplayport(true);
if (nsContentUtils::IsSafeToRunScript()) { if (nsContentUtils::IsSafeToRunScript()) {
WebWidget()->PaintNowIfNeeded(); WebWidget()->PaintNowIfNeeded();
} else { } else {
@ -2675,7 +2664,7 @@ TabChild::RecvRenderLayers(const bool& aEnabled, const bool& aForceRepaint, cons
nsIPresShell::PAINT_LAYERS); nsIPresShell::PAINT_LAYERS);
} }
} }
APZCCallbackHelper::SuppressDisplayport(false, presShell); presShell->SuppressDisplayport(false);
} }
} else { } else {
if (sVisibleTabs) { if (sVisibleTabs) {

Просмотреть файл

@ -828,7 +828,6 @@ private:
RefPtr<nsIContentChild> mManager; RefPtr<nsIContentChild> mManager;
uint32_t mChromeFlags; uint32_t mChromeFlags;
uint32_t mMaxTouchPoints; uint32_t mMaxTouchPoints;
int32_t mActiveSuppressDisplayport;
layers::LayersId mLayersId; layers::LayersId mLayersId;
int64_t mBeforeUnloadListeners; int64_t mBeforeUnloadListeners;
CSSRect mUnscaledOuterRect; CSSRect mUnscaledOuterRect;

Просмотреть файл

@ -884,48 +884,6 @@ APZCCallbackHelper::NotifyFlushComplete(nsIPresShell* aShell)
observerService->NotifyObservers(nullptr, "apz-repaints-flushed", nullptr); observerService->NotifyObservers(nullptr, "apz-repaints-flushed", nullptr);
} }
static int32_t sActiveSuppressDisplayport = 0;
static bool sDisplayPortSuppressionRespected = true;
void
APZCCallbackHelper::SuppressDisplayport(const bool& aEnabled,
const nsCOMPtr<nsIPresShell>& 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<nsIPresShell>& 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 /* static */ bool
APZCCallbackHelper::IsScrollInProgress(nsIScrollableFrame* aFrame) APZCCallbackHelper::IsScrollInProgress(nsIScrollableFrame* aFrame)
{ {

Просмотреть файл

@ -194,27 +194,6 @@ public:
static void CancelAutoscroll(const FrameMetrics::ViewID& aScrollId); 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<nsIPresShell>& 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<nsIPresShell>& aShell);
/* Whether or not the displayport is currently suppressed. */
static bool IsDisplayportSuppressed();
static void static void
AdjustDisplayPortForScrollDelta(mozilla::layers::FrameMetrics& aFrameMetrics, AdjustDisplayPortForScrollDelta(mozilla::layers::FrameMetrics& aFrameMetrics,
const CSSPoint& aActualScrollOffset); const CSSPoint& aActualScrollOffset);

Просмотреть файл

@ -809,6 +809,7 @@ PresShell::PresShell()
, mLastCallbackEventRequest(nullptr) , mLastCallbackEventRequest(nullptr)
, mLastReflowStart(0.0) , mLastReflowStart(0.0)
, mLastAnchorScrollPositionY(0) , mLastAnchorScrollPositionY(0)
, mActiveSuppressDisplayport(0)
, mAPZFocusSequenceNumber(0) , mAPZFocusSequenceNumber(0)
, mDocumentLoading(false) , mDocumentLoading(false)
, mIgnoreFrameDestruction(false) , mIgnoreFrameDestruction(false)
@ -8555,6 +8556,47 @@ PresShell::IsVisible()
return frame->IsVisibleConsideringAncestors(nsIFrame::VISIBILITY_CROSS_CHROME_CONTENT_BOUNDARY); 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 nsresult
PresShell::GetAgentStyleSheets(nsTArray<RefPtr<StyleSheet>>& aSheets) PresShell::GetAgentStyleSheets(nsTArray<RefPtr<StyleSheet>>& aSheets)
{ {

Просмотреть файл

@ -245,6 +245,9 @@ public:
void ScheduleViewManagerFlush(PaintType aType = PAINT_DEFAULT) override; void ScheduleViewManagerFlush(PaintType aType = PAINT_DEFAULT) override;
void ClearMouseCaptureOnView(nsView* aView) override; void ClearMouseCaptureOnView(nsView* aView) override;
bool IsVisible() override; bool IsVisible() override;
void SuppressDisplayport(bool aEnabled) override;
void RespectDisplayportSuppression(bool aEnabled) override;
bool IsDisplayportSuppressed() override;
already_AddRefed<AccessibleCaretEventHub> GetAccessibleCaretEventHub() const override; already_AddRefed<AccessibleCaretEventHub> GetAccessibleCaretEventHub() const override;
@ -830,6 +833,8 @@ private:
// when target of pointer event was deleted during executing user handlers. // when target of pointer event was deleted during executing user handlers.
nsCOMPtr<nsIContent> mPointerEventTarget; nsCOMPtr<nsIContent> mPointerEventTarget;
int32_t mActiveSuppressDisplayport;
// The focus sequence number of the last processed input event // The focus sequence number of the last processed input event
uint64_t mAPZFocusSequenceNumber; uint64_t mAPZFocusSequenceNumber;
// The focus information needed for async keyboard scrolling // The focus information needed for async keyboard scrolling

Просмотреть файл

@ -1505,6 +1505,22 @@ public:
virtual bool IsVisible() = 0; virtual bool IsVisible() = 0;
void DispatchSynthMouseMove(mozilla::WidgetGUIEvent* aEvent); 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; virtual void AddSizeOfIncludingThis(nsWindowSizes& aWindowSizes) const = 0;
/** /**

Просмотреть файл

@ -877,7 +877,10 @@ GetDisplayPortFromMarginsData(nsIContent* aContent,
// the choosing of the resolution to display-list building time. // the choosing of the resolution to display-list building time.
ScreenSize alignment; ScreenSize alignment;
if (APZCCallbackHelper::IsDisplayportSuppressed()) { nsIPresShell* presShell = presContext->PresShell();
MOZ_ASSERT(presShell);
if (presShell->IsDisplayportSuppressed()) {
alignment = ScreenSize(1, 1); alignment = ScreenSize(1, 1);
} else if (gfxPrefs::LayersTilesEnabled()) { } else if (gfxPrefs::LayersTilesEnabled()) {
// Don't align to tiles if they are too large, because we could expand // 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; 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; nsRect result;
if (rectData) { if (rectData) {
result = GetDisplayPortFromRectData(aContent, rectData, aMultiplier); result = GetDisplayPortFromRectData(aContent, rectData, aMultiplier);
} else if (APZCCallbackHelper::IsDisplayportSuppressed() || } else if (isDisplayportSuppressed ||
nsLayoutUtils::ShouldDisableApzForElement(aContent)) { nsLayoutUtils::ShouldDisableApzForElement(aContent)) {
DisplayPortMarginsPropertyData noMargins(ScreenMargin(), 1); DisplayPortMarginsPropertyData noMargins(ScreenMargin(), 1);
result = GetDisplayPortFromMarginsData(aContent, &noMargins, aMultiplier); result = GetDisplayPortFromMarginsData(aContent, &noMargins, aMultiplier);

Просмотреть файл

@ -1913,7 +1913,9 @@ public:
} }
mCallee = aCallee; mCallee = aCallee;
APZCCallbackHelper::SuppressDisplayport(true, mCallee->mOuter->PresShell()); if (nsIPresShell* shell = mCallee->mOuter->PresShell()) {
shell->SuppressDisplayport(true);
}
return true; return true;
} }
@ -1938,7 +1940,9 @@ private:
void RemoveObserver() { void RemoveObserver() {
if (mCallee) { if (mCallee) {
RefreshDriver(mCallee)->RemoveRefreshObserver(this, FlushType::Style); RefreshDriver(mCallee)->RemoveRefreshObserver(this, FlushType::Style);
APZCCallbackHelper::SuppressDisplayport(false, mCallee->mOuter->PresShell()); if (nsIPresShell* shell = mCallee->mOuter->PresShell()) {
shell->SuppressDisplayport(false);
}
} }
} }
}; };

Просмотреть файл

@ -99,9 +99,9 @@ nsSliderFrame::nsSliderFrame(ComputedStyle* aStyle)
nsSliderFrame::~nsSliderFrame() nsSliderFrame::~nsSliderFrame()
{ {
if (mSuppressionActive) { if (mSuppressionActive) {
APZCCallbackHelper::SuppressDisplayport(false, PresContext() ? if (nsIPresShell* shell = PresShell()) {
PresShell() : shell->SuppressDisplayport(false);
nullptr); }
} }
} }
@ -1618,8 +1618,9 @@ void
nsSliderFrame::SuppressDisplayport() nsSliderFrame::SuppressDisplayport()
{ {
if (!mSuppressionActive) { if (!mSuppressionActive) {
MOZ_ASSERT(PresShell()); nsIPresShell* shell = PresShell();
APZCCallbackHelper::SuppressDisplayport(true, PresShell()); MOZ_ASSERT(shell);
shell->SuppressDisplayport(true);
mSuppressionActive = true; mSuppressionActive = true;
} }
} }
@ -1628,8 +1629,9 @@ void
nsSliderFrame::UnsuppressDisplayport() nsSliderFrame::UnsuppressDisplayport()
{ {
if (mSuppressionActive) { if (mSuppressionActive) {
MOZ_ASSERT(PresShell()); nsIPresShell* shell = PresShell();
APZCCallbackHelper::SuppressDisplayport(false, PresShell()); MOZ_ASSERT(shell);
shell->SuppressDisplayport(false);
mSuppressionActive = false; mSuppressionActive = false;
} }
} }