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)
{
nsCOMPtr<nsIPresShell> shell(GetPresShell());
APZCCallbackHelper::RespectDisplayPortSuppression(aEnabled, shell);
shell->RespectDisplayportSuppression(aEnabled);
return NS_OK;
}

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

@ -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<nsIPresShell> 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) {

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

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

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

@ -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<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
APZCCallbackHelper::IsScrollInProgress(nsIScrollableFrame* aFrame)
{

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

@ -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<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
AdjustDisplayPortForScrollDelta(mozilla::layers::FrameMetrics& aFrameMetrics,
const CSSPoint& aActualScrollOffset);

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

@ -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<RefPtr<StyleSheet>>& aSheets)
{

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

@ -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<AccessibleCaretEventHub> GetAccessibleCaretEventHub() const override;
@ -830,6 +833,8 @@ private:
// when target of pointer event was deleted during executing user handlers.
nsCOMPtr<nsIContent> 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

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

@ -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;
/**

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

@ -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);

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

@ -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);
}
}
}
};

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

@ -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;
}
}