⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 107335 in webkit


Ignore:
Timestamp:
Feb 9, 2012, 6:10:13 PM (15 years ago)
Author:
andersca@apple.com
Message:

Update the scroll layer position on the main thread when we have slow repaint objects
https://bugs.webkit.org/show_bug.cgi?id=78300
<rdar://problem/10710754>

Reviewed by Dan Bernstein.

When we have slow repaint objects (background-attachment: fixed), we need to update the
scroll layer position on the main thread, otherwise the web page will appear to jiggle.

  • page/FrameView.cpp:

(WebCore::FrameView::addSlowRepaintObject):
(WebCore::FrameView::removeSlowRepaintObject):
Call ScrollingCoordinator::frameViewHasSlowRepaintObjectsDidChange if needed.

  • page/FrameView.h:

(WebCore::FrameView::hasSlowRepaintObjects):
Add new getter.

  • page/scrolling/ScrollingCoordinator.cpp:

(WebCore::ScrollingCoordinator::frameViewHasSlowRepaintObjectsDidChange):
Call ScrollingTreeNode::shouldUpdateScrollLayerPositionOnMainThread.

(WebCore::ScrollingCoordinator::updateMainFrameScrollPositionAndScrollLayerPosition):
New function that will update both the main frame scroll position and the scroll layer position.

  • page/scrolling/ScrollingTree.cpp:

(WebCore::ScrollingTree::updateMainFrameScrollPositionAndScrollLayerPosition):
Dispatch a call to ScrollingCoordinator::updateMainFrameScrollPositionAndScrollLayerPosition on the main thread.

  • page/scrolling/ScrollingTreeNode.cpp:

(WebCore::ScrollingTreeNode::ScrollingTreeNode):
Initialize m_shouldUpdateScrollLayerPositionOnMainThread.

(WebCore::ScrollingTreeNode::update):
Set m_shouldUpdateScrollLayerPositionOnMainThread.

  • page/scrolling/ScrollingTreeState.cpp:

(WebCore::ScrollingTreeState::ScrollingTreeState):
Initialize m_shouldUpdateScrollLayerPositionOnMainThread.

(WebCore::ScrollingTreeState::setShouldUpdateScrollLayerPositionOnMainThread):
Update m_shouldUpdateScrollLayerPositionOnMainThread if needed.

  • page/scrolling/mac/ScrollingTreeNodeMac.mm:

(WebCore::ScrollingTreeNodeMac::setScrollPosition):
Assert that we're not supposed to update the scroll layer position on the main thread.

(WebCore::ScrollingTreeNodeMac::scrollBy):
If we're supposed to update the scroll layer position on the main thread,
call ScrollingTree::updateMainFrameScrollPositionAndScrollLayerPosition.

  • rendering/RenderLayerCompositor.cpp:

(WebCore::RenderLayerCompositor::frameViewDidScroll):
If the frame view has its scrolling coordinated by a scrolling coordinator, don't update the scroll layer position.

