- Revision
- 134170
- Author
- [email protected]
- Date
- 2012-11-10 22:39:12 -0800 (Sat, 10 Nov 2012)
Log Message
Coalesce main thread scroll position updates
https://bugs.webkit.org/show_bug.cgi?id=101855
Reviewed by Anders Carlsson.
When using threaded scrolling, the dispatched updateMainFrameScrollPosition() calls
from ScrollingTree would pile up on the main thread, and we'd handle several per
runloop cycle when scrolling fast. This causes extra work especially on pages
with position:fixed elements which must update RenderLayers on scrolling.
Fix by using a zero-delay timer in ScrollingCoordinator to coalesce these
scrolling updates to one per runloop.
* page/scrolling/ScrollingCoordinator.cpp:
(WebCore::ScrollingCoordinator::ScrollingCoordinator): Initialized data members
for the scheduled scroll position update.
(WebCore::ScrollingCoordinator::scheduleUpdateMainFrameScrollPosition): If
the timer is active and the parameters match, just update the target scroll
position and return. If the params don't match, dispatch the scheduled update,
and then the new one. Otherwise, prime the timer.
(WebCore::ScrollingCoordinator::updateMainFrameScrollPositionTimerFired): Call
the existing updateMainFrameScrollPosition() with the saved values.
* page/scrolling/ScrollingCoordinator.h:
* page/scrolling/ScrollingTree.cpp:
(WebCore::ScrollingTree::updateMainFrameScrollPosition): Call scheduleUpdateMainFrameScrollPosition()
rather than updateMainFrameScrollPosition().
* page/scrolling/mac/ScrollingCoordinatorMac.mm:
(WebCore::ScrollingCoordinatorMac::syncChildPositions): Fixed a bug that caused fixed
position elements to jiggle with the patch; we should be calling syncPosition() (which just
sets the position data, without touching CA layers).
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (134169 => 134170)
--- trunk/Source/WebCore/ChangeLog 2012-11-11 05:21:04 UTC (rev 134169)
+++ trunk/Source/WebCore/ChangeLog 2012-11-11 06:39:12 UTC (rev 134170)
@@ -1,5 +1,38 @@
2012-11-10 Simon Fraser <[email protected]>
+ Coalesce main thread scroll position updates
+ https://bugs.webkit.org/show_bug.cgi?id=101855
+
+ Reviewed by Anders Carlsson.
+
+ When using threaded scrolling, the dispatched updateMainFrameScrollPosition() calls
+ from ScrollingTree would pile up on the main thread, and we'd handle several per
+ runloop cycle when scrolling fast. This causes extra work especially on pages
+ with position:fixed elements which must update RenderLayers on scrolling.
+
+ Fix by using a zero-delay timer in ScrollingCoordinator to coalesce these
+ scrolling updates to one per runloop.
+
+ * page/scrolling/ScrollingCoordinator.cpp:
+ (WebCore::ScrollingCoordinator::ScrollingCoordinator): Initialized data members
+ for the scheduled scroll position update.
+ (WebCore::ScrollingCoordinator::scheduleUpdateMainFrameScrollPosition): If
+ the timer is active and the parameters match, just update the target scroll
+ position and return. If the params don't match, dispatch the scheduled update,
+ and then the new one. Otherwise, prime the timer.
+ (WebCore::ScrollingCoordinator::updateMainFrameScrollPositionTimerFired): Call
+ the existing updateMainFrameScrollPosition() with the saved values.
+ * page/scrolling/ScrollingCoordinator.h:
+ * page/scrolling/ScrollingTree.cpp:
+ (WebCore::ScrollingTree::updateMainFrameScrollPosition): Call scheduleUpdateMainFrameScrollPosition()
+ rather than updateMainFrameScrollPosition().
+ * page/scrolling/mac/ScrollingCoordinatorMac.mm:
+ (WebCore::ScrollingCoordinatorMac::syncChildPositions): Fixed a bug that caused fixed
+ position elements to jiggle with the patch; we should be calling syncPosition() (which just
+ sets the position data, without touching CA layers).
+
+2012-11-10 Simon Fraser <[email protected]>
+
Remove ScrollingCoordinatorMac::updateMainFrameScrollPositionAndScrollLayerPosition()
https://bugs.webkit.org/show_bug.cgi?id=101514
Modified: trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp (134169 => 134170)
--- trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp 2012-11-11 05:21:04 UTC (rev 134169)
+++ trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp 2012-11-11 06:39:12 UTC (rev 134170)
@@ -101,6 +101,9 @@
ScrollingCoordinator::ScrollingCoordinator(Page* page)
: m_page(page)
+ , m_updateMainFrameScrollPositionTimer(this, &ScrollingCoordinator::updateMainFrameScrollPositionTimerFired)
+ , m_scheduledUpdateIsProgrammaticScroll(false)
+ , m_scheduledScrollingLayerPositionAction(SyncScrollingLayerPosition)
, m_forceMainThreadScrollLayerPositionUpdates(false)
{
}
@@ -250,6 +253,33 @@
updateShouldUpdateScrollLayerPositionOnMainThread();
}
+void ScrollingCoordinator::scheduleUpdateMainFrameScrollPosition(const IntPoint& scrollPosition, bool programmaticScroll, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
+{
+ if (m_updateMainFrameScrollPositionTimer.isActive()) {
+ if (m_scheduledUpdateIsProgrammaticScroll == programmaticScroll
+ && m_scheduledScrollingLayerPositionAction == scrollingLayerPositionAction) {
+ m_scheduledUpdateScrollPosition = scrollPosition;
+ return;
+ }
+
+ // If the parameters don't match what was previosly scheduled, dispatch immediately.
+ m_updateMainFrameScrollPositionTimer.stop();
+ updateMainFrameScrollPosition(m_scheduledUpdateScrollPosition, m_scheduledUpdateIsProgrammaticScroll, m_scheduledScrollingLayerPositionAction);
+ updateMainFrameScrollPosition(scrollPosition, programmaticScroll, scrollingLayerPositionAction);
+ return;
+ }
+
+ m_scheduledUpdateScrollPosition = scrollPosition;
+ m_scheduledUpdateIsProgrammaticScroll = programmaticScroll;
+ m_scheduledScrollingLayerPositionAction = scrollingLayerPositionAction;
+ m_updateMainFrameScrollPositionTimer.startOneShot(0);
+}
+
+void ScrollingCoordinator::updateMainFrameScrollPositionTimerFired(Timer<ScrollingCoordinator>*)
+{
+ updateMainFrameScrollPosition(m_scheduledUpdateScrollPosition, m_scheduledUpdateIsProgrammaticScroll, m_scheduledScrollingLayerPositionAction);
+}
+
void ScrollingCoordinator::updateMainFrameScrollPosition(const IntPoint& scrollPosition, bool programmaticScroll, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
{
ASSERT(isMainThread());
Modified: trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h (134169 => 134170)
--- trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h 2012-11-11 05:21:04 UTC (rev 134169)
+++ trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h 2012-11-11 06:39:12 UTC (rev 134170)
@@ -128,6 +128,7 @@
ScrollingNodeID uniqueScrollLayerID();
// Dispatched by the scrolling tree whenever the main frame scroll position changes.
+ void scheduleUpdateMainFrameScrollPosition(const IntPoint&, bool programmaticScroll, SetOrSyncScrollingLayerPosition);
void updateMainFrameScrollPosition(const IntPoint&, bool programmaticScroll, SetOrSyncScrollingLayerPosition);
enum MainThreadScrollingReasonFlags {
@@ -164,7 +165,14 @@
virtual bool hasVisibleSlowRepaintFixedObjects(FrameView*) const;
void updateShouldUpdateScrollLayerPositionOnMainThread();
+
+ void updateMainFrameScrollPositionTimerFired(Timer<ScrollingCoordinator>*);
+ Timer<ScrollingCoordinator> m_updateMainFrameScrollPositionTimer;
+ IntPoint m_scheduledUpdateScrollPosition;
+ bool m_scheduledUpdateIsProgrammaticScroll;
+ SetOrSyncScrollingLayerPosition m_scheduledScrollingLayerPositionAction;
+
bool m_forceMainThreadScrollLayerPositionUpdates;
};
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp (134169 => 134170)
--- trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2012-11-11 05:21:04 UTC (rev 134169)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2012-11-11 06:39:12 UTC (rev 134170)
@@ -224,7 +224,7 @@
m_mainFrameScrollPosition = scrollPosition;
}
- callOnMainThread(bind(&ScrollingCoordinator::updateMainFrameScrollPosition, m_scrollingCoordinator.get(), scrollPosition, m_isHandlingProgrammaticScroll, scrollingLayerPositionAction));
+ callOnMainThread(bind(&ScrollingCoordinator::scheduleUpdateMainFrameScrollPosition, m_scrollingCoordinator.get(), scrollPosition, m_isHandlingProgrammaticScroll, scrollingLayerPositionAction));
}
IntPoint ScrollingTree::mainFrameScrollPosition()
Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm (134169 => 134170)
--- trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm 2012-11-11 05:21:04 UTC (rev 134169)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm 2012-11-11 06:39:12 UTC (rev 134170)
@@ -373,7 +373,7 @@
for (size_t i = 0; i < size; ++i) {
ScrollingStateFixedNode* child = toScrollingStateFixedNode(children->at(i).get());
FloatPoint position = child->viewportConstraints().layerPositionForViewportRect(viewportRect);
- child->graphicsLayer()->setPosition(position);
+ child->graphicsLayer()->syncPosition(position);
}
}