Bug 980679 - Filter redundant scroll offset updates by scroll generation value. r=botond,tn

This commit is contained in:
Kartikaya Gupta 2014-03-28 08:21:19 -04:00
parent 05dcbf9506
commit ced251bb3e
3 changed files with 28 additions and 8 deletions

View File

@ -210,6 +210,12 @@ public:
mZoom.scale *= aFactor;
}
void CopyScrollInfoFrom(const FrameMetrics& aOther)
{
mScrollOffset = aOther.mScrollOffset;
mScrollGeneration = aOther.mScrollGeneration;
}
// ---------------------------------------------------------------------------
// The following metrics are all in widget space/device pixels.
//

View File

@ -67,7 +67,7 @@
#define APZC_LOG_FM(fm, prefix, ...) \
APZC_LOG(prefix ":" \
" i=(%ld %lld) cb=(%d %d %d %d) rcs=(%.3f %.3f) dp=(%.3f %.3f %.3f %.3f) dpm=(%.3f %.3f %.3f %.3f) um=%d " \
"v=(%.3f %.3f %.3f %.3f) s=(%.3f %.3f) sr=(%.3f %.3f %.3f %.3f) z=(%.3f %.3f %.3f %.3f) u=(%d %llu)\n", \
"v=(%.3f %.3f %.3f %.3f) s=(%.3f %.3f) sr=(%.3f %.3f %.3f %.3f) z=(%.3f %.3f %.3f %.3f) u=(%d %lu)\n", \
__VA_ARGS__, \
fm.mPresShellId, fm.GetScrollId(), \
fm.mCompositionBounds.x, fm.mCompositionBounds.y, fm.mCompositionBounds.width, fm.mCompositionBounds.height, \
@ -1745,6 +1745,13 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
mFrameMetrics.mViewport = aLayerMetrics.mViewport;
}
// If the layers update was not triggered by our own repaint request, then
// we want to take the new scroll offset. Check the scroll generation as well
// to filter duplicate calls to NotifyLayersUpdated with the same scroll offset
// update message.
bool scrollOffsetUpdated = aLayerMetrics.GetScrollOffsetUpdated()
&& (aLayerMetrics.GetScrollGeneration() != mFrameMetrics.GetScrollGeneration());
if (aIsFirstPaint || isDefault) {
// Initialize our internal state to something sane when the content
// that was just painted is something we knew nothing about previously
@ -1781,14 +1788,12 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
mFrameMetrics.mCumulativeResolution = aLayerMetrics.mCumulativeResolution;
mFrameMetrics.mHasScrollgrab = aLayerMetrics.mHasScrollgrab;
// If the layers update was not triggered by our own repaint request, then
// we want to take the new scroll offset.
if (aLayerMetrics.GetScrollOffsetUpdated()) {
if (scrollOffsetUpdated) {
APZC_LOG("%p updating scroll offset from (%f, %f) to (%f, %f)\n", this,
mFrameMetrics.GetScrollOffset().x, mFrameMetrics.GetScrollOffset().y,
aLayerMetrics.GetScrollOffset().x, aLayerMetrics.GetScrollOffset().y);
mFrameMetrics.SetScrollOffset(aLayerMetrics.GetScrollOffset());
mFrameMetrics.CopyScrollInfoFrom(aLayerMetrics);
// Because of the scroll offset update, any inflight paint requests are
// going to be ignored by layout, and so mLastDispatchedPaintMetrics
@ -1799,13 +1804,14 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
}
}
if (aLayerMetrics.GetScrollOffsetUpdated()) {
if (scrollOffsetUpdated) {
// Once layout issues a scroll offset update, it becomes impervious to
// scroll offset updates from APZ until we acknowledge the update it sent.
// This prevents APZ updates from clobbering scroll updates from other
// more "legitimate" sources like content scripts.
nsRefPtr<GeckoContentController> controller = GetGeckoContentController();
if (controller) {
APZC_LOG("%p sending scroll update acknowledgement with gen %lu\n", this, aLayerMetrics.GetScrollGeneration());
controller->AcknowledgeScrollUpdate(aLayerMetrics.GetScrollId(),
aLayerMetrics.GetScrollGeneration());
}

View File

@ -1545,6 +1545,14 @@ public:
static ScrollFrameActivityTracker *gScrollFrameActivityTracker = nullptr;
// There are situations when a scroll frame is destroyed and then re-created
// for the same content element. In this case we want to increment the scroll
// generation between the old and new scrollframes. If the new one knew about
// the old one then it could steal the old generation counter and increment it
// but it doesn't have that reference so instead we use a static global to
// ensure the new one gets a fresh value.
static uint32_t sScrollGenerationCounter = 0;
ScrollFrameHelper::ScrollFrameHelper(nsContainerFrame* aOuter,
bool aIsRoot)
: mHScrollbarBox(nullptr)
@ -1555,7 +1563,7 @@ ScrollFrameHelper::ScrollFrameHelper(nsContainerFrame* aOuter,
, mOuter(aOuter)
, mAsyncScroll(nullptr)
, mOriginOfLastScroll(nsGkAtoms::other)
, mScrollGeneration(0)
, mScrollGeneration(++sScrollGenerationCounter)
, mDestination(0, 0)
, mScrollPosAtLastPaint(0, 0)
, mRestorePos(-1, -1)
@ -2071,7 +2079,7 @@ ScrollFrameHelper::ScrollToImpl(nsPoint aPt, const nsRect& aRange, nsIAtom* aOri
// Update frame position for scrolling
mScrolledFrame->SetPosition(mScrollPort.TopLeft() - pt);
mOriginOfLastScroll = aOrigin;
mScrollGeneration++;
mScrollGeneration = ++sScrollGenerationCounter;
// We pass in the amount to move visually
ScrollVisual(oldScrollFramePos);