void AsyncScrollingCoordinator::frameViewLayoutUpdated(FrameView* frameView)
{
    ASSERT(isMainThread());
    ASSERT(m_page);

    // If there isn't a root node yet, don't do anything. We'll be called again after creating one.
    if (!m_scrollingStateTree->rootStateNode())
        return;

    // Compute the region of the page that we can't do fast scrolling for. This currently includes
    // all scrollable areas, such as subframes, overflow divs and list boxes. We need to do this even if the
    // frame view whose layout was updated is not the main frame.
    // In the future, we may want to have the ability to set non-fast scrolling regions for more than
    // just the root node. But right now, this concept only applies to the root.
    if (frameView->frame().isMainFrame())
        m_scrollingStateTree->rootStateNode()->setNonFastScrollableRegion(computeNonFastScrollableRegion(&frameView->frame(), IntPoint()));

    if (!coordinatesScrollingForFrameView(frameView))
        return;

    ScrollingStateFrameScrollingNode* node = downcast<ScrollingStateFrameScrollingNode>(m_scrollingStateTree->stateNodeForID(frameView->scrollLayerID()));
    if (!node)
        return;

    Scrollbar* verticalScrollbar = frameView->verticalScrollbar();
    Scrollbar* horizontalScrollbar = frameView->horizontalScrollbar();
    node->setScrollbarPaintersFromScrollbars(verticalScrollbar, horizontalScrollbar);
    
    node->setFrameScaleFactor(frameView->frame().frameScaleFactor());
    node->setHeaderHeight(frameView->headerHeight());
    node->setFooterHeight(frameView->footerHeight());
    node->setTopContentInset(frameView->topContentInset());

    node->setScrollOrigin(frameView->scrollOrigin());
    node->setScrollableAreaSize(frameView->visibleContentRect().size());
    node->setTotalContentsSize(frameView->totalContentsSize());
    node->setReachableContentsSize(frameView->totalContentsSize());

#if ENABLE(CSS_SCROLL_SNAP)
    frameView->updateSnapOffsets();
    if (const Vector<LayoutUnit>* horizontalSnapOffsets = frameView->horizontalSnapOffsets())
        setStateScrollingNodeSnapOffsetsAsFloat(*node, ScrollEventAxis::Horizontal, *horizontalSnapOffsets, m_page->deviceScaleFactor());

    if (const Vector<LayoutUnit>* verticalSnapOffsets = frameView->verticalSnapOffsets())
        setStateScrollingNodeSnapOffsetsAsFloat(*node, ScrollEventAxis::Vertical, *verticalSnapOffsets, m_page->deviceScaleFactor());
#endif

    ScrollableAreaParameters scrollParameters;
    scrollParameters.horizontalScrollElasticity = frameView->horizontalScrollElasticity();
    scrollParameters.verticalScrollElasticity = frameView->verticalScrollElasticity();
    scrollParameters.hasEnabledHorizontalScrollbar = horizontalScrollbar && horizontalScrollbar->enabled();
    scrollParameters.hasEnabledVerticalScrollbar = verticalScrollbar && verticalScrollbar->enabled();
    scrollParameters.horizontalScrollbarMode = frameView->horizontalScrollbarMode();
    scrollParameters.verticalScrollbarMode = frameView->verticalScrollbarMode();

    node->setScrollableAreaParameters(scrollParameters);
}
void AsyncScrollingCoordinator::updateScrollSnapPropertiesWithFrameView(const FrameView& frameView)
{
    if (auto node = downcast<ScrollingStateFrameScrollingNode>(m_scrollingStateTree->stateNodeForID(frameView.scrollLayerID()))) {
        setStateScrollingNodeSnapOffsetsAsFloat(*node, ScrollEventAxis::Horizontal, frameView.horizontalSnapOffsets(), m_page->deviceScaleFactor());
        setStateScrollingNodeSnapOffsetsAsFloat(*node, ScrollEventAxis::Vertical, frameView.verticalSnapOffsets(), m_page->deviceScaleFactor());
        node->setCurrentHorizontalSnapPointIndex(frameView.currentHorizontalSnapPointIndex());
        node->setCurrentVerticalSnapPointIndex(frameView.currentVerticalSnapPointIndex());
    }
}
void AsyncScrollingCoordinator::updateOverflowScrollingNode(ScrollingNodeID nodeID, GraphicsLayer* layer, GraphicsLayer* scrolledContentsLayer, const ScrollingGeometry* scrollingGeometry)
{
    ScrollingStateOverflowScrollingNode* node = downcast<ScrollingStateOverflowScrollingNode>(m_scrollingStateTree->stateNodeForID(nodeID));
    ASSERT(node);
    if (!node)
        return;

    node->setLayer(layer);
    node->setScrolledContentsLayer(scrolledContentsLayer);
    
    if (scrollingGeometry) {
        node->setScrollOrigin(scrollingGeometry->scrollOrigin);
        node->setScrollPosition(scrollingGeometry->scrollPosition);
        node->setTotalContentsSize(scrollingGeometry->contentSize);
        node->setReachableContentsSize(scrollingGeometry->reachableContentSize);
        node->setScrollableAreaSize(scrollingGeometry->scrollableAreaSize);
#if ENABLE(CSS_SCROLL_SNAP)
        setStateScrollingNodeSnapOffsetsAsFloat(*node, ScrollEventAxis::Horizontal, scrollingGeometry->horizontalSnapOffsets, m_page->deviceScaleFactor());
        setStateScrollingNodeSnapOffsetsAsFloat(*node, ScrollEventAxis::Vertical, scrollingGeometry->verticalSnapOffsets, m_page->deviceScaleFactor());
#endif
    }
}