Location:
trunk/Source/WebCore
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r107332 r107335  
     12012-02-09  Anders Carlsson  <andersca@apple.com>
     2
     3        Update the scroll layer position on the main thread when we have slow repaint objects
     4        https://bugs.webkit.org/show_bug.cgi?id=78300
     5        <rdar://problem/10710754>
     6
     7        Reviewed by Dan Bernstein.
     8
     9        When we have slow repaint objects (background-attachment: fixed), we need to update the
     10        scroll layer position on the main thread, otherwise the web page will appear to jiggle.
     11   
     12        * page/FrameView.cpp:
     13        (WebCore::FrameView::addSlowRepaintObject):
     14        (WebCore::FrameView::removeSlowRepaintObject):
     15        Call ScrollingCoordinator::frameViewHasSlowRepaintObjectsDidChange if needed.
     16
     17        * page/FrameView.h:
     18        (WebCore::FrameView::hasSlowRepaintObjects):
     19        Add new getter.
     20
     21        * page/scrolling/ScrollingCoordinator.cpp:
     22        (WebCore::ScrollingCoordinator::frameViewHasSlowRepaintObjectsDidChange):
     23        Call ScrollingTreeNode::shouldUpdateScrollLayerPositionOnMainThread.
     24
     25        (WebCore::ScrollingCoordinator::updateMainFrameScrollPositionAndScrollLayerPosition):
     26        New function that will update both the main frame scroll position and the scroll layer position.
     27
     28        * page/scrolling/ScrollingTree.cpp:
     29        (WebCore::ScrollingTree::updateMainFrameScrollPositionAndScrollLayerPosition):
     30        Dispatch a call to ScrollingCoordinator::updateMainFrameScrollPositionAndScrollLayerPosition on the main thread.
     31
     32        * page/scrolling/ScrollingTreeNode.cpp:
     33        (WebCore::ScrollingTreeNode::ScrollingTreeNode):
     34        Initialize m_shouldUpdateScrollLayerPositionOnMainThread.
     35
     36        (WebCore::ScrollingTreeNode::update):
     37        Set m_shouldUpdateScrollLayerPositionOnMainThread.
     38
     39        * page/scrolling/ScrollingTreeState.cpp:
     40        (WebCore::ScrollingTreeState::ScrollingTreeState):
     41        Initialize m_shouldUpdateScrollLayerPositionOnMainThread.
     42
     43        (WebCore::ScrollingTreeState::setShouldUpdateScrollLayerPositionOnMainThread):
     44        Update m_shouldUpdateScrollLayerPositionOnMainThread if needed.
     45
     46        * page/scrolling/mac/ScrollingTreeNodeMac.mm:
     47        (WebCore::ScrollingTreeNodeMac::setScrollPosition):
     48        Assert that we're not supposed to update the scroll layer position on the main thread.
     49
     50        (WebCore::ScrollingTreeNodeMac::scrollBy):
     51        If we're supposed to update the scroll layer position on the main thread,
     52        call ScrollingTree::updateMainFrameScrollPositionAndScrollLayerPosition.
     53
     54        * rendering/RenderLayerCompositor.cpp:
     55        (WebCore::RenderLayerCompositor::frameViewDidScroll):
     56        If the frame view has its scrolling coordinated by a scrolling coordinator, don't update the scroll layer position.
     57
    1582012-02-09  Anders Carlsson  <andersca@apple.com>
    259
  • trunk/Source/WebCore/page/FrameView.cpp

    r107332 r107335  
    13291329void FrameView::addSlowRepaintObject()
    13301330{
    1331     if (!m_slowRepaintObjectCount++)
     1331    if (!m_slowRepaintObjectCount++) {
    13321332        updateCanBlitOnScrollRecursively();
     1333
     1334#if ENABLE(THREADED_SCROLLING)
     1335        if (Page* page = m_frame->page()) {
     1336            if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
     1337                scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(this);
     1338        }
     1339#endif
     1340    }
    13331341}
    13341342
     
    13371345    ASSERT(m_slowRepaintObjectCount > 0);
    13381346    m_slowRepaintObjectCount--;
    1339     if (!m_slowRepaintObjectCount)
     1347    if (!m_slowRepaintObjectCount) {
    13401348        updateCanBlitOnScrollRecursively();
     1349
     1350#if ENABLE(THREADED_SCROLLING)
     1351        if (Page* page = m_frame->page()) {
     1352            if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
     1353                scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(this);
     1354        }
     1355#endif
     1356    }
    13411357}
    13421358
  • trunk/Source/WebCore/page/FrameView.h

    r107168 r107335  
    185185    void addSlowRepaintObject();
    186186    void removeSlowRepaintObject();
     187    bool hasSlowRepaintObjects() const { return m_slowRepaintObjectCount; }
    187188
    188189    void addFixedObject();
  • trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp

    r107277 r107335  
    3636#include "PlatformWheelEvent.h"
    3737#include "Region.h"
     38#include "RenderLayerCompositor.h"
     39#include "RenderView.h"
    3840#include "ScrollAnimator.h"
    3941#include "ScrollingThread.h"
     
    135137}
    136138
     139void ScrollingCoordinator::frameViewHasSlowRepaintObjectsDidChange(FrameView* frameView)
     140{
     141    ASSERT(isMainThread());
     142    ASSERT(m_page);
     143
     144    if (!coordinatesScrollingForFrameView(frameView))
     145        return;
     146
     147    m_scrollingTreeState->setShouldUpdateScrollLayerPositionOnMainThread(frameView->hasSlowRepaintObjects());
     148    scheduleTreeStateCommit();
     149}
     150
    137151void ScrollingCoordinator::updateMainFrameScrollPosition(const IntPoint& scrollPosition)
    138152{
     
    149163    frameView->scrollToOffsetWithoutAnimation(scrollPosition);
    150164    frameView->setConstrainsScrollingToContentEdge(true);
     165}
     166
     167void ScrollingCoordinator::updateMainFrameScrollPositionAndScrollLayerPosition(const IntPoint& scrollPosition)
     168{
     169    FrameView* frameView = m_page->mainFrame()->view();
     170
     171    RenderView* renderView = m_page->mainFrame()->contentRenderer();
     172    if (!renderView)
     173        return;
     174
     175    GraphicsLayer* scrollLayer = renderView->compositor()->scrollLayer();
     176    if (!scrollLayer)
     177        return;
     178
     179    frameView->setConstrainsScrollingToContentEdge(false);
     180    frameView->scrollToOffsetWithoutAnimation(scrollPosition);
     181    frameView->setConstrainsScrollingToContentEdge(true);
     182
     183    scrollLayer->setPosition(-frameView->scrollPosition());
    151184}
    152185
  • trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h

    r106766 r107335  
    7272    void frameViewWheelEventHandlerCountChanged(FrameView*);
    7373
     74    // Should be called whenever the slow repaint objects counter changes between zero and one.
     75    void frameViewHasSlowRepaintObjectsDidChange(FrameView*);
     76
    7477    // Should be called whenever the scroll layer for the given frame view changes.
    7578    void frameViewScrollLayerDidChange(FrameView*, const GraphicsLayer*);
     
    8386    // Dispatched by the scrolling tree whenever the main frame scroll position changes.
    8487    void updateMainFrameScrollPosition(const IntPoint&);
     88
     89    // Dispatched by the scrolling tree whenever the main frame scroll position changes and the scroll layer position needs to be updated as well.
     90    void updateMainFrameScrollPositionAndScrollLayerPosition(const IntPoint&);
    8591
    8692private:
  • trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp

    r107013 r107335  
    121121}
    122122
     123void ScrollingTree::updateMainFrameScrollPositionAndScrollLayerPosition(const IntPoint& scrollPosition)
     124{
     125    if (!m_scrollingCoordinator)
     126        return;
     127
     128    {
     129        MutexLocker lock(m_mutex);
     130        m_mainFrameScrollPosition = scrollPosition;
     131    }
     132
     133    callOnMainThread(bind(&ScrollingCoordinator::updateMainFrameScrollPositionAndScrollLayerPosition, m_scrollingCoordinator.get(), scrollPosition));
     134}
     135
    123136} // namespace WebCore
    124137
  • trunk/Source/WebCore/page/scrolling/ScrollingTree.h

    r107013 r107335  
    6565
    6666    void updateMainFrameScrollPosition(const IntPoint& scrollPosition);
     67    void updateMainFrameScrollPositionAndScrollLayerPosition(const IntPoint& scrollPosition);
    6768
    6869private:
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp

    r107277 r107335  
    3535ScrollingTreeNode::ScrollingTreeNode(ScrollingTree* scrollingTree)
    3636    : m_scrollingTree(scrollingTree)
     37    , m_shouldUpdateScrollLayerPositionOnMainThread(false)
    3738    , m_horizontalScrollElasticity(ScrollElasticityNone)
    3839    , m_verticalScrollElasticity(ScrollElasticityNone)
     
    5455        m_contentsSize = state->contentsSize();
    5556
     57    if (state->changedProperties() & ScrollingTreeState::ShouldUpdateScrollLayerPositionOnMainThread)
     58        m_shouldUpdateScrollLayerPositionOnMainThread = state->shouldUpdateScrollLayerPositionOnMainThread();
     59
    5660    if (state->changedProperties() & ScrollingTreeState::HorizontalScrollElasticity)
    5761        m_horizontalScrollElasticity = state->horizontalScrollElasticity();
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.h

    r107277 r107335  
    5353    const IntRect& viewportRect() const { return m_viewportRect; }
    5454    const IntSize& contentsSize() const { return m_contentsSize; }
     55    bool shouldUpdateScrollLayerPositionOnMainThread() const { return m_shouldUpdateScrollLayerPositionOnMainThread; }
    5556
    5657private:
     
    5960    IntRect m_viewportRect;
    6061    IntSize m_contentsSize;
     62
     63    bool m_shouldUpdateScrollLayerPositionOnMainThread;
    6164
    6265    ScrollElasticity m_horizontalScrollElasticity;
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeState.cpp

    r107277 r107335  
    3939    : m_changedProperties(0)
    4040    , m_wheelEventHandlerCount(0)
     41    , m_shouldUpdateScrollLayerPositionOnMainThread(false)
    4142    , m_horizontalScrollElasticity(ScrollElasticityNone)
    4243    , m_verticalScrollElasticity(ScrollElasticityNone)
     
    8485    m_wheelEventHandlerCount = wheelEventHandlerCount;
    8586    m_changedProperties |= WheelEventHandlerCount;
     87}
     88
     89void ScrollingTreeState::setShouldUpdateScrollLayerPositionOnMainThread(bool shouldUpdateScrollLayerPositionOnMainThread)
     90{
     91    if (m_shouldUpdateScrollLayerPositionOnMainThread == shouldUpdateScrollLayerPositionOnMainThread)
     92        return;
     93
     94    m_shouldUpdateScrollLayerPositionOnMainThread = shouldUpdateScrollLayerPositionOnMainThread;
     95    m_changedProperties |= ShouldUpdateScrollLayerPositionOnMainThread;
    8696}
    8797
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeState.h

    r107277 r107335  
    5555        NonFastScrollableRegion = 1 << 2,
    5656        WheelEventHandlerCount = 1 << 3,
    57         HorizontalScrollElasticity = 1 << 4,
    58         VerticalScrollElasticity = 1 << 5,
    59         HasEnabledHorizontalScrollbar = 1 << 6,
    60         HasEnabledVerticalScrollbar = 1 << 7,
    61         ScrollLayer = 1 << 8,
     57        ShouldUpdateScrollLayerPositionOnMainThread = 1 << 4,
     58        HorizontalScrollElasticity = 1 << 5,
     59        VerticalScrollElasticity = 1 << 6,
     60        HasEnabledHorizontalScrollbar = 1 << 7,
     61        HasEnabledVerticalScrollbar = 1 << 8,
     62        ScrollLayer = 1 << 9,
    6263    };
    6364
     
    7677    unsigned wheelEventHandlerCount() const { return m_wheelEventHandlerCount; }
    7778    void setWheelEventHandlerCount(unsigned);
     79
     80    bool shouldUpdateScrollLayerPositionOnMainThread() const { return m_shouldUpdateScrollLayerPositionOnMainThread; }
     81    void setShouldUpdateScrollLayerPositionOnMainThread(bool);
    7882
    7983    ScrollElasticity horizontalScrollElasticity() const { return m_horizontalScrollElasticity; }
     
    107111    unsigned m_wheelEventHandlerCount;
    108112
     113    bool m_shouldUpdateScrollLayerPositionOnMainThread;
     114
    109115    ScrollElasticity m_horizontalScrollElasticity;
    110116    ScrollElasticity m_verticalScrollElasticity;
  • trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeNodeMac.mm

    r107285 r107335  
    135135void ScrollingTreeNodeMac::setScrollPosition(const IntPoint& position)
    136136{
     137    ASSERT(!shouldUpdateScrollLayerPositionOnMainThread());
     138
    137139    m_scrollLayer.get().position = CGPointMake(-position.x(), -position.y());
    138140}
    139141
    140 void ScrollingTreeNodeMac::scrollBy(const IntSize &offset)
     142void ScrollingTreeNodeMac::scrollBy(const IntSize& offset)
    141143{
    142     setScrollPosition(scrollPosition() + offset);
     144    IntPoint newScrollPosition = scrollPosition() + offset;
    143145
    144     scrollingTree()->updateMainFrameScrollPosition(scrollPosition());
     146    if (shouldUpdateScrollLayerPositionOnMainThread()) {
     147        scrollingTree()->updateMainFrameScrollPositionAndScrollLayerPosition(newScrollPosition);
     148        return;
     149    }
     150
     151    setScrollPosition(newScrollPosition);
     152    scrollingTree()->updateMainFrameScrollPosition(newScrollPosition);
    145153}
    146154
  • trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp

    r107296 r107335  
    984984        backing->graphicsLayer()->visibleRectChanged();
    985985
    986     if (m_scrollLayer)
    987         m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y()));
     986    if (!m_scrollLayer)
     987        return;
     988
     989#if ENABLE(THREADED_SCROLLING)
     990    // If there's a scrolling coordinator that manages scrolling for this frame view,
     991    // it will also manage updating the scroll layer position.
     992    if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
     993        if (scrollingCoordinator->coordinatesScrollingForFrameView(frameView))
     994            return;
     995    }
     996#endif
     997
     998    m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y()));
    988999}
    9891000
Note: See TracChangeset for help on using the changeset viewer.