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

This commit is contained in:
Kartikaya Gupta 2014-03-13 15:48:38 -04:00
parent ddafbb93e1
commit a9019c7fc6
3 changed files with 19 additions and 7 deletions

View File

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

View File

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

View File

@ -1552,7 +1552,7 @@ ScrollFrameHelper::ScrollFrameHelper(nsContainerFrame* aOuter,
, mOuter(aOuter) , mOuter(aOuter)
, mAsyncScroll(nullptr) , mAsyncScroll(nullptr)
, mOriginOfLastScroll(nsGkAtoms::other) , mOriginOfLastScroll(nsGkAtoms::other)
, mScrollGeneration(0) , mScrollGeneration(1) // we start off pretending we scrolled to 0,0 to flush a notification to APZ
, mDestination(0, 0) , mDestination(0, 0)
, mScrollPosAtLastPaint(0, 0) , mScrollPosAtLastPaint(0, 0)
, mRestorePos(-1, -1) , mRestorePos(-1, -1)