Bug 1241371. Don't schedule an image visibility update every time display port margins change. r=kats

Displayport margins change by small amounts on almost every single scroll. We do not want to update image visibility nearly that often.

As the comment, and the original bug (bug 1169881) suggest this is only meant to catch rather large changes in display ports as we already have means to trigger an image visibility update via a scroll position change and via any style or layout flush.
This commit is contained in:
Timothy Nikkel 2016-01-22 00:29:17 -06:00
Родитель 2e3da0d24d
Коммит 6a8edbd624
4 изменённых файлов: 68 добавлений и 2 удалений

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

@ -1176,8 +1176,45 @@ nsLayoutUtils::SetDisplayPortMargins(nsIContent* aContent,
}
// Display port margins changing means that the set of visible images may
// have drastically changed. Schedule an update.
aPresShell->ScheduleImageVisibilityUpdate();
// have drastically changed. Check if we should schedule an update.
nsIFrame* frame = GetScrollFrameFromContent(aContent);
nsIScrollableFrame* scrollableFrame = frame ? frame->GetScrollTargetFrame() : nullptr;
if (!scrollableFrame) {
return true;
}
nsRect oldDisplayPort;
bool hadDisplayPort =
scrollableFrame->GetDisplayPortAtLastImageVisibilityUpdate(&oldDisplayPort);
nsRect newDisplayPort;
Unused << GetDisplayPort(aContent, &newDisplayPort);
bool needImageVisibilityUpdate = !hadDisplayPort;
// Check if the total size has changed by a large factor.
if (!needImageVisibilityUpdate) {
if ((newDisplayPort.width > 2 * oldDisplayPort.width) ||
(oldDisplayPort.width > 2 * newDisplayPort.width) ||
(newDisplayPort.height > 2 * oldDisplayPort.height) ||
(oldDisplayPort.height > 2 * newDisplayPort.height)) {
needImageVisibilityUpdate = true;
}
}
// Check if it's moved by a significant amount.
if (!needImageVisibilityUpdate) {
if (nsRect* baseData = static_cast<nsRect*>(aContent->GetProperty(nsGkAtoms::DisplayPortBase))) {
nsRect base = *baseData;
if ((std::abs(newDisplayPort.X() - oldDisplayPort.X()) > base.width) ||
(std::abs(newDisplayPort.XMost() - oldDisplayPort.XMost()) > base.width) ||
(std::abs(newDisplayPort.Y() - oldDisplayPort.Y()) > base.height) ||
(std::abs(newDisplayPort.YMost() - oldDisplayPort.YMost()) > base.height)) {
needImageVisibilityUpdate = true;
}
}
}
if (needImageVisibilityUpdate) {
aPresShell->ScheduleImageVisibilityUpdate();
}
return true;
}

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

@ -1839,6 +1839,8 @@ ScrollFrameHelper::ScrollFrameHelper(nsContainerFrame* aOuter,
, mLastPos(-1, -1)
, mScrollPosForLayerPixelAlignment(-1, -1)
, mLastUpdateImagesPos(-1, -1)
, mHadDisplayPortAtLastImageUpdate(false)
, mDisplayPortAtLastImageUpdate()
, mNeverHasVerticalScrollbar(false)
, mNeverHasHorizontalScrollbar(false)
, mHasVerticalScrollbar(false)
@ -2478,6 +2480,17 @@ void
ScrollFrameHelper::NotifyImageVisibilityUpdate()
{
mLastUpdateImagesPos = GetScrollPosition();
mHadDisplayPortAtLastImageUpdate =
nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), &mDisplayPortAtLastImageUpdate);
}
bool
ScrollFrameHelper::GetDisplayPortAtLastImageVisibilityUpdate(nsRect* aDisplayPort)
{
if (mHadDisplayPortAtLastImageUpdate) {
*aDisplayPort = mDisplayPortAtLastImageUpdate;
}
return mHadDisplayPortAtLastImageUpdate;
}
void

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

@ -368,6 +368,7 @@ public:
nsRect* aDirtyRect,
bool aAllowCreateDisplayPort);
void NotifyImageVisibilityUpdate();
bool GetDisplayPortAtLastImageVisibilityUpdate(nsRect* aDisplayPort);
void ScheduleSyntheticMouseMove();
static void ScrollActivityCallback(nsITimer *aTimer, void* anInstance);
@ -460,6 +461,8 @@ public:
// The scroll position where we last updated image visibility.
nsPoint mLastUpdateImagesPos;
bool mHadDisplayPortAtLastImageUpdate;
nsRect mDisplayPortAtLastImageUpdate;
nsRect mPrevScrolledRect;
@ -853,6 +856,9 @@ public:
virtual void NotifyImageVisibilityUpdate() override {
mHelper.NotifyImageVisibilityUpdate();
}
virtual bool GetDisplayPortAtLastImageVisibilityUpdate(nsRect* aDisplayPort) override {
return mHelper.GetDisplayPortAtLastImageVisibilityUpdate(aDisplayPort);
}
// nsIStatefulFrame
NS_IMETHOD SaveState(nsPresState** aState) override {
@ -1323,6 +1329,9 @@ public:
virtual void NotifyImageVisibilityUpdate() override {
mHelper.NotifyImageVisibilityUpdate();
}
virtual bool GetDisplayPortAtLastImageVisibilityUpdate(nsRect* aDisplayPort) override {
return mHelper.GetDisplayPortAtLastImageVisibilityUpdate(aDisplayPort);
}
#ifdef DEBUG_FRAME_DUMP
virtual nsresult GetFrameName(nsAString& aResult) const override;

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

@ -446,6 +446,13 @@ public:
* Notification that this scroll frame is getting its image visibility updated.
*/
virtual void NotifyImageVisibilityUpdate() = 0;
/**
* Returns true if this scroll frame had a display port at the last image
* visibility update and fills in aDisplayPort with that displayport. Returns
* false otherwise, and doesn't touch aDisplayPort.
*/
virtual bool GetDisplayPortAtLastImageVisibilityUpdate(nsRect* aDisplayPort) = 0;
};
#endif