Title: [134170] trunk/Source/WebCore
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);
     }
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to