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>
#include <wtf/TemporaryChange.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> threadedScrollingTree(this);
ScrollingThread::dispatch([threadedScrollingTree, wheelEvent] {
threadedScrollingTree->handleWheelEvent(wheelEvent);
});
return DidHandleEvent;
}
void ThreadedScrollingTree::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
{
ASSERT(ScrollingThread::isCurrentThread());
ScrollingTree::handleWheelEvent(wheelEvent);
}
void ThreadedScrollingTree::invalidate()
{
ASSERT(ScrollingThread::isCurrentThread());
ScrollingCoordinator* scrollingCoordinator = m_scrollingCoordinator.release().leakRef();
RunLoop::main().dispatch([scrollingCoordinator] {
scrollingCoordinator->deref();
});
}
void ThreadedScrollingTree::commitNewTreeState(std::unique_ptr<ScrollingStateTree> scrollingStateTree)
{
ASSERT(ScrollingThread::isCurrentThread());
ScrollingTree::commitNewTreeState(WTF::move(scrollingStateTree));
}
void ThreadedScrollingTree::scrollingTreeNodeDidScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
{
if (!m_scrollingCoordinator)
return;
if (nodeID == rootNode()->scrollingNodeID())
setMainFrameScrollPosition(scrollPosition);
RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
bool localIsHandlingProgrammaticScroll = isHandlingProgrammaticScroll();
RunLoop::main().dispatch([scrollingCoordinator, nodeID, scrollPosition, localIsHandlingProgrammaticScroll, scrollingLayerPositionAction] {
scrollingCoordinator->scheduleUpdateScrollPositionAfterAsyncScroll(nodeID, scrollPosition, localIsHandlingProgrammaticScroll, scrollingLayerPositionAction);
});
}
void ThreadedScrollingTree::currentSnapPointIndicesDidChange(ScrollingNodeID nodeID, unsigned horizontal, unsigned vertical)
{
if (!m_scrollingCoordinator)
return;
RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
RunLoop::main().dispatch([scrollingCoordinator, nodeID, horizontal, vertical] {
scrollingCoordinator->setActiveScrollSnapIndices(nodeID, horizontal, vertical);
});
}
#if PLATFORM(MAC)
void ThreadedScrollingTree::handleWheelEventPhase(PlatformWheelEventPhase phase)
{
if (!m_scrollingCoordinator)
return;
RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
RunLoop::main().dispatch([scrollingCoordinator, phase] {
scrollingCoordinator->handleWheelEventPhase(phase);
});
}
void ThreadedScrollingTree::setActiveScrollSnapIndices(ScrollingNodeID nodeID, unsigned horizontalIndex, unsigned verticalIndex)
{
if (!m_scrollingCoordinator)
return;
RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
RunLoop::main().dispatch([scrollingCoordinator, nodeID, horizontalIndex, verticalIndex] {
scrollingCoordinator->setActiveScrollSnapIndices(nodeID, horizontalIndex, verticalIndex);
});
}
void ThreadedScrollingTree::deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason)
{
if (!m_scrollingCoordinator)
return;
RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
RunLoop::main().dispatch([scrollingCoordinator, identifier, reason] {
scrollingCoordinator->deferTestsForReason(identifier, reason);
});
}
void ThreadedScrollingTree::removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason)
{
if (!m_scrollingCoordinator)
return;
RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
RunLoop::main().dispatch([scrollingCoordinator, identifier, reason] {
scrollingCoordinator->removeTestDeferralForReason(identifier, reason);
});
}
#endif
}
#endif // ENABLE(ASYNC_SCROLLING)