ThreadedScrollingTree.cpp [plain text]
#include "config.h"
#include "ThreadedScrollingTree.h"
#if ENABLE(ASYNC_SCROLLING)
#include "AsyncScrollingCoordinator.h"
#include "PlatformWheelEvent.h"
#include "ScrollingThread.h"
#include "ScrollingTreeFixedNode.h"
#include "ScrollingTreeNode.h"
#include "ScrollingTreeScrollingNode.h"
#include "ScrollingTreeStickyNode.h"
#include <wtf/RunLoop.h>
namespace WebCore {
ThreadedScrollingTree::ThreadedScrollingTree(AsyncScrollingCoordinator& scrollingCoordinator)
: m_scrollingCoordinator(&scrollingCoordinator)
{
}
ThreadedScrollingTree::~ThreadedScrollingTree()
{
ASSERT(!m_scrollingCoordinator);
}
ScrollingTree::EventResult ThreadedScrollingTree::tryToHandleWheelEvent(const PlatformWheelEvent& wheelEvent)
{
if (shouldHandleWheelEventSynchronously(wheelEvent))
return SendToMainThread;
if (willWheelEventStartSwipeGesture(wheelEvent))
return DidNotHandleEvent;
RefPtr<ThreadedScrollingTree> protectedThis(this);
ScrollingThread::dispatch([protectedThis, wheelEvent] {
protectedThis->handleWheelEvent(wheelEvent);
});
return DidHandleEvent;
}
void ThreadedScrollingTree::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
{
ASSERT(ScrollingThread::isCurrentThread());
ScrollingTree::handleWheelEvent(wheelEvent);
}
void ThreadedScrollingTree::invalidate()
{
ASSERT(ScrollingThread::isCurrentThread());
RunLoop::main().dispatch([scrollingCoordinator = WTFMove(m_scrollingCoordinator)] {
});
}
void ThreadedScrollingTree::commitTreeState(std::unique_ptr<ScrollingStateTree> scrollingStateTree)
{
ASSERT(ScrollingThread::isCurrentThread());
ScrollingTree::commitTreeState(WTFMove(scrollingStateTree));
}
void ThreadedScrollingTree::scrollingTreeNodeDidScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, const std::optional<FloatPoint>& layoutViewportOrigin, ScrollingLayerPositionAction scrollingLayerPositionAction)
{
if (!m_scrollingCoordinator)
return;
if (nodeID == rootNode()->scrollingNodeID())
setMainFrameScrollPosition(scrollPosition);
RunLoop::main().dispatch([scrollingCoordinator = m_scrollingCoordinator, nodeID, scrollPosition, layoutViewportOrigin, localIsHandlingProgrammaticScroll = isHandlingProgrammaticScroll(), scrollingLayerPositionAction] {
scrollingCoordinator->scheduleUpdateScrollPositionAfterAsyncScroll(nodeID, scrollPosition, layoutViewportOrigin, localIsHandlingProgrammaticScroll, scrollingLayerPositionAction);
});
}
void ThreadedScrollingTree::reportSynchronousScrollingReasonsChanged(MonotonicTime timestamp, SynchronousScrollingReasons reasons)
{
RunLoop::main().dispatch([scrollingCoordinator = m_scrollingCoordinator, timestamp, reasons] {
scrollingCoordinator->reportSynchronousScrollingReasonsChanged(timestamp, reasons);
});
}
void ThreadedScrollingTree::reportExposedUnfilledArea(MonotonicTime timestamp, unsigned unfilledArea)
{
RunLoop::main().dispatch([scrollingCoordinator = m_scrollingCoordinator, timestamp, unfilledArea] {
scrollingCoordinator->reportExposedUnfilledArea(timestamp, unfilledArea);
});
}
void ThreadedScrollingTree::currentSnapPointIndicesDidChange(ScrollingNodeID nodeID, unsigned horizontal, unsigned vertical)
{
if (!m_scrollingCoordinator)
return;
RunLoop::main().dispatch([scrollingCoordinator = m_scrollingCoordinator, nodeID, horizontal, vertical] {
scrollingCoordinator->setActiveScrollSnapIndices(nodeID, horizontal, vertical);
});
}
#if PLATFORM(MAC)
void ThreadedScrollingTree::handleWheelEventPhase(PlatformWheelEventPhase phase)
{
if (!m_scrollingCoordinator)
return;
RunLoop::main().dispatch([scrollingCoordinator = m_scrollingCoordinator, phase] {
scrollingCoordinator->handleWheelEventPhase(phase);
});
}
void ThreadedScrollingTree::setActiveScrollSnapIndices(ScrollingNodeID nodeID, unsigned horizontalIndex, unsigned verticalIndex)
{
if (!m_scrollingCoordinator)
return;
RunLoop::main().dispatch([scrollingCoordinator = m_scrollingCoordinator, nodeID, horizontalIndex, verticalIndex] {
scrollingCoordinator->setActiveScrollSnapIndices(nodeID, horizontalIndex, verticalIndex);
});
}
void ThreadedScrollingTree::deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason)
{
if (!m_scrollingCoordinator)
return;
RunLoop::main().dispatch([scrollingCoordinator = m_scrollingCoordinator, identifier, reason] {
scrollingCoordinator->deferTestsForReason(identifier, reason);
});
}
void ThreadedScrollingTree::removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason)
{
if (!m_scrollingCoordinator)
return;
RunLoop::main().dispatch([scrollingCoordinator = m_scrollingCoordinator, identifier, reason] {
scrollingCoordinator->removeTestDeferralForReason(identifier, reason);
});
}
#endif
}
#endif // ENABLE(ASYNC_SCROLLING)