https://bugs.webkit.org/show_bug.cgi?id=164855
Reviewed by Sam Weinig.
Source/WebCore:
During UI-process panning and zooming, we send visible rect updates to the web process
with inStableState=false, and don't update GraphicsLayers until we get into a stable state.
This causes a problem where the web process has a stale notion of where the GraphicsLayers
for position:fixed elements are, but is then told to update tiling coverage with an up-to-date
visible rect. The existing "sync layer positions" path isn't useful to fix this, because it
breaks the relationship between the GraphicsLayer positions and their FixedPositionViewportConstraints
in the scrolling tree.
To address this, add the notion of an Optional<> approximatePosition on GraphicsLayers. This is used
only by the coverageRect computation code path, and is cleared by a setPosition(). ApproximatePositions
are pushed onto GraphicsLayers via the syncViewportConstrainedLayerPositions() code path (renamed to
reconcileViewportConstrainedLayerPositions).
This allows us to remmove "viewportIsStable" from GraphicsLayer flushing, and FrameView.
SetOrSyncScrollingLayerPosition is made into an enum class.
Tested by scrollingcoordinator/ios/non-stable-viewport-scroll.html
* page/FrameView.cpp:
(WebCore::FrameView::reset):
* page/FrameView.h:
* page/scrolling/AsyncScrollingCoordinator.cpp:
(WebCore::AsyncScrollingCoordinator::requestScrollPositionUpdate):
(WebCore::AsyncScrollingCoordinator::scheduleUpdateScrollPositionAfterAsyncScroll):
(WebCore::AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll):
(WebCore::AsyncScrollingCoordinator::reconcileScrollingState):
(WebCore::AsyncScrollingCoordinator::reconcileViewportConstrainedLayerPositions):
(WebCore::AsyncScrollingCoordinator::syncViewportConstrainedLayerPositions): Deleted.
* page/scrolling/AsyncScrollingCoordinator.h:
(WebCore::AsyncScrollingCoordinator::ScheduledScrollUpdate::ScheduledScrollUpdate):
* page/scrolling/ScrollingCoordinator.cpp:
(WebCore::operator<<):
* page/scrolling/ScrollingCoordinator.h:
(WebCore::ScrollingCoordinator::reconcileScrollingState):
(WebCore::ScrollingCoordinator::reconcileViewportConstrainedLayerPositions):
(WebCore::ScrollingCoordinator::syncViewportConstrainedLayerPositions): Deleted.
* page/scrolling/ScrollingStateFixedNode.cpp:
(WebCore::ScrollingStateFixedNode::reconcileLayerPositionForViewportRect):
(WebCore::ScrollingStateFixedNode::syncLayerPositionForViewportRect): Deleted.
* page/scrolling/ScrollingStateFixedNode.h:
* page/scrolling/ScrollingStateNode.h:
(WebCore::ScrollingStateNode::reconcileLayerPositionForViewportRect):
(WebCore::ScrollingStateNode::syncLayerPositionForViewportRect): Deleted.
* page/scrolling/ScrollingStateStickyNode.cpp:
(WebCore::ScrollingStateStickyNode::reconcileLayerPositionForViewportRect):
(WebCore::ScrollingStateStickyNode::syncLayerPositionForViewportRect): Deleted.
* page/scrolling/ScrollingStateStickyNode.h:
* page/scrolling/ScrollingTree.cpp:
(WebCore::ScrollingTree::scrollPositionChangedViaDelegatedScrolling):
* page/scrolling/ScrollingTree.h:
* page/scrolling/ThreadedScrollingTree.cpp:
(WebCore::ThreadedScrollingTree::scrollingTreeNodeDidScroll):
* page/scrolling/ThreadedScrollingTree.h:
* page/scrolling/ios/ScrollingTreeFrameScrollingNodeIOS.mm:
(WebCore::ScrollingTreeFrameScrollingNodeIOS::setScrollPositionWithoutContentEdgeConstraints):
* page/scrolling/ios/ScrollingTreeIOS.cpp:
(WebCore::ScrollingTreeIOS::scrollingTreeNodeDidScroll):
* page/scrolling/ios/ScrollingTreeIOS.h:
* page/scrolling/mac/ScrollingTreeFixedNode.mm:
(WebCore::ScrollingTreeFixedNode::updateLayersAfterAncestorChange):
* platform/graphics/GraphicsLayer.cpp:
(WebCore::GraphicsLayer::dumpProperties):
* platform/graphics/GraphicsLayer.h:
(WebCore::GraphicsLayer::setPosition):
(WebCore::GraphicsLayer::approximatePosition):
(WebCore::GraphicsLayer::setApproximatePosition):
(WebCore::GraphicsLayer::flushCompositingState):
(WebCore::GraphicsLayer::flushCompositingStateForThisLayerOnly):
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::flushCompositingState):
(WebCore::GraphicsLayerCA::flushCompositingStateForThisLayerOnly):
(WebCore::GraphicsLayerCA::computeVisibleAndCoverageRect):
(WebCore::GraphicsLayerCA::setVisibleAndCoverageRects): No longer bail for viewportConstained layers when the viewport is unstable.
(WebCore::GraphicsLayerCA::recursiveCommitChanges):
* platform/graphics/ca/GraphicsLayerCA.h:
(WebCore::GraphicsLayerCA::CommitState::CommitState): Deleted.
* platform/graphics/texmap/GraphicsLayerTextureMapper.cpp:
(WebCore::GraphicsLayerTextureMapper::flushCompositingState):
* platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp:
(WebCore::CoordinatedGraphicsLayer::flushCompositingState):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::flushPendingLayerChanges):
Source/WebKit/win:
Remove the "inStableState" parameter from flushCompositingState() etc.
* WebCoreSupport/AcceleratedCompositingContext.cpp:
(AcceleratedCompositingContext::flushPendingLayerChanges):
* WebView.cpp:
(WebView::flushPendingGraphicsLayerChanges):
Source/WebKit2:
During UI-process panning and zooming, we send visible rect updates to the web process
with inStableState=false, and don't update GraphicsLayers until we get into a stable state.
This causes a problem where the web process has a stale notion of where the GraphicsLayers
for position:fixed elements are, but is then told to update tiling coverage with an up-to-date
visible rect. The existing "sync layer positions" path isn't useful to fix this, because it
breaks the relationship between the GraphicsLayer positions and their FixedPositionViewportConstraints
in the scrolling tree.
To address this, add the notion of an Optional<> approximatePosition on GraphicsLayers. This is used
only by the coverageRect computation code path, and is cleared by a setPosition(). ApproximatePositions
are pushed onto GraphicsLayers via the syncViewportConstrainedLayerPositions() code path (renamed to
reconcileViewportConstrainedLayerPositions).
Tested by scrollingcoordinator/ios/non-stable-viewport-scroll.html
* UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp:
(WebKit::RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll):
* UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h:
* UIProcess/Scrolling/RemoteScrollingTree.cpp:
(WebKit::RemoteScrollingTree::scrollingTreeNodeDidScroll):
* UIProcess/Scrolling/RemoteScrollingTree.h:
* WebProcess/Scrolling/RemoteScrollingCoordinator.mm:
(WebKit::RemoteScrollingCoordinator::scrollPositionChangedForNode):
* WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.cpp:
(WebKit::CompositingCoordinator::flushPendingLayerChanges):
* WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.cpp:
(WebKit::CoordinatedLayerTreeHost::didFlushRootLayer):
* WebProcess/WebPage/gtk/LayerTreeHostGtk.cpp:
(WebKit::LayerTreeHostGtk::flushPendingLayerChanges):
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::updateVisibleContentRects): Always push the custom fixed position rect down, but send
ScrollingLayerPositionAction::SetApproximate if the state is not stable.
* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
(WebKit::RemoteLayerTreeDrawingArea::flushLayers):
* WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:
(WebKit::TiledCoreAnimationDrawingArea::flushLayers):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208927
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
(children 1
(GraphicsLayer
(position 10.00 0.00)
+ (approximate position 10.00 960.75)
(bounds 100.00 568.00)
(usingTiledLayer 1)
(contentsOpaque 1)
(drawsContent 1)
- (visible rect 0.00, 0.00 100.00 x 568.00)
- (coverage rect -10.00, 0.00 320.00 x 568.00)
+ (visible rect 0.00, 39.25 96.67 x 189.33)
+ (coverage rect -10.00, -3.42 192.00 x 274.67)
(intersects coverage rect 1)
(contentsScale 6.00)
)
(children 1
(GraphicsLayer
(position 12.00 10.00)
+ (approximate position 12.00 166.50)
(bounds 100.00 100.00)
(contentsOpaque 1)
)
+2016-11-19 Simon Fraser <simon.fraser@apple.com>
+
+ [iOS WK2] When zoomed in and panning on pages with fixed bars, parts of the bars are sometimes missing
+ https://bugs.webkit.org/show_bug.cgi?id=164855
+
+ Reviewed by Sam Weinig.
+
+ During UI-process panning and zooming, we send visible rect updates to the web process
+ with inStableState=false, and don't update GraphicsLayers until we get into a stable state.
+
+ This causes a problem where the web process has a stale notion of where the GraphicsLayers
+ for position:fixed elements are, but is then told to update tiling coverage with an up-to-date
+ visible rect. The existing "sync layer positions" path isn't useful to fix this, because it
+ breaks the relationship between the GraphicsLayer positions and their FixedPositionViewportConstraints
+ in the scrolling tree.
+
+ To address this, add the notion of an Optional<> approximatePosition on GraphicsLayers. This is used
+ only by the coverageRect computation code path, and is cleared by a setPosition(). ApproximatePositions
+ are pushed onto GraphicsLayers via the syncViewportConstrainedLayerPositions() code path (renamed to
+ reconcileViewportConstrainedLayerPositions).
+
+ This allows us to remmove "viewportIsStable" from GraphicsLayer flushing, and FrameView.
+
+ SetOrSyncScrollingLayerPosition is made into an enum class.
+
+ Tested by scrollingcoordinator/ios/non-stable-viewport-scroll.html
+
+ * page/FrameView.cpp:
+ (WebCore::FrameView::reset):
+ * page/FrameView.h:
+ * page/scrolling/AsyncScrollingCoordinator.cpp:
+ (WebCore::AsyncScrollingCoordinator::requestScrollPositionUpdate):
+ (WebCore::AsyncScrollingCoordinator::scheduleUpdateScrollPositionAfterAsyncScroll):
+ (WebCore::AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll):
+ (WebCore::AsyncScrollingCoordinator::reconcileScrollingState):
+ (WebCore::AsyncScrollingCoordinator::reconcileViewportConstrainedLayerPositions):
+ (WebCore::AsyncScrollingCoordinator::syncViewportConstrainedLayerPositions): Deleted.
+ * page/scrolling/AsyncScrollingCoordinator.h:
+ (WebCore::AsyncScrollingCoordinator::ScheduledScrollUpdate::ScheduledScrollUpdate):
+ * page/scrolling/ScrollingCoordinator.cpp:
+ (WebCore::operator<<):
+ * page/scrolling/ScrollingCoordinator.h:
+ (WebCore::ScrollingCoordinator::reconcileScrollingState):
+ (WebCore::ScrollingCoordinator::reconcileViewportConstrainedLayerPositions):
+ (WebCore::ScrollingCoordinator::syncViewportConstrainedLayerPositions): Deleted.
+ * page/scrolling/ScrollingStateFixedNode.cpp:
+ (WebCore::ScrollingStateFixedNode::reconcileLayerPositionForViewportRect):
+ (WebCore::ScrollingStateFixedNode::syncLayerPositionForViewportRect): Deleted.
+ * page/scrolling/ScrollingStateFixedNode.h:
+ * page/scrolling/ScrollingStateNode.h:
+ (WebCore::ScrollingStateNode::reconcileLayerPositionForViewportRect):
+ (WebCore::ScrollingStateNode::syncLayerPositionForViewportRect): Deleted.
+ * page/scrolling/ScrollingStateStickyNode.cpp:
+ (WebCore::ScrollingStateStickyNode::reconcileLayerPositionForViewportRect):
+ (WebCore::ScrollingStateStickyNode::syncLayerPositionForViewportRect): Deleted.
+ * page/scrolling/ScrollingStateStickyNode.h:
+ * page/scrolling/ScrollingTree.cpp:
+ (WebCore::ScrollingTree::scrollPositionChangedViaDelegatedScrolling):
+ * page/scrolling/ScrollingTree.h:
+ * page/scrolling/ThreadedScrollingTree.cpp:
+ (WebCore::ThreadedScrollingTree::scrollingTreeNodeDidScroll):
+ * page/scrolling/ThreadedScrollingTree.h:
+ * page/scrolling/ios/ScrollingTreeFrameScrollingNodeIOS.mm:
+ (WebCore::ScrollingTreeFrameScrollingNodeIOS::setScrollPositionWithoutContentEdgeConstraints):
+ * page/scrolling/ios/ScrollingTreeIOS.cpp:
+ (WebCore::ScrollingTreeIOS::scrollingTreeNodeDidScroll):
+ * page/scrolling/ios/ScrollingTreeIOS.h:
+ * page/scrolling/mac/ScrollingTreeFixedNode.mm:
+ (WebCore::ScrollingTreeFixedNode::updateLayersAfterAncestorChange):
+ * platform/graphics/GraphicsLayer.cpp:
+ (WebCore::GraphicsLayer::dumpProperties):
+ * platform/graphics/GraphicsLayer.h:
+ (WebCore::GraphicsLayer::setPosition):
+ (WebCore::GraphicsLayer::approximatePosition):
+ (WebCore::GraphicsLayer::setApproximatePosition):
+ (WebCore::GraphicsLayer::flushCompositingState):
+ (WebCore::GraphicsLayer::flushCompositingStateForThisLayerOnly):
+ * platform/graphics/ca/GraphicsLayerCA.cpp:
+ (WebCore::GraphicsLayerCA::flushCompositingState):
+ (WebCore::GraphicsLayerCA::flushCompositingStateForThisLayerOnly):
+ (WebCore::GraphicsLayerCA::computeVisibleAndCoverageRect):
+ (WebCore::GraphicsLayerCA::setVisibleAndCoverageRects): No longer bail for viewportConstained layers when the viewport is unstable.
+ (WebCore::GraphicsLayerCA::recursiveCommitChanges):
+ * platform/graphics/ca/GraphicsLayerCA.h:
+ (WebCore::GraphicsLayerCA::CommitState::CommitState): Deleted.
+ * platform/graphics/texmap/GraphicsLayerTextureMapper.cpp:
+ (WebCore::GraphicsLayerTextureMapper::flushCompositingState):
+ * platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp:
+ (WebCore::CoordinatedGraphicsLayer::flushCompositingState):
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::flushPendingLayerChanges):
+
2016-11-19 Joanmarie Diggs <jdiggs@igalia.com>
AX: [ATK] Expose aria-busy via ATK_STATE_BUSY
m_visuallyNonEmptyPixelCount = 0;
m_isVisuallyNonEmpty = false;
m_firstVisuallyNonEmptyLayoutCallbackPending = true;
- m_viewportIsStable = true;
m_needsDeferredScrollbarsUpdate = false;
m_maintainScrollPositionAnchor = nullptr;
}
WEBCORE_EXPORT bool renderedCharactersExceed(unsigned threshold);
- void setViewportIsStable(bool stable) { m_viewportIsStable = stable; }
- bool viewportIsStable() const { return m_viewportIsStable; }
-
#if PLATFORM(IOS)
bool useCustomFixedPositionLayoutRect() const;
IntRect customFixedPositionLayoutRect() const { return m_customFixedPositionLayoutRect; }
bool m_isVisuallyNonEmpty;
bool m_firstVisuallyNonEmptyLayoutCallbackPending;
- bool m_viewportIsStable { true };
-
bool m_needsDeferredScrollbarsUpdate { false };
RefPtr<ContainerNode> m_maintainScrollPositionAnchor;
bool isProgrammaticScroll = frameView.inProgrammaticScroll();
if (isProgrammaticScroll || frameView.frame().document()->pageCacheState() != Document::NotInPageCache)
- updateScrollPositionAfterAsyncScroll(frameView.scrollLayerID(), scrollPosition, Nullopt, isProgrammaticScroll, SetScrollingLayerPosition);
+ updateScrollPositionAfterAsyncScroll(frameView.scrollLayerID(), scrollPosition, Nullopt, isProgrammaticScroll, ScrollingLayerPositionAction::Set);
// If this frame view's document is being put into the page cache, we don't want to update our
// main frame scroll position. Just let the FrameView think that we did.
return true;
}
-void AsyncScrollingCoordinator::scheduleUpdateScrollPositionAfterAsyncScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, const Optional<FloatPoint>& layoutViewportOrigin, bool programmaticScroll, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
+void AsyncScrollingCoordinator::scheduleUpdateScrollPositionAfterAsyncScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, const Optional<FloatPoint>& layoutViewportOrigin, bool programmaticScroll, ScrollingLayerPositionAction scrollingLayerPositionAction)
{
ScheduledScrollUpdate scrollUpdate(nodeID, scrollPosition, layoutViewportOrigin, programmaticScroll, scrollingLayerPositionAction);
return nullptr;
}
-void AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll(ScrollingNodeID scrollingNodeID, const FloatPoint& scrollPosition, Optional<FloatPoint> layoutViewportOrigin, bool programmaticScroll, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
+void AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll(ScrollingNodeID scrollingNodeID, const FloatPoint& scrollPosition, Optional<FloatPoint> layoutViewportOrigin, bool programmaticScroll, ScrollingLayerPositionAction scrollingLayerPositionAction)
{
ASSERT(isMainThread());
if (!frameViewPtr)
return;
- LOG_WITH_STREAM(Scrolling, stream << "AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll node " << scrollingNodeID << " scrollPosition " << scrollPosition << (scrollingLayerPositionAction == SetScrollingLayerPosition ? " set" : " sync") << " layer positions");
+ LOG_WITH_STREAM(Scrolling, stream << "AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll node " << scrollingNodeID << " scrollPosition " << scrollPosition << " action " << scrollingLayerPositionAction);
FrameView& frameView = *frameViewPtr;
if (scrollingNodeID == frameView.scrollLayerID()) {
- reconcileScrollingState(frameView, scrollPosition, layoutViewportOrigin, programmaticScroll, scrollingLayerPositionAction);
+ reconcileScrollingState(frameView, scrollPosition, layoutViewportOrigin, programmaticScroll, true, scrollingLayerPositionAction);
#if PLATFORM(COCOA)
if (m_page->expectsWheelEventTriggers()) {
// Overflow-scroll area.
if (ScrollableArea* scrollableArea = frameView.scrollableAreaForScrollLayerID(scrollingNodeID)) {
- scrollableArea->setIsUserScroll(scrollingLayerPositionAction == SyncScrollingLayerPosition);
+ scrollableArea->setIsUserScroll(scrollingLayerPositionAction == ScrollingLayerPositionAction::Sync);
scrollableArea->scrollToOffsetWithoutAnimation(scrollPosition);
scrollableArea->setIsUserScroll(false);
- if (scrollingLayerPositionAction == SetScrollingLayerPosition)
+ if (scrollingLayerPositionAction == ScrollingLayerPositionAction::Set)
m_page->editorClient().overflowScrollPositionChanged();
#if PLATFORM(COCOA)
}
}
-void AsyncScrollingCoordinator::reconcileScrollingState(FrameView& frameView, const FloatPoint& scrollPosition, const LayoutViewportOriginOrOverrideRect& layoutViewportOriginOrOverrideRect, bool programmaticScroll, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
+void AsyncScrollingCoordinator::reconcileScrollingState(FrameView& frameView, const FloatPoint& scrollPosition, const LayoutViewportOriginOrOverrideRect& layoutViewportOriginOrOverrideRect, bool programmaticScroll, bool inStableState, ScrollingLayerPositionAction scrollingLayerPositionAction)
{
bool oldProgrammaticScroll = frameView.inProgrammaticScroll();
frameView.setInProgrammaticScroll(programmaticScroll);
+ Optional<FloatRect> layoutViewportRect;
+
WTF::switchOn(layoutViewportOriginOrOverrideRect,
[&frameView](Optional<FloatPoint> origin) {
if (origin)
frameView.setBaseLayoutViewportOrigin(LayoutPoint(origin.value()), FrameView::TriggerLayoutOrNot::No);
- }, [&frameView](Optional<FloatRect> overrideRect) {
+ }, [&frameView, &layoutViewportRect, inStableState, visualViewportEnabled = visualViewportEnabled()](Optional<FloatRect> overrideRect) {
+ layoutViewportRect = overrideRect;
+ if (overrideRect && inStableState) {
+ if (visualViewportEnabled)
+ frameView.setLayoutViewportOverrideRect(LayoutRect(overrideRect.value()));
#if PLATFORM(IOS)
- if (overrideRect)
- frameView.setCustomFixedPositionLayoutRect(enclosingIntRect(overrideRect.value()));
-#else
- UNUSED_PARAM(overrideRect);
+ else
+ frameView.setCustomFixedPositionLayoutRect(enclosingIntRect(overrideRect.value()));
#endif
+ }
}
);
frameView.setConstrainsScrollingToContentEdge(true);
frameView.setInProgrammaticScroll(oldProgrammaticScroll);
- if (!programmaticScroll && scrollingLayerPositionAction == SyncScrollingLayerPosition)
- syncViewportConstrainedLayerPositions(frameView.rectForFixedPositionLayout());
+ if (!programmaticScroll && scrollingLayerPositionAction != ScrollingLayerPositionAction::Set) {
+ if (inStableState)
+ reconcileViewportConstrainedLayerPositions(frameView.rectForFixedPositionLayout(), scrollingLayerPositionAction);
+ else if (layoutViewportRect)
+ reconcileViewportConstrainedLayerPositions(LayoutRect(layoutViewportRect.value()), scrollingLayerPositionAction);
+ }
GraphicsLayer* scrollLayer = scrollLayerForFrameView(frameView);
if (!scrollLayer)
FloatPoint positionForFooterLayer = FloatPoint(scrollPositionForFixed.x(),
FrameView::yPositionForFooterLayer(scrollPosition, topContentInset, frameView.totalContentsSize().height(), frameView.footerHeight()));
- if (programmaticScroll || scrollingLayerPositionAction == SetScrollingLayerPosition) {
+ if (programmaticScroll || scrollingLayerPositionAction == ScrollingLayerPositionAction::Set) {
scrollLayer->setPosition(-frameView.scrollPosition());
if (counterScrollingLayer)
counterScrollingLayer->setPosition(scrollPositionForFixed);
m_scrollingStateTree->clear();
}
-void AsyncScrollingCoordinator::syncViewportConstrainedLayerPositions(const LayoutRect& viewportRect)
+void AsyncScrollingCoordinator::reconcileViewportConstrainedLayerPositions(const LayoutRect& viewportRect, ScrollingLayerPositionAction action)
{
if (!m_scrollingStateTree->rootStateNode())
return;
if (!children)
return;
- LOG_WITH_STREAM(Scrolling, stream << "AsyncScrollingCoordinator::syncChildPositions for viewport rect " << viewportRect);
+ LOG_WITH_STREAM(Scrolling, stream << "AsyncScrollingCoordinator::reconcileViewportConstrainedLayerPositions for viewport rect " << viewportRect);
// FIXME: We'll have to traverse deeper into the tree at some point.
for (auto& child : *children)
- child->syncLayerPositionForViewportRect(viewportRect);
+ child->reconcileLayerPositionForViewportRect(viewportRect, action);
}
void AsyncScrollingCoordinator::ensureRootStateNodeForFrameView(FrameView& frameView)
void scrollingStateTreePropertiesChanged();
- WEBCORE_EXPORT void scheduleUpdateScrollPositionAfterAsyncScroll(ScrollingNodeID, const FloatPoint&, const Optional<FloatPoint>& layoutViewportOrigin, bool programmaticScroll, SetOrSyncScrollingLayerPosition);
+ WEBCORE_EXPORT void scheduleUpdateScrollPositionAfterAsyncScroll(ScrollingNodeID, const FloatPoint&, const Optional<FloatPoint>& layoutViewportOrigin, bool programmaticScroll, ScrollingLayerPositionAction);
#if PLATFORM(COCOA)
WEBCORE_EXPORT void setActiveScrollSnapIndices(ScrollingNodeID, unsigned horizontalIndex, unsigned verticalIndex);
PassRefPtr<ScrollingTree> releaseScrollingTree() { return WTFMove(m_scrollingTree); }
- void updateScrollPositionAfterAsyncScroll(ScrollingNodeID, const FloatPoint&, Optional<FloatPoint> layoutViewportOrigin, bool programmaticScroll, SetOrSyncScrollingLayerPosition);
+ void updateScrollPositionAfterAsyncScroll(ScrollingNodeID, const FloatPoint&, Optional<FloatPoint> layoutViewportOrigin, bool programmaticScroll, ScrollingLayerPositionAction);
WEBCORE_EXPORT String scrollingStateTreeAsText() const override;
WEBCORE_EXPORT void willCommitTree() override;
WEBCORE_EXPORT void updateFrameScrollingNode(ScrollingNodeID, GraphicsLayer* scrollLayer, GraphicsLayer* scrolledContentsLayer, GraphicsLayer* counterScrollingLayer, GraphicsLayer* insetClipLayer, const ScrollingGeometry* = nullptr) override;
WEBCORE_EXPORT void updateOverflowScrollingNode(ScrollingNodeID, GraphicsLayer* scrollLayer, GraphicsLayer* scrolledContentsLayer, const ScrollingGeometry* = nullptr) override;
- WEBCORE_EXPORT void reconcileScrollingState(FrameView&, const FloatPoint&, const LayoutViewportOriginOrOverrideRect&, bool programmaticScroll, SetOrSyncScrollingLayerPosition) override;
+ WEBCORE_EXPORT void reconcileScrollingState(FrameView&, const FloatPoint&, const LayoutViewportOriginOrOverrideRect&, bool programmaticScroll, bool inStableState, ScrollingLayerPositionAction) override;
bool isRubberBandInProgress() const override;
void setScrollPinningBehavior(ScrollPinningBehavior) override;
bool isScrollSnapInProgress() const override;
#endif
- WEBCORE_EXPORT void syncViewportConstrainedLayerPositions(const LayoutRect& viewportRect) override;
+ WEBCORE_EXPORT void reconcileViewportConstrainedLayerPositions(const LayoutRect& viewportRect, ScrollingLayerPositionAction) override;
WEBCORE_EXPORT void scrollableAreaScrollbarLayerDidChange(ScrollableArea&, ScrollbarOrientation) override;
WEBCORE_EXPORT void setSynchronousScrollingReasons(SynchronousScrollingReasons) override;
struct ScheduledScrollUpdate {
ScheduledScrollUpdate() = default;
- ScheduledScrollUpdate(ScrollingNodeID scrollingNodeID, FloatPoint point, Optional<FloatPoint> viewportOrigin, bool isProgrammatic, SetOrSyncScrollingLayerPosition udpateAction)
+ ScheduledScrollUpdate(ScrollingNodeID scrollingNodeID, FloatPoint point, Optional<FloatPoint> viewportOrigin, bool isProgrammatic, ScrollingLayerPositionAction udpateAction)
: nodeID(scrollingNodeID)
, scrollPosition(point)
, layoutViewportOrigin(viewportOrigin)
FloatPoint scrollPosition;
Optional<FloatPoint> layoutViewportOrigin;
bool isProgrammaticScroll { false };
- SetOrSyncScrollingLayerPosition updateLayerPositionAction { SyncScrollingLayerPosition };
+ ScrollingLayerPositionAction updateLayerPositionAction { ScrollingLayerPositionAction::Sync };
bool matchesUpdateType(const ScheduledScrollUpdate& other) const
{
return ts;
}
+TextStream& operator<<(TextStream& ts, ScrollingLayerPositionAction action)
+{
+ switch (action) {
+ case ScrollingLayerPositionAction::Set:
+ ts << "set";
+ break;
+ case ScrollingLayerPositionAction::SetApproximate:
+ ts << "set approximate";
+ break;
+ case ScrollingLayerPositionAction::Sync:
+ ts << "sync";
+ break;
+ }
+ return ts;
+}
+
} // namespace WebCore
class ScrollingTree;
#endif
-enum SetOrSyncScrollingLayerPosition {
- SetScrollingLayerPosition,
- SyncScrollingLayerPosition
+enum class ScrollingLayerPositionAction {
+ Set,
+ SetApproximate,
+ Sync
};
struct ScrollableAreaParameters {
virtual void frameViewLayoutUpdated(FrameView&) { }
using LayoutViewportOriginOrOverrideRect = WTF::Variant<Optional<FloatPoint>, Optional<FloatRect>>;
- virtual void reconcileScrollingState(FrameView&, const FloatPoint&, const LayoutViewportOriginOrOverrideRect&, bool /* programmaticScroll */, SetOrSyncScrollingLayerPosition) { }
+ virtual void reconcileScrollingState(FrameView&, const FloatPoint&, const LayoutViewportOriginOrOverrideRect&, bool /* programmaticScroll */, bool /* inStableState*/, ScrollingLayerPositionAction) { }
// Should be called whenever the slow repaint objects counter changes between zero and one.
void frameViewHasSlowRepaintObjectsDidChange(FrameView&);
virtual void updateFrameScrollingNode(ScrollingNodeID, GraphicsLayer* /*scrollLayer*/, GraphicsLayer* /*scrolledContentsLayer*/, GraphicsLayer* /*counterScrollingLayer*/, GraphicsLayer* /*insetClipLayer*/, const ScrollingGeometry* = nullptr) { }
virtual void updateOverflowScrollingNode(ScrollingNodeID, GraphicsLayer* /*scrollLayer*/, GraphicsLayer* /*scrolledContentsLayer*/, const ScrollingGeometry* = nullptr) { }
- virtual void syncViewportConstrainedLayerPositions(const LayoutRect&) { }
+ virtual void reconcileViewportConstrainedLayerPositions(const LayoutRect&, ScrollingLayerPositionAction) { }
virtual String scrollingStateTreeAsText() const;
virtual bool isRubberBandInProgress() const { return false; }
virtual bool isScrollSnapInProgress() const { return false; }
};
WEBCORE_EXPORT TextStream& operator<<(TextStream&, ScrollingNodeType);
+WEBCORE_EXPORT TextStream& operator<<(TextStream&, ScrollingLayerPositionAction);
} // namespace WebCore
#include "ScrollingStateFixedNode.h"
#include "GraphicsLayer.h"
+#include "Logging.h"
#include "ScrollingStateTree.h"
#include "TextStream.h"
setPropertyChanged(ViewportConstraints);
}
-void ScrollingStateFixedNode::syncLayerPositionForViewportRect(const LayoutRect& viewportRect)
+void ScrollingStateFixedNode::reconcileLayerPositionForViewportRect(const LayoutRect& viewportRect, ScrollingLayerPositionAction action)
{
FloatPoint position = m_constraints.layerPositionForViewportRect(viewportRect);
- if (layer().representsGraphicsLayer())
- static_cast<GraphicsLayer*>(layer())->syncPosition(position);
+ if (layer().representsGraphicsLayer()) {
+ GraphicsLayer* graphicsLayer = static_cast<GraphicsLayer*>(layer());
+
+ LOG_WITH_STREAM(Compositing, stream << "ScrollingStateFixedNode::reconcileLayerPositionForViewportRect setting position of layer " << graphicsLayer->primaryLayerID() << " to " << position);
+
+ switch (action) {
+ case ScrollingLayerPositionAction::Set:
+ graphicsLayer->setPosition(position);
+ break;
+
+ case ScrollingLayerPositionAction::SetApproximate:
+ graphicsLayer->setApproximatePosition(position);
+ break;
+
+ case ScrollingLayerPositionAction::Sync:
+ graphicsLayer->syncPosition(position);
+ break;
+ }
+ }
}
void ScrollingStateFixedNode::dumpProperties(TextStream& ts, int indent, ScrollingStateTreeAsTextBehavior) const
ScrollingStateFixedNode(ScrollingStateTree&, ScrollingNodeID);
ScrollingStateFixedNode(const ScrollingStateFixedNode&, ScrollingStateTree&);
- void syncLayerPositionForViewportRect(const LayoutRect& viewportRect) override;
+ void reconcileLayerPositionForViewportRect(const LayoutRect& viewportRect, ScrollingLayerPositionAction) override;
void dumpProperties(TextStream&, int indent, ScrollingStateTreeAsTextBehavior) const override;
ChangedProperties changedProperties() const { return m_changedProperties; }
void setChangedProperties(ChangedProperties changedProperties) { m_changedProperties = changedProperties; }
- virtual void syncLayerPositionForViewportRect(const LayoutRect& /*viewportRect*/) { }
+ virtual void reconcileLayerPositionForViewportRect(const LayoutRect& /*viewportRect*/, ScrollingLayerPositionAction) { }
const LayerRepresentation& layer() const { return m_layer; }
WEBCORE_EXPORT void setLayer(const LayerRepresentation&);
#if ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
#include "GraphicsLayer.h"
+#include "Logging.h"
#include "ScrollingStateTree.h"
#include "TextStream.h"
setPropertyChanged(ViewportConstraints);
}
-void ScrollingStateStickyNode::syncLayerPositionForViewportRect(const LayoutRect& viewportRect)
+void ScrollingStateStickyNode::reconcileLayerPositionForViewportRect(const LayoutRect& viewportRect, ScrollingLayerPositionAction action)
{
FloatPoint position = m_constraints.layerPositionForConstrainingRect(viewportRect);
- if (layer().representsGraphicsLayer())
- static_cast<GraphicsLayer*>(layer())->syncPosition(position);
+ if (layer().representsGraphicsLayer()) {
+ GraphicsLayer* graphicsLayer = static_cast<GraphicsLayer*>(layer());
+
+ LOG_WITH_STREAM(Compositing, stream << "ScrollingStateStickyNode::reconcileLayerPositionForViewportRect setting position of layer " << graphicsLayer->primaryLayerID() << " to " << position);
+
+ switch (action) {
+ case ScrollingLayerPositionAction::Set:
+ graphicsLayer->setPosition(position);
+ break;
+
+ case ScrollingLayerPositionAction::SetApproximate:
+ graphicsLayer->setApproximatePosition(position);
+ break;
+
+ case ScrollingLayerPositionAction::Sync:
+ graphicsLayer->syncPosition(position);
+ break;
+ }
+ }
}
void ScrollingStateStickyNode::dumpProperties(TextStream& ts, int indent, ScrollingStateTreeAsTextBehavior) const
ScrollingStateStickyNode(ScrollingStateTree&, ScrollingNodeID);
ScrollingStateStickyNode(const ScrollingStateStickyNode&, ScrollingStateTree&);
- void syncLayerPositionForViewportRect(const LayoutRect& viewportRect) override;
+ void reconcileLayerPositionForViewportRect(const LayoutRect& viewportRect, ScrollingLayerPositionAction) override;
void dumpProperties(TextStream&, int indent, ScrollingStateTreeAsTextBehavior) const override;
downcast<ScrollingTreeOverflowScrollingNode>(*node).updateLayersAfterDelegatedScroll(scrollPosition);
// Update GraphicsLayers and scroll state.
- scrollingTreeNodeDidScroll(nodeID, scrollPosition, Nullopt, inUserInteration ? SyncScrollingLayerPosition : SetScrollingLayerPosition);
+ scrollingTreeNodeDidScroll(nodeID, scrollPosition, Nullopt, inUserInteration ? ScrollingLayerPositionAction::Sync : ScrollingLayerPositionAction::Set);
}
void ScrollingTree::commitTreeState(std::unique_ptr<ScrollingStateTree> scrollingStateTree)
// Called after a scrolling tree node has handled a scroll and updated its layers.
// Updates FrameView/RenderLayer scrolling state and GraphicsLayers.
- virtual void scrollingTreeNodeDidScroll(ScrollingNodeID, const FloatPoint& scrollPosition, const Optional<FloatPoint>& layoutViewportOrigin, SetOrSyncScrollingLayerPosition = SyncScrollingLayerPosition) = 0;
+ virtual void scrollingTreeNodeDidScroll(ScrollingNodeID, const FloatPoint& scrollPosition, const Optional<FloatPoint>& layoutViewportOrigin, ScrollingLayerPositionAction = ScrollingLayerPositionAction::Sync) = 0;
// Called for requested scroll position updates.
virtual void scrollingTreeNodeRequestsScroll(ScrollingNodeID, const FloatPoint& /*scrollPosition*/, bool /*representsProgrammaticScroll*/) { }
ScrollingTree::commitTreeState(WTFMove(scrollingStateTree));
}
-void ThreadedScrollingTree::scrollingTreeNodeDidScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, const Optional<FloatPoint>& layoutViewportOrigin, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
+void ThreadedScrollingTree::scrollingTreeNodeDidScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, const Optional<FloatPoint>& layoutViewportOrigin, ScrollingLayerPositionAction scrollingLayerPositionAction)
{
if (!m_scrollingCoordinator)
return;
protected:
explicit ThreadedScrollingTree(AsyncScrollingCoordinator*);
- void scrollingTreeNodeDidScroll(ScrollingNodeID, const FloatPoint& scrollPosition, const Optional<FloatPoint>& layoutViewportOrigin, SetOrSyncScrollingLayerPosition = SyncScrollingLayerPosition) override;
+ void scrollingTreeNodeDidScroll(ScrollingNodeID, const FloatPoint& scrollPosition, const Optional<FloatPoint>& layoutViewportOrigin, ScrollingLayerPositionAction = ScrollingLayerPositionAction::Sync) override;
void currentSnapPointIndicesDidChange(ScrollingNodeID, unsigned horizontal, unsigned vertical) override;
#if PLATFORM(MAC)
void handleWheelEventPhase(PlatformWheelEventPhase) override;
{
if (shouldUpdateScrollLayerPositionSynchronously()) {
m_probableMainThreadScrollPosition = scrollPosition;
- scrollingTree().scrollingTreeNodeDidScroll(scrollingNodeID(), scrollPosition, Nullopt, SetScrollingLayerPosition);
+ scrollingTree().scrollingTreeNodeDidScroll(scrollingNodeID(), scrollPosition, Nullopt, ScrollingLayerPositionAction::Set);
return;
}
});
}
-void ScrollingTreeIOS::scrollingTreeNodeDidScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, const Optional<FloatPoint>& layoutViewportOrigin, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
+void ScrollingTreeIOS::scrollingTreeNodeDidScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, const Optional<FloatPoint>& layoutViewportOrigin, ScrollingLayerPositionAction scrollingLayerPositionAction)
{
if (!m_scrollingCoordinator)
return;
PassRefPtr<ScrollingTreeNode> createScrollingTreeNode(ScrollingNodeType, ScrollingNodeID) override;
- void scrollingTreeNodeDidScroll(ScrollingNodeID, const FloatPoint& scrollPosition, const Optional<FloatPoint>& layoutViewportOrigin, SetOrSyncScrollingLayerPosition = SyncScrollingLayerPosition) override;
+ void scrollingTreeNodeDidScroll(ScrollingNodeID, const FloatPoint& scrollPosition, const Optional<FloatPoint>& layoutViewportOrigin, ScrollingLayerPositionAction = ScrollingLayerPositionAction::Sync) override;
void currentSnapPointIndicesDidChange(WebCore::ScrollingNodeID, unsigned horizontal, unsigned vertical) override;
if (shouldUpdateScrollLayerPositionSynchronously()) {
m_probableMainThreadScrollPosition = scrollPosition;
- scrollingTree().scrollingTreeNodeDidScroll(scrollingNodeID(), scrollPosition, layoutViewportOrigin, SetScrollingLayerPosition);
+ scrollingTree().scrollingTreeNodeDidScroll(scrollingNodeID(), scrollPosition, layoutViewportOrigin, ScrollingLayerPositionAction::Set);
return;
}
ts << "(position " << m_position.x() << " " << m_position.y() << ")\n";
}
+ if (m_approximatePosition) {
+ writeIndent(ts, indent + 1);
+ ts << "(approximate position " << m_approximatePosition.value().x() << " " << m_approximatePosition.value().y() << ")\n";
+ }
+
if (m_boundsOrigin != FloatPoint()) {
writeIndent(ts, indent + 1);
ts << "(bounds origin " << m_boundsOrigin.x() << " " << m_boundsOrigin.y() << ")\n";
// The position of the layer (the location of its top-left corner in its parent)
const FloatPoint& position() const { return m_position; }
- virtual void setPosition(const FloatPoint& p) { m_position = p; }
+ virtual void setPosition(const FloatPoint& p) { m_approximatePosition = Nullopt; m_position = p; }
+
+ // approximatePosition, if set, overrides position() and is used during coverage rect computation.
+ FloatPoint approximatePosition() const { return m_approximatePosition ? m_approximatePosition.value() : m_position; }
+ void setApproximatePosition(Optional<FloatPoint> p) { m_approximatePosition = p; }
// For platforms that move underlying platform layers on a different thread for scrolling; just update the GraphicsLayer state.
virtual void syncPosition(const FloatPoint& p) { m_position = p; }
// Some compositing systems may do internal batching to synchronize compositing updates
// with updates drawn into the window. These methods flush internal batched state on this layer
// and descendant layers, and this layer only.
- virtual void flushCompositingState(const FloatRect& /* clipRect */, bool /* viewportIsStable */) { }
- virtual void flushCompositingStateForThisLayerOnly(bool /* viewportIsStable */) { }
+ virtual void flushCompositingState(const FloatRect& /* clipRect */) { }
+ virtual void flushCompositingStateForThisLayerOnly() { }
// If the exposed rect of this layer changes, returns true if this or descendant layers need a flush,
// for example to allocate new tiles.
// Position is relative to the parent GraphicsLayer
FloatPoint m_position;
+
+ // If set, overrides m_position. Only used for coverage computation.
+ Optional<FloatPoint> m_approximatePosition;
+
FloatPoint3D m_anchorPoint;
FloatSize m_size;
FloatPoint m_boundsOrigin;
return FloatPoint();
}
-void GraphicsLayerCA::flushCompositingState(const FloatRect& clipRect, bool viewportIsStable)
+void GraphicsLayerCA::flushCompositingState(const FloatRect& clipRect)
{
TransformState state(TransformState::UnapplyInverseTransformDirection, FloatQuad(clipRect));
FloatQuad coverageQuad(clipRect);
state.setSecondaryQuad(&coverageQuad);
- recursiveCommitChanges(CommitState(viewportIsStable), state);
+ recursiveCommitChanges(CommitState(), state);
}
-void GraphicsLayerCA::flushCompositingStateForThisLayerOnly(bool viewportIsStable)
+void GraphicsLayerCA::flushCompositingStateForThisLayerOnly()
{
float pageScaleFactor;
bool hadChanges = m_uncommittedChanges;
- CommitState commitState(viewportIsStable);
+ CommitState commitState;
FloatPoint offset = computePositionRelativeToBase(pageScaleFactor);
commitLayerChangesBeforeSublayers(commitState, pageScaleFactor, offset);
GraphicsLayerCA::VisibleAndCoverageRects GraphicsLayerCA::computeVisibleAndCoverageRect(TransformState& state, bool preserves3D, ComputeVisibleRectFlags flags) const
{
- FloatPoint position = m_position;
+ FloatPoint position = approximatePosition();
client().customPositionForVisibleRectComputation(this, position);
TransformationMatrix layerTransform;
return true;
}
-void GraphicsLayerCA::setVisibleAndCoverageRects(const VisibleAndCoverageRects& rects, bool isViewportConstrained, bool viewportIsStable)
+void GraphicsLayerCA::setVisibleAndCoverageRects(const VisibleAndCoverageRects& rects, bool isViewportConstrained)
{
bool visibleRectChanged = rects.visibleRect != m_visibleRect;
bool coverageRectChanged = rects.coverageRect != m_coverageRect;
if (!visibleRectChanged && !coverageRectChanged)
return;
- if (isViewportConstrained && !viewportIsStable)
- return;
-
// FIXME: we need to take reflections into account when determining whether this layer intersects the coverage rect.
bool intersectsCoverageRect = isViewportConstrained || rects.coverageRect.intersects(FloatRect(m_boundsOrigin, size()));
if (intersectsCoverageRect != m_intersectsCoverageRect) {
localState.setLastPlanarSecondaryQuad(&secondaryQuad);
}
}
- setVisibleAndCoverageRects(rects, m_isViewportConstrained || commitState.ancestorIsViewportConstrained, commitState.viewportIsStable);
+ setVisibleAndCoverageRects(rects, m_isViewportConstrained || commitState.ancestorIsViewportConstrained);
#ifdef VISIBLE_TILE_WASH
// Use having a transform as a key to making the tile wash layer. If every layer gets a wash,
int treeDepth { 0 };
bool ancestorHasTransformAnimation { false };
bool ancestorIsViewportConstrained { false };
- bool viewportIsStable { true };
-
- CommitState(bool stableViewport)
- : viewportIsStable(stableViewport)
- {
- }
};
void recursiveCommitChanges(const CommitState&, const TransformState&, float pageScaleFactor = 1, const FloatPoint& positionRelativeToBase = FloatPoint(), bool affectedByPageScale = false);
- WEBCORE_EXPORT void flushCompositingState(const FloatRect&, bool viewportIsStable) override;
- WEBCORE_EXPORT void flushCompositingStateForThisLayerOnly(bool viewportIsStable) override;
+ WEBCORE_EXPORT void flushCompositingState(const FloatRect&) override;
+ WEBCORE_EXPORT void flushCompositingStateForThisLayerOnly() override;
WEBCORE_EXPORT bool visibleRectChangeRequiresFlush(const FloatRect& visibleRect) const override;
const FloatRect& visibleRect() const { return m_visibleRect; }
const FloatRect& coverageRect() const { return m_coverageRect; }
- void setVisibleAndCoverageRects(const VisibleAndCoverageRects&, bool isViewportConstrained, bool viewportIsStable);
+ void setVisibleAndCoverageRects(const VisibleAndCoverageRects&, bool isViewportConstrained);
static FloatRect adjustTiledLayerVisibleRect(TiledBacking*, const FloatRect& oldVisibleRect, const FloatRect& newVisibleRect, const FloatSize& oldSize, const FloatSize& newSize);
notifyChange(IsScrollableChange);
}
-void GraphicsLayerTextureMapper::flushCompositingStateForThisLayerOnly(bool)
+void GraphicsLayerTextureMapper::flushCompositingStateForThisLayerOnly()
{
prepareBackingStoreIfNeeded();
commitLayerChanges();
m_changeMask = NoChanges;
}
-void GraphicsLayerTextureMapper::flushCompositingState(const FloatRect& rect, bool viewportIsStable)
+void GraphicsLayerTextureMapper::flushCompositingState(const FloatRect& rect)
{
if (!m_layer.textureMapper())
return;
- flushCompositingStateForThisLayerOnly(viewportIsStable);
+ flushCompositingStateForThisLayerOnly();
if (maskLayer())
- maskLayer()->flushCompositingState(rect, viewportIsStable);
+ maskLayer()->flushCompositingState(rect);
if (replicaLayer())
- replicaLayer()->flushCompositingState(rect, viewportIsStable);
+ replicaLayer()->flushCompositingState(rect);
for (auto* child : children())
- child->flushCompositingState(rect, viewportIsStable);
+ child->flushCompositingState(rect);
}
void GraphicsLayerTextureMapper::updateBackingStoreIncludingSubLayers()
void setDebugBorder(const Color&, float width) override;
void setShowRepaintCounter(bool) override;
- void flushCompositingState(const FloatRect&, bool) override;
- void flushCompositingStateForThisLayerOnly(bool) override;
+ void flushCompositingState(const FloatRect&) override;
+ void flushCompositingStateForThisLayerOnly() override;
void updateBackingStoreIncludingSubLayers();
didChangeLayerState();
}
-void CoordinatedGraphicsLayer::flushCompositingState(const FloatRect& rect, bool viewportIsStable)
+void CoordinatedGraphicsLayer::flushCompositingState(const FloatRect& rect)
{
if (CoordinatedGraphicsLayer* mask = downcast<CoordinatedGraphicsLayer>(maskLayer()))
- mask->flushCompositingStateForThisLayerOnly(viewportIsStable);
+ mask->flushCompositingStateForThisLayerOnly();
if (CoordinatedGraphicsLayer* replica = downcast<CoordinatedGraphicsLayer>(replicaLayer()))
- replica->flushCompositingStateForThisLayerOnly(viewportIsStable);
+ replica->flushCompositingStateForThisLayerOnly();
- flushCompositingStateForThisLayerOnly(viewportIsStable);
+ flushCompositingStateForThisLayerOnly();
for (auto& child : children())
- child->flushCompositingState(rect, viewportIsStable);
+ child->flushCompositingState(rect);
}
void CoordinatedGraphicsLayer::syncChildren()
}
#endif
-void CoordinatedGraphicsLayer::flushCompositingStateForThisLayerOnly(bool)
+void CoordinatedGraphicsLayer::flushCompositingStateForThisLayerOnly()
{
// When we have a transform animation, we need to update visible rect every frame to adjust the visible rect of a backing store.
bool hasActiveTransformAnimation = selfOrAncestorHasActiveTransformAnimation();
void setNeedsDisplayInRect(const FloatRect&, ShouldClipToLayer = ClipToLayer) override;
void setContentsNeedsDisplay() override;
void deviceOrPageScaleFactorChanged() override;
- void flushCompositingState(const FloatRect&, bool) override;
- void flushCompositingStateForThisLayerOnly(bool) override;
+ void flushCompositingState(const FloatRect&) override;
+ void flushCompositingStateForThisLayerOnly() override;
bool setFilters(const FilterOperations&) override;
bool addAnimation(const KeyframeValueList&, const FloatSize&, const Animation*, const String&, double) override;
void pauseAnimation(const String&, double) override;
if (GraphicsLayer* rootLayer = rootGraphicsLayer()) {
#if PLATFORM(IOS)
FloatRect exposedRect = frameView.exposedContentRect();
- LOG(Compositing, "RenderLayerCompositor %p flushPendingLayerChanges(%d) %.2f, %.2f, %.2fx%.2f (stable viewport %d)", this, isFlushRoot,
- exposedRect.x(), exposedRect.y(), exposedRect.width(), exposedRect.height(), frameView.viewportIsStable());
- rootLayer->flushCompositingState(exposedRect, frameView.viewportIsStable());
+ LOG_WITH_STREAM(Compositing, stream << "RenderLayerCompositor " << this << " flushPendingLayerChanges (root " << isFlushRoot << ") exposedRect " << exposedRect);
+ rootLayer->flushCompositingState(exposedRect);
#else
// Having a m_clipLayer indicates that we're doing scrolling via GraphicsLayers.
FloatRect visibleRect = m_clipLayer ? FloatRect({ 0, 0 }, frameView.sizeForVisibleContent()) : frameView.visibleContentRect();
if (frameView.viewExposedRect())
visibleRect.intersect(frameView.viewExposedRect().value());
- LOG_WITH_STREAM(Compositing, stream << "RenderLayerCompositor " << this << " flushPendingLayerChanges(" << isFlushRoot << ") " << visibleRect << " (stable viewport " << frameView.viewportIsStable() << ")");
- rootLayer->flushCompositingState(visibleRect, frameView.viewportIsStable());
+ LOG_WITH_STREAM(Compositing, stream << "RenderLayerCompositor " << this << " flushPendingLayerChanges(" << isFlushRoot << ") " << visibleRect);
+ rootLayer->flushCompositingState(visibleRect);
#endif
}
+2016-11-19 Simon Fraser <simon.fraser@apple.com>
+
+ [iOS WK2] When zoomed in and panning on pages with fixed bars, parts of the bars are sometimes missing
+ https://bugs.webkit.org/show_bug.cgi?id=164855
+
+ Reviewed by Sam Weinig.
+
+ Remove the "inStableState" parameter from flushCompositingState() etc.
+
+ * WebCoreSupport/AcceleratedCompositingContext.cpp:
+ (AcceleratedCompositingContext::flushPendingLayerChanges):
+ * WebView.cpp:
+ (WebView::flushPendingGraphicsLayerChanges):
+
2016-11-16 Yusuke Suzuki <utatane.tea@gmail.com>
[ES6][WebCore] Change ES6_MODULES compile time flag to runtime flag
bool AcceleratedCompositingContext::flushPendingLayerChanges()
{
FrameView* frameView = core(&m_webView)->mainFrame().view();
- m_rootLayer->flushCompositingStateForThisLayerOnly(frameView->viewportIsStable());
- m_nonCompositedContentLayer->flushCompositingStateForThisLayerOnly(frameView->viewportIsStable());
+ m_rootLayer->flushCompositingStateForThisLayerOnly();
+ m_nonCompositedContentLayer->flushCompositingStateForThisLayerOnly();
if (!frameView->flushCompositingStateIncludingSubframes())
return false;
#if USE(CA)
// Updating layout might have taken us out of compositing mode.
if (m_backingLayer)
- m_backingLayer->flushCompositingStateForThisLayerOnly(view->viewportIsStable());
+ m_backingLayer->flushCompositingStateForThisLayerOnly();
view->flushCompositingStateIncludingSubframes();
#elif USE(TEXTURE_MAPPER_GL)
+2016-11-19 Simon Fraser <simon.fraser@apple.com>
+
+ [iOS WK2] When zoomed in and panning on pages with fixed bars, parts of the bars are sometimes missing
+ https://bugs.webkit.org/show_bug.cgi?id=164855
+
+ Reviewed by Sam Weinig.
+
+ During UI-process panning and zooming, we send visible rect updates to the web process
+ with inStableState=false, and don't update GraphicsLayers until we get into a stable state.
+
+ This causes a problem where the web process has a stale notion of where the GraphicsLayers
+ for position:fixed elements are, but is then told to update tiling coverage with an up-to-date
+ visible rect. The existing "sync layer positions" path isn't useful to fix this, because it
+ breaks the relationship between the GraphicsLayer positions and their FixedPositionViewportConstraints
+ in the scrolling tree.
+
+ To address this, add the notion of an Optional<> approximatePosition on GraphicsLayers. This is used
+ only by the coverageRect computation code path, and is cleared by a setPosition(). ApproximatePositions
+ are pushed onto GraphicsLayers via the syncViewportConstrainedLayerPositions() code path (renamed to
+ reconcileViewportConstrainedLayerPositions).
+
+ Tested by scrollingcoordinator/ios/non-stable-viewport-scroll.html
+
+ * UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp:
+ (WebKit::RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll):
+ * UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h:
+ * UIProcess/Scrolling/RemoteScrollingTree.cpp:
+ (WebKit::RemoteScrollingTree::scrollingTreeNodeDidScroll):
+ * UIProcess/Scrolling/RemoteScrollingTree.h:
+ * WebProcess/Scrolling/RemoteScrollingCoordinator.mm:
+ (WebKit::RemoteScrollingCoordinator::scrollPositionChangedForNode):
+ * WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.cpp:
+ (WebKit::CompositingCoordinator::flushPendingLayerChanges):
+ * WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.cpp:
+ (WebKit::CoordinatedLayerTreeHost::didFlushRootLayer):
+ * WebProcess/WebPage/gtk/LayerTreeHostGtk.cpp:
+ (WebKit::LayerTreeHostGtk::flushPendingLayerChanges):
+ * WebProcess/WebPage/ios/WebPageIOS.mm:
+ (WebKit::WebPage::updateVisibleContentRects): Always push the custom fixed position rect down, but send
+ ScrollingLayerPositionAction::SetApproximate if the state is not stable.
+ * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
+ (WebKit::RemoteLayerTreeDrawingArea::flushLayers):
+ * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:
+ (WebKit::TiledCoreAnimationDrawingArea::flushLayers):
+
2016-11-18 Simon Fraser <simon.fraser@apple.com>
Make it possible to test non-stable-state scrolling on iOS
}
// This comes from the scrolling tree.
-void RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll(ScrollingNodeID scrolledNodeID, const FloatPoint& newScrollPosition, const Optional<FloatPoint>& layoutViewportOrigin, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
+void RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll(ScrollingNodeID scrolledNodeID, const FloatPoint& newScrollPosition, const Optional<FloatPoint>& layoutViewportOrigin, ScrollingLayerPositionAction scrollingLayerPositionAction)
{
// Scroll updates for the main frame are sent via WebPageProxy::updateVisibleContentRects()
// so don't send them here.
#if PLATFORM(IOS)
m_webPageProxy.overflowScrollViewDidScroll();
#endif
- m_webPageProxy.send(Messages::RemoteScrollingCoordinator::ScrollPositionChangedForNode(scrolledNodeID, newScrollPosition, scrollingLayerPositionAction));
+ m_webPageProxy.send(Messages::RemoteScrollingCoordinator::ScrollPositionChangedForNode(scrolledNodeID, newScrollPosition, scrollingLayerPositionAction == ScrollingLayerPositionAction::Sync));
}
void RemoteScrollingCoordinatorProxy::scrollingTreeNodeRequestsScroll(ScrollingNodeID scrolledNodeID, const FloatPoint& scrollPosition, bool representsProgrammaticScroll)
bool visualViewportEnabled() const { return m_scrollingTree && m_scrollingTree->visualViewportEnabled(); }
// Inform the web process that the scroll position changed (called from the scrolling tree)
- void scrollingTreeNodeDidScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& newScrollPosition, const Optional<WebCore::FloatPoint>& layoutViewportOrigin, WebCore::SetOrSyncScrollingLayerPosition);
+ void scrollingTreeNodeDidScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& newScrollPosition, const Optional<WebCore::FloatPoint>& layoutViewportOrigin, WebCore::ScrollingLayerPositionAction);
void scrollingTreeNodeRequestsScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, bool representsProgrammaticScroll);
WebCore::TrackingType eventTrackingTypeForPoint(const AtomicString& eventName, WebCore::IntPoint) const;
#endif
-void RemoteScrollingTree::scrollingTreeNodeDidScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, const Optional<FloatPoint>& layoutViewportOrigin, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
+void RemoteScrollingTree::scrollingTreeNodeDidScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, const Optional<FloatPoint>& layoutViewportOrigin, ScrollingLayerPositionAction scrollingLayerPositionAction)
{
m_scrollingCoordinatorProxy.scrollingTreeNodeDidScroll(nodeID, scrollPosition, layoutViewportOrigin, scrollingLayerPositionAction);
}
const RemoteScrollingCoordinatorProxy& scrollingCoordinatorProxy() const { return m_scrollingCoordinatorProxy; }
- void scrollingTreeNodeDidScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, const Optional<WebCore::FloatPoint>& layoutViewportOrigin, WebCore::SetOrSyncScrollingLayerPosition = WebCore::SyncScrollingLayerPosition) override;
+ void scrollingTreeNodeDidScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, const Optional<WebCore::FloatPoint>& layoutViewportOrigin, WebCore::ScrollingLayerPositionAction = WebCore::ScrollingLayerPositionAction::Sync) override;
void scrollingTreeNodeRequestsScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, bool representsProgrammaticScroll) override;
void currentSnapPointIndicesDidChange(WebCore::ScrollingNodeID, unsigned horizontal, unsigned vertical) override;
// Notification from the UI process that we scrolled.
void RemoteScrollingCoordinator::scrollPositionChangedForNode(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, bool syncLayerPosition)
{
- scheduleUpdateScrollPositionAfterAsyncScroll(nodeID, scrollPosition, Nullopt, false /* FIXME */, syncLayerPosition ? SyncScrollingLayerPosition : SetScrollingLayerPosition);
+ scheduleUpdateScrollPositionAfterAsyncScroll(nodeID, scrollPosition, Nullopt, false /* FIXME */, syncLayerPosition ? ScrollingLayerPositionAction::Sync : ScrollingLayerPositionAction::Set);
}
void RemoteScrollingCoordinator::currentSnapPointIndicesChangedForNode(ScrollingNodeID nodeID, unsigned horizontal, unsigned vertical)
initializeRootCompositingLayerIfNeeded();
- bool viewportIsStable = m_page->mainFrame().view()->viewportIsStable();
- m_rootLayer->flushCompositingStateForThisLayerOnly(viewportIsStable);
+ m_rootLayer->flushCompositingStateForThisLayerOnly();
m_client.didFlushRootLayer(m_visibleContentsRect);
if (m_overlayCompositingLayer)
- m_overlayCompositingLayer->flushCompositingState(FloatRect(FloatPoint(), m_rootLayer->size()), viewportIsStable);
+ m_overlayCompositingLayer->flushCompositingState(FloatRect(FloatPoint(), m_rootLayer->size()));
bool didSync = m_page->mainFrame().view()->flushCompositingStateIncludingSubframes();
{
// Because our view-relative overlay root layer is not attached to the FrameView's GraphicsLayer tree, we need to flush it manually.
if (m_viewOverlayRootLayer)
- m_viewOverlayRootLayer->flushCompositingState(visibleContentRect, m_webPage.mainFrame()->view()->viewportIsStable());
+ m_viewOverlayRootLayer->flushCompositingState(visibleContentRect);
}
void CoordinatedLayerTreeHost::layerFlushTimerFired()
bool LayerTreeHostGtk::flushPendingLayerChanges()
{
- bool viewportIsStable = m_webPage.corePage()->mainFrame().view()->viewportIsStable();
- m_rootLayer->flushCompositingStateForThisLayerOnly(viewportIsStable);
- m_nonCompositedContentLayer->flushCompositingStateForThisLayerOnly(viewportIsStable);
+ m_rootLayer->flushCompositingStateForThisLayerOnly();
+ m_nonCompositedContentLayer->flushCompositingStateForThisLayerOnly();
if (!m_webPage.corePage()->mainFrame().view()->flushCompositingStateIncludingSubframes())
return false;
if (m_viewOverlayRootLayer)
- m_viewOverlayRootLayer->flushCompositingState(FloatRect(FloatPoint(), m_rootLayer->size()), viewportIsStable);
+ m_viewOverlayRootLayer->flushCompositingState(FloatRect(FloatPoint(), m_rootLayer->size()));
downcast<GraphicsLayerTextureMapper>(*m_rootLayer).updateBackingStoreIncludingSubLayers();
return true;
if (visibleContentRectUpdateInfo.lastLayerTreeTransactionID() < m_mainFrame->firstLayerTreeTransactionIDAfterDidCommitLoad())
return;
+ LOG_WITH_STREAM(VisibleRects, stream << "\nWebPage::updateVisibleContentRects " << visibleContentRectUpdateInfo);
+
m_hasReceivedVisibleContentRectsAfterDidCommitLoad = true;
m_isInStableState = visibleContentRectUpdateInfo.inStableState();
double scaleChangeRate = visibleContentRectUpdateInfo.scaleChangeRate();
adjustVelocityDataForBoundedScale(horizontalVelocity, verticalVelocity, scaleChangeRate, visibleContentRectUpdateInfo.scale(), m_viewportConfiguration.minimumScale(), m_viewportConfiguration.maximumScale());
- frameView.setViewportIsStable(m_isInStableState);
frameView.setScrollVelocity(horizontalVelocity, verticalVelocity, scaleChangeRate, visibleContentRectUpdateInfo.timestamp());
- LOG_WITH_STREAM(VisibleRects, stream << "WebPage::updateVisibleContentRects setting layoutViewportOverrideRect " << visibleContentRectUpdateInfo.customFixedPositionRect() << " stable " << m_isInStableState);
if (m_isInStableState) {
if (frameView.frame().settings().visualViewportEnabled())
frameView.setLayoutViewportOverrideRect(LayoutRect(visibleContentRectUpdateInfo.customFixedPositionRect()));
if (!visibleContentRectUpdateInfo.isChangingObscuredInsetsInteractively())
frameView.setCustomSizeForResizeEvent(expandedIntSize(visibleContentRectUpdateInfo.unobscuredRectInScrollViewCoordinates().size()));
- if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
- Optional<FloatRect> customFixedPositionRect;
- if (m_isInStableState)
- customFixedPositionRect = visibleContentRectUpdateInfo.customFixedPositionRect();
- scrollingCoordinator->reconcileScrollingState(frameView, scrollPosition, customFixedPositionRect, false, SetOrSyncScrollingLayerPosition::SyncScrollingLayerPosition);
- }
+ if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
+ scrollingCoordinator->reconcileScrollingState(frameView, scrollPosition, visibleContentRectUpdateInfo.customFixedPositionRect(), false, m_isInStableState, m_isInStableState ? ScrollingLayerPositionAction::Sync : ScrollingLayerPositionAction::SetApproximate);
}
void WebPage::willStartUserTriggeredZooming()
// Because our view-relative overlay root layer is not attached to the FrameView's GraphicsLayer tree, we need to flush it manually.
if (m_viewOverlayRootLayer)
- m_viewOverlayRootLayer->flushCompositingState(visibleRect, m_webPage.mainFrameView()->viewportIsStable());
+ m_viewOverlayRootLayer->flushCompositingState(visibleRect);
- m_rootLayer->flushCompositingStateForThisLayerOnly(m_webPage.mainFrameView()->viewportIsStable());
+ m_rootLayer->flushCompositingStateForThisLayerOnly();
// FIXME: Minimize these transactions if nothing changed.
RemoteLayerTreeTransaction layerTransaction;
// Because our view-relative overlay root layer is not attached to the main GraphicsLayer tree, we need to flush it manually.
if (m_viewOverlayRootLayer)
- m_viewOverlayRootLayer->flushCompositingState(visibleRect, m_webPage.mainFrameView()->viewportIsStable());
+ m_viewOverlayRootLayer->flushCompositingState(visibleRect);
RefPtr<WebPage> retainedPage = &m_webPage;
#if TARGET_OS_IPHONE || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)