Title: [107646] trunk/Source/WebCore
Revision
107646
Author
[email protected]
Date
2012-02-13 17:07:59 -0800 (Mon, 13 Feb 2012)

Log Message

Force slow-scrolling mode when there are position:fixed elements on a page
https://bugs.webkit.org/show_bug.cgi?id=78553
<rdar://problem/10247934>

Reviewed by Dan Bernstein.

Eventually, the scrolling tree will know about fixed positioning layers so their position can be updated
when the scroll layer position is updated. For now we'll take the simple route however.

* page/FrameView.cpp:
(WebCore::FrameView::addFixedObject):
(WebCore::FrameView::removeFixedObject):
Inform the scrolling coordinator when the number of fixed objects changes between 0 and 1.

* page/FrameView.h:
(WebCore::FrameView::hasFixedObjects):
Make this public.

* page/scrolling/ScrollingCoordinator.cpp:
(WebCore::ScrollingCoordinator::frameViewHasSlowRepaintObjectsDidChange):
Call updateShouldUpdateScrollLayerPositionOnMainThread.

(WebCore::ScrollingCoordinator::frameViewHasFixedObjectsDidChange):
Call updateShouldUpdateScrollLayerPositionOnMainThread.

(WebCore::ScrollingCoordinator::updateMainFrameScrollPositionAndScrollLayerPosition):
Make sure to update compositing layers here. Normally, they will be updated by layout but doing a layout
here is too intrusive since it could potentially change the size of the page.

(WebCore::ScrollingCoordinator::updateShouldUpdateScrollLayerPositionOnMainThread):
If we have fixed objects or slow repaint objects we need to update the scroll layer position on the main thread.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (107645 => 107646)


--- trunk/Source/WebCore/ChangeLog	2012-02-14 01:07:14 UTC (rev 107645)
+++ trunk/Source/WebCore/ChangeLog	2012-02-14 01:07:59 UTC (rev 107646)
@@ -1,3 +1,37 @@
+2012-02-13  Anders Carlsson  <[email protected]>
+
+        Force slow-scrolling mode when there are position:fixed elements on a page
+        https://bugs.webkit.org/show_bug.cgi?id=78553
+        <rdar://problem/10247934>
+
+        Reviewed by Dan Bernstein.
+
+        Eventually, the scrolling tree will know about fixed positioning layers so their position can be updated
+        when the scroll layer position is updated. For now we'll take the simple route however.
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::addFixedObject):
+        (WebCore::FrameView::removeFixedObject):
+        Inform the scrolling coordinator when the number of fixed objects changes between 0 and 1.
+
+        * page/FrameView.h:
+        (WebCore::FrameView::hasFixedObjects):
+        Make this public.
+
+        * page/scrolling/ScrollingCoordinator.cpp:
+        (WebCore::ScrollingCoordinator::frameViewHasSlowRepaintObjectsDidChange):
+        Call updateShouldUpdateScrollLayerPositionOnMainThread.
+
+        (WebCore::ScrollingCoordinator::frameViewHasFixedObjectsDidChange):
+        Call updateShouldUpdateScrollLayerPositionOnMainThread.
+
+        (WebCore::ScrollingCoordinator::updateMainFrameScrollPositionAndScrollLayerPosition):
+        Make sure to update compositing layers here. Normally, they will be updated by layout but doing a layout
+        here is too intrusive since it could potentially change the size of the page.
+
+        (WebCore::ScrollingCoordinator::updateShouldUpdateScrollLayerPositionOnMainThread):
+        If we have fixed objects or slow repaint objects we need to update the scroll layer position on the main thread.
+
 2012-02-13  Adrienne Walker  <[email protected]>
 
         [chromium] Use HashMap<..., OwnPtr<Tile>> for compositor tilemap

Modified: trunk/Source/WebCore/page/FrameView.cpp (107645 => 107646)


--- trunk/Source/WebCore/page/FrameView.cpp	2012-02-14 01:07:14 UTC (rev 107645)
+++ trunk/Source/WebCore/page/FrameView.cpp	2012-02-14 01:07:59 UTC (rev 107646)
@@ -1358,17 +1358,36 @@
 
 void FrameView::addFixedObject()
 {
-    if (!m_fixedObjectCount && platformWidget())
-        updateCanBlitOnScrollRecursively();
-    ++m_fixedObjectCount;
+    if (!m_fixedObjectCount++) {
+        if (platformWidget())
+            updateCanBlitOnScrollRecursively();
+
+#if ENABLE(THREADED_SCROLLING)
+        if (Page* page = m_frame->page()) {
+            if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
+                scrollingCoordinator->frameViewHasFixedObjectsDidChange(this);
+        }
+#endif
+    }
 }
 
 void FrameView::removeFixedObject()
 {
     ASSERT(m_fixedObjectCount > 0);
     --m_fixedObjectCount;
-    if (!m_fixedObjectCount)
+
+    if (!m_fixedObjectCount) {
+#if ENABLE(THREADED_SCROLLING)
+        if (Page* page = m_frame->page()) {
+            if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
+                scrollingCoordinator->frameViewHasFixedObjectsDidChange(this);
+        }
+#endif
+
+        // FIXME: In addFixedObject() we only call this if there's a platform widget,
+        // why isn't the same check being made here?
         updateCanBlitOnScrollRecursively();
+    }
 }
 
 int FrameView::scrollXForFixedPosition() const

