Diff
Modified: trunk/Source/WebCore/ChangeLog (107334 => 107335)
--- trunk/Source/WebCore/ChangeLog 2012-02-10 01:58:36 UTC (rev 107334)
+++ trunk/Source/WebCore/ChangeLog 2012-02-10 02:10:13 UTC (rev 107335)
@@ -1,5 +1,62 @@
2012-02-09 Anders Carlsson <[email protected]>
+ 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.
+
+2012-02-09 Anders Carlsson <[email protected]>
+
FrameView::addSlowRepaintObject() doesn't update m_canBlitOnScroll correctly
https://bugs.webkit.org/show_bug.cgi?id=78291
Modified: trunk/Source/WebCore/page/FrameView.cpp (107334 => 107335)
--- trunk/Source/WebCore/page/FrameView.cpp 2012-02-10 01:58:36 UTC (rev 107334)
+++ trunk/Source/WebCore/page/FrameView.cpp 2012-02-10 02:10:13 UTC (rev 107335)
@@ -1328,16 +1328,32 @@
void FrameView::addSlowRepaintObject()
{
- if (!m_slowRepaintObjectCount++)
+ if (!m_slowRepaintObjectCount++) {
updateCanBlitOnScrollRecursively();
+
+#if ENABLE(THREADED_SCROLLING)
+ if (Page* page = m_frame->page()) {
+ if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
+ scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(this);
+ }
+#endif
+ }
}
void FrameView::removeSlowRepaintObject()
{
ASSERT(m_slowRepaintObjectCount > 0);
m_slowRepaintObjectCount--;
- if (!m_slowRepaintObjectCount)
+ if (!m_slowRepaintObjectCount) {
updateCanBlitOnScrollRecursively();
+
+#if ENABLE(THREADED_SCROLLING)
+ if (Page* page = m_frame->page()) {
+ if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
+ scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(this);
+ }
+#endif
+ }
}
void FrameView::addFixedObject()
Modified: trunk/Source/WebCore/page/FrameView.h (107334 => 107335)
--- trunk/Source/WebCore/page/FrameView.h 2012-02-10 01:58:36 UTC (rev 107334)
+++ trunk/Source/WebCore/page/FrameView.h 2012-02-10 02:10:13 UTC (rev 107335)
@@ -184,6 +184,7 @@
void addSlowRepaintObject();
void removeSlowRepaintObject();
+ bool hasSlowRepaintObjects() const { return m_slowRepaintObjectCount; }
void addFixedObject();
void removeFixedObject();
Modified: trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp (107334 => 107335)
--- trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp 2012-02-10 01:58:36 UTC (rev 107334)
+++ trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp 2012-02-10 02:10:13 UTC (rev 107335)
@@ -35,6 +35,8 @@
#include "Page.h"
#include "PlatformWheelEvent.h"
#include "Region.h"
+#include "RenderLayerCompositor.h"
+#include "RenderView.h"
#include "ScrollAnimator.h"
#include "ScrollingThread.h"
#include "ScrollingTree.h"
@@ -134,6 +136,18 @@
recomputeWheelEventHandlerCount();
}
+void ScrollingCoordinator::frameViewHasSlowRepaintObjectsDidChange(FrameView* frameView)
+{
+ ASSERT(isMainThread());
+ ASSERT(m_page);
+
+ if (!coordinatesScrollingForFrameView(frameView))
+ return;
+
+ m_scrollingTreeState->setShouldUpdateScrollLayerPositionOnMainThread(frameView->hasSlowRepaintObjects());
+ scheduleTreeStateCommit();
+}
+
void ScrollingCoordinator::updateMainFrameScrollPosition(const IntPoint& scrollPosition)
{
ASSERT(isMainThread());
@@ -150,6 +164,25 @@
frameView->setConstrainsScrollingToContentEdge(true);
}
+void ScrollingCoordinator::updateMainFrameScrollPositionAndScrollLayerPosition(const IntPoint& scrollPosition)
+{
+ FrameView* frameView = m_page->mainFrame()->view();
+
+ RenderView* renderView = m_page->mainFrame()->contentRenderer();
+ if (!renderView)
+ return;
+
+ GraphicsLayer* scrollLayer = renderView->compositor()->scrollLayer();
+ if (!scrollLayer)
+ return;
+
+ frameView->setConstrainsScrollingToContentEdge(false);
+ frameView->scrollToOffsetWithoutAnimation(scrollPosition);
+ frameView->setConstrainsScrollingToContentEdge(true);
+
+ scrollLayer->setPosition(-frameView->scrollPosition());
+}
+
void ScrollingCoordinator::recomputeWheelEventHandlerCount()
{
unsigned wheelEventHandlerCount = 0;
Modified: trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h (107334 => 107335)
--- trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h 2012-02-10 01:58:36 UTC (rev 107334)
+++ trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h 2012-02-10 02:10:13 UTC (rev 107335)
@@ -71,6 +71,9 @@
// frame view's underlying document.
void frameViewWheelEventHandlerCountChanged(FrameView*);
+ // Should be called whenever the slow repaint objects counter changes between zero and one.
+ void frameViewHasSlowRepaintObjectsDidChange(FrameView*);
+
// Should be called whenever the scroll layer for the given frame view changes.
void frameViewScrollLayerDidChange(FrameView*, const GraphicsLayer*);
@@ -83,6 +86,9 @@
// Dispatched by the scrolling tree whenever the main frame scroll position changes.
void updateMainFrameScrollPosition(const IntPoint&);
+ // Dispatched by the scrolling tree whenever the main frame scroll position changes and the scroll layer position needs to be updated as well.
+ void updateMainFrameScrollPositionAndScrollLayerPosition(const IntPoint&);
+
private:
explicit ScrollingCoordinator(Page*);
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp (107334 => 107335)
--- trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2012-02-10 01:58:36 UTC (rev 107334)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2012-02-10 02:10:13 UTC (rev 107335)
@@ -120,6 +120,19 @@
callOnMainThread(bind(&ScrollingCoordinator::updateMainFrameScrollPosition, m_scrollingCoordinator.get(), scrollPosition));
}
+void ScrollingTree::updateMainFrameScrollPositionAndScrollLayerPosition(const IntPoint& scrollPosition)
+{
+ if (!m_scrollingCoordinator)
+ return;
+
+ {
+ MutexLocker lock(m_mutex);
+ m_mainFrameScrollPosition = scrollPosition;
+ }
+
+ callOnMainThread(bind(&ScrollingCoordinator::updateMainFrameScrollPositionAndScrollLayerPosition, m_scrollingCoordinator.get(), scrollPosition));
+}
+
} // namespace WebCore
#endif // ENABLE(THREADED_SCROLLING)
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.h (107334 => 107335)
--- trunk/Source/WebCore/page/scrolling/ScrollingTree.h 2012-02-10 01:58:36 UTC (rev 107334)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.h 2012-02-10 02:10:13 UTC (rev 107335)
@@ -64,6 +64,7 @@
void commitNewTreeState(PassOwnPtr<ScrollingTreeState>);
void updateMainFrameScrollPosition(const IntPoint& scrollPosition);
+ void updateMainFrameScrollPositionAndScrollLayerPosition(const IntPoint& scrollPosition);
private:
explicit ScrollingTree(ScrollingCoordinator*);
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp (107334 => 107335)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp 2012-02-10 01:58:36 UTC (rev 107334)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp 2012-02-10 02:10:13 UTC (rev 107335)
@@ -34,6 +34,7 @@
ScrollingTreeNode::ScrollingTreeNode(ScrollingTree* scrollingTree)
: m_scrollingTree(scrollingTree)
+ , m_shouldUpdateScrollLayerPositionOnMainThread(false)
, m_horizontalScrollElasticity(ScrollElasticityNone)
, m_verticalScrollElasticity(ScrollElasticityNone)
, m_hasEnabledHorizontalScrollbar(false)
@@ -53,6 +54,9 @@
if (state->changedProperties() & ScrollingTreeState::ContentsSize)
m_contentsSize = state->contentsSize();
+ if (state->changedProperties() & ScrollingTreeState::ShouldUpdateScrollLayerPositionOnMainThread)
+ m_shouldUpdateScrollLayerPositionOnMainThread = state->shouldUpdateScrollLayerPositionOnMainThread();
+
if (state->changedProperties() & ScrollingTreeState::HorizontalScrollElasticity)
m_horizontalScrollElasticity = state->horizontalScrollElasticity();
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.h (107334 => 107335)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.h 2012-02-10 01:58:36 UTC (rev 107334)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.h 2012-02-10 02:10:13 UTC (rev 107335)
@@ -52,6 +52,7 @@
ScrollingTree* scrollingTree() const { return m_scrollingTree; }
const IntRect& viewportRect() const { return m_viewportRect; }
const IntSize& contentsSize() const { return m_contentsSize; }
+ bool shouldUpdateScrollLayerPositionOnMainThread() const { return m_shouldUpdateScrollLayerPositionOnMainThread; }
private:
ScrollingTree* m_scrollingTree;
@@ -59,6 +60,8 @@
IntRect m_viewportRect;
IntSize m_contentsSize;
+ bool m_shouldUpdateScrollLayerPositionOnMainThread;
+
ScrollElasticity m_horizontalScrollElasticity;
ScrollElasticity m_verticalScrollElasticity;
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeState.cpp (107334 => 107335)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeState.cpp 2012-02-10 01:58:36 UTC (rev 107334)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeState.cpp 2012-02-10 02:10:13 UTC (rev 107335)
@@ -38,6 +38,7 @@
ScrollingTreeState::ScrollingTreeState()
: m_changedProperties(0)
, m_wheelEventHandlerCount(0)
+ , m_shouldUpdateScrollLayerPositionOnMainThread(false)
, m_horizontalScrollElasticity(ScrollElasticityNone)
, m_verticalScrollElasticity(ScrollElasticityNone)
, m_hasEnabledHorizontalScrollbar(false)
@@ -85,6 +86,15 @@
m_changedProperties |= WheelEventHandlerCount;
}
+void ScrollingTreeState::setShouldUpdateScrollLayerPositionOnMainThread(bool shouldUpdateScrollLayerPositionOnMainThread)
+{
+ if (m_shouldUpdateScrollLayerPositionOnMainThread == shouldUpdateScrollLayerPositionOnMainThread)
+ return;
+
+ m_shouldUpdateScrollLayerPositionOnMainThread = shouldUpdateScrollLayerPositionOnMainThread;
+ m_changedProperties |= ShouldUpdateScrollLayerPositionOnMainThread;
+}
+
void ScrollingTreeState::setHorizontalScrollElasticity(ScrollElasticity horizontalScrollElasticity)
{
if (m_horizontalScrollElasticity == horizontalScrollElasticity)
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeState.h (107334 => 107335)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeState.h 2012-02-10 01:58:36 UTC (rev 107334)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeState.h 2012-02-10 02:10:13 UTC (rev 107335)
@@ -54,11 +54,12 @@
ContentsSize = 1 << 1,
NonFastScrollableRegion = 1 << 2,
WheelEventHandlerCount = 1 << 3,
- HorizontalScrollElasticity = 1 << 4,
- VerticalScrollElasticity = 1 << 5,
- HasEnabledHorizontalScrollbar = 1 << 6,
- HasEnabledVerticalScrollbar = 1 << 7,
- ScrollLayer = 1 << 8,
+ ShouldUpdateScrollLayerPositionOnMainThread = 1 << 4,
+ HorizontalScrollElasticity = 1 << 5,
+ VerticalScrollElasticity = 1 << 6,
+ HasEnabledHorizontalScrollbar = 1 << 7,
+ HasEnabledVerticalScrollbar = 1 << 8,
+ ScrollLayer = 1 << 9,
};
bool hasChangedProperties() const { return m_changedProperties; }
@@ -76,6 +77,9 @@
unsigned wheelEventHandlerCount() const { return m_wheelEventHandlerCount; }
void setWheelEventHandlerCount(unsigned);
+ bool shouldUpdateScrollLayerPositionOnMainThread() const { return m_shouldUpdateScrollLayerPositionOnMainThread; }
+ void setShouldUpdateScrollLayerPositionOnMainThread(bool);
+
ScrollElasticity horizontalScrollElasticity() const { return m_horizontalScrollElasticity; }
void setHorizontalScrollElasticity(ScrollElasticity);
@@ -106,6 +110,8 @@
unsigned m_wheelEventHandlerCount;
+ bool m_shouldUpdateScrollLayerPositionOnMainThread;
+
ScrollElasticity m_horizontalScrollElasticity;
ScrollElasticity m_verticalScrollElasticity;
Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeNodeMac.mm (107334 => 107335)
--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeNodeMac.mm 2012-02-10 01:58:36 UTC (rev 107334)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeNodeMac.mm 2012-02-10 02:10:13 UTC (rev 107335)
@@ -134,14 +134,22 @@
void ScrollingTreeNodeMac::setScrollPosition(const IntPoint& position)
{
+ ASSERT(!shouldUpdateScrollLayerPositionOnMainThread());
+
m_scrollLayer.get().position = CGPointMake(-position.x(), -position.y());
}
-void ScrollingTreeNodeMac::scrollBy(const IntSize &offset)
+void ScrollingTreeNodeMac::scrollBy(const IntSize& offset)
{
- setScrollPosition(scrollPosition() + offset);
+ IntPoint newScrollPosition = scrollPosition() + offset;
- scrollingTree()->updateMainFrameScrollPosition(scrollPosition());
+ if (shouldUpdateScrollLayerPositionOnMainThread()) {
+ scrollingTree()->updateMainFrameScrollPositionAndScrollLayerPosition(newScrollPosition);
+ return;
+ }
+
+ setScrollPosition(newScrollPosition);
+ scrollingTree()->updateMainFrameScrollPosition(newScrollPosition);
}
} // namespace WebCore
Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (107334 => 107335)
--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2012-02-10 01:58:36 UTC (rev 107334)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2012-02-10 02:10:13 UTC (rev 107335)
@@ -983,8 +983,19 @@
if (RenderLayerBacking* backing = rootRenderLayer()->backing())
backing->graphicsLayer()->visibleRectChanged();
- if (m_scrollLayer)
- m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y()));
+ if (!m_scrollLayer)
+ return;
+
+#if ENABLE(THREADED_SCROLLING)
+ // If there's a scrolling coordinator that manages scrolling for this frame view,
+ // it will also manage updating the scroll layer position.
+ if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
+ if (scrollingCoordinator->coordinatesScrollingForFrameView(frameView))
+ return;
+ }
+#endif
+
+ m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y()));
}
String RenderLayerCompositor::layerTreeAsText(bool showDebugInfo)