Modified: trunk/Source/WebCore/page/FrameView.h (107645 => 107646)


--- trunk/Source/WebCore/page/FrameView.h	2012-02-14 01:07:14 UTC (rev 107645)
+++ trunk/Source/WebCore/page/FrameView.h	2012-02-14 01:07:59 UTC (rev 107646)
@@ -189,6 +189,7 @@
 
     void addFixedObject();
     void removeFixedObject();
+    bool hasFixedObjects() const { return m_fixedObjectCount > 0; }
 
     // Functions for querying the current scrolled position, negating the effects of overhang
     // and adjusting for page scale.
@@ -338,8 +339,6 @@
     void updateCanBlitOnScrollRecursively();
     bool contentsInCompositedLayer() const;
 
-    bool hasFixedObjects() const { return m_fixedObjectCount > 0; }
-
     void applyOverflowToViewport(RenderObject*, ScrollbarMode& hMode, ScrollbarMode& vMode);
 
     void updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow);

Modified: trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp (107645 => 107646)


--- trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp	2012-02-14 01:07:14 UTC (rev 107645)
+++ trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp	2012-02-14 01:07:59 UTC (rev 107646)
@@ -154,10 +154,20 @@
     if (!coordinatesScrollingForFrameView(frameView))
         return;
 
-    m_scrollingTreeState->setShouldUpdateScrollLayerPositionOnMainThread(frameView->hasSlowRepaintObjects());
-    scheduleTreeStateCommit();
+    updateShouldUpdateScrollLayerPositionOnMainThread();
 }
 
+void ScrollingCoordinator::frameViewHasFixedObjectsDidChange(FrameView* frameView)
+{
+    ASSERT(isMainThread());
+    ASSERT(m_page);
+
+    if (!coordinatesScrollingForFrameView(frameView))
+        return;
+
+    updateShouldUpdateScrollLayerPositionOnMainThread();
+}
+
 bool ScrollingCoordinator::requestScrollPositionUpdate(FrameView* frameView, const IntPoint& scrollPosition)
 {
     ASSERT(isMainThread());
@@ -198,6 +208,7 @@
     if (!scrollLayer)
         return;
 
+    frameView->updateCompositingLayers();
     frameView->setConstrainsScrollingToContentEdge(false);
     frameView->notifyScrollPositionChanged(scrollPosition);
     frameView->setConstrainsScrollingToContentEdge(true);
@@ -217,6 +228,17 @@
     scheduleTreeStateCommit();
 }
 
+void ScrollingCoordinator::updateShouldUpdateScrollLayerPositionOnMainThread()
+{
+    FrameView* frameView = m_page->mainFrame()->view();
+
+    // FIXME: Having fixed objects on the page should not trigger the slow path.
+    bool shouldUpdateScrollLayerPositionOnMainThread = frameView->hasSlowRepaintObjects() || frameView->hasFixedObjects();
+
+    m_scrollingTreeState->setShouldUpdateScrollLayerPositionOnMainThread(shouldUpdateScrollLayerPositionOnMainThread);
+    scheduleTreeStateCommit();
+}
+
 void ScrollingCoordinator::scheduleTreeStateCommit()
 {
     if (m_scrollingTreeStateCommitterTimer.isActive())

Modified: trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h (107645 => 107646)


--- trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h	2012-02-14 01:07:14 UTC (rev 107645)
+++ trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h	2012-02-14 01:07:59 UTC (rev 107646)
@@ -74,6 +74,12 @@
     // Should be called whenever the slow repaint objects counter changes between zero and one.
     void frameViewHasSlowRepaintObjectsDidChange(FrameView*);
 
+    // Should be called whenever the fixed objects counter changes between zero and one.
+    // FIXME: This is a temporary workaround so that we'll fall into main thread scrolling mode
+    // if a page has fixed elements. The scrolling tree should know about the fixed elements
+    // so it can make sure they stay fixed even when we scroll on the scrolling thread.
+    void frameViewHasFixedObjectsDidChange(FrameView*);
+
     // Should be called whenever the scroll layer for the given frame view changes.
     void frameViewScrollLayerDidChange(FrameView*, const GraphicsLayer*);
 
@@ -97,6 +103,7 @@
     explicit ScrollingCoordinator(Page*);
 
     void recomputeWheelEventHandlerCount();
+    void updateShouldUpdateScrollLayerPositionOnMainThread();
 
     void scheduleTreeStateCommit();
     void scrollingTreeStateCommitterTimerFired(Timer<ScrollingCoordinator>*);
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to