Modified: trunk/Source/WebCore/ChangeLog (157440 => 157441)
--- trunk/Source/WebCore/ChangeLog 2013-10-15 03:48:55 UTC (rev 157440)
+++ trunk/Source/WebCore/ChangeLog 2013-10-15 04:08:16 UTC (rev 157441)
@@ -1,3 +1,27 @@
+2013-10-14 Ryosuke Niwa <[email protected]>
+
+ EventPath::updateTouchLists traverses through EventPath thrice
+ https://bugs.webkit.org/show_bug.cgi?id=122804
+
+ Reviewed by Benjamin Poulain.
+
+ Instead of traversing through EventPath for each TouchList, traverse through TouchList for every EventContext.
+ This paves our way to have one-pass traversal over EventPath, and evetually to remove EventContext altogether.
+
+ This change should also improve the cache hit rate since all Touch objects tend to be allocated at the same time
+ but this performance improvement is probably not observable.
+
+ * dom/EventContext.h:
+ * dom/EventDispatcher.cpp:
+ (WebCore::EventRelatedNodeResolver::EventRelatedNodeResolver): Added a new constructor that takes Touch and
+ and TouchListType. We need to store these two values in order to update EventContext later.
+ (WebCore::EventRelatedNodeResolver::touch): Added,
+ (WebCore::EventRelatedNodeResolver::touchListType): Added.
+ (WebCore::addRelatedNodeResolversForTouchList): Extracted from updateTouchListsInEventPath.
+ (WebCore::EventPath::updateTouchLists): Moved the loop over m_path here. Notice that the outer loop iterates
+ over m_path instead of touchList as done in updateTouchListsInEventPath. The inner loop goes through resolvers
+ and adds Touch objects each EventContext as needed.
+
2013-10-14 Alexey Proskuryakov <[email protected]>
Don't generate a wasteful isObservable check in isReachableFromOpaqueRoots
Modified: trunk/Source/WebCore/dom/EventContext.h (157440 => 157441)
--- trunk/Source/WebCore/dom/EventContext.h 2013-10-15 03:48:55 UTC (rev 157440)
+++ trunk/Source/WebCore/dom/EventContext.h 2013-10-15 04:08:16 UTC (rev 157441)
@@ -91,7 +91,7 @@
virtual void handleLocalEvents(Event&) const OVERRIDE;
virtual bool isTouchEventContext() const OVERRIDE;
- enum TouchListType { Touches, TargetTouches, ChangedTouches, };
+ enum TouchListType { Touches, TargetTouches, ChangedTouches, NotTouchList };
TouchList* touchList(TouchListType type)
{
switch (type) {
@@ -101,6 +101,8 @@
return m_targetTouches.get();
case ChangedTouches:
return m_changedTouches.get();
+ case NotTouchList:
+ break;
}
ASSERT_NOT_REACHED();
return nullptr;
Modified: trunk/Source/WebCore/dom/EventDispatcher.cpp (157440 => 157441)
--- trunk/Source/WebCore/dom/EventDispatcher.cpp 2013-10-15 03:48:55 UTC (rev 157440)
+++ trunk/Source/WebCore/dom/EventDispatcher.cpp 2013-10-15 04:08:16 UTC (rev 157441)
@@ -116,9 +116,31 @@
, m_relatedNodeTreeScope(relatedNode.treeScope())
, m_relatedNodeInCurrentTreeScope(nullptr)
, m_currentTreeScope(nullptr)
+#if ENABLE(TOUCH_EVENTS)
+ , m_touch(0)
+ , m_touchListType(TouchEventContext::NotTouchList)
+#endif
{
}
+#if ENABLE(TOUCH_EVENTS)
+ EventRelatedNodeResolver(Touch& touch, TouchEventContext::TouchListType touchListType)
+ : m_relatedNode(*touch.target()->toNode())
+ , m_relatedNodeTreeScope(m_relatedNode.treeScope())
+ , m_relatedNodeInCurrentTreeScope(nullptr)
+ , m_currentTreeScope(nullptr)
+ , m_touch(&touch)
+ , m_touchListType(touchListType)
+ {
+ ASSERT(touch.target()->toNode());
+ }
+#endif
+
+#if ENABLE(TOUCH_EVENTS)
+ Touch* touch() const { return m_touch; }
+ TouchEventContext::TouchListType touchListType() const { return m_touchListType; }
+#endif
+
Node* moveToParentOrShadowHost(Node& newTarget)
{
TreeScope& newTreeScope = newTarget.treeScope();
@@ -148,6 +170,10 @@
const TreeScope& m_relatedNodeTreeScope;
Node* m_relatedNodeInCurrentTreeScope;
TreeScope* m_currentTreeScope;
+#if ENABLE(TOUCH_EVENTS)
+ Touch* m_touch;
+ TouchEventContext::TouchListType m_touchListType;
+#endif
};
inline EventTarget& eventTargetRespectingTargetRules(Node& referenceNode)
@@ -405,29 +431,35 @@
}
#if ENABLE(TOUCH_EVENTS)
-void EventPath::updateTouchListsInEventPath(const TouchList* touchList, TouchEventContext::TouchListType touchListType)
+static void addRelatedNodeResolversForTouchList(Vector<EventRelatedNodeResolver, 16>& touchTargetResolvers, TouchList* touchList, TouchEventContext::TouchListType type)
{
- if (!touchList)
- return;
- for (size_t i = 0; i < touchList->length(); ++i) {
- const Touch& touch = *touchList->item(i);
-
- ASSERT(touch.target()->toNode());
- EventRelatedNodeResolver resolver(*touch.target()->toNode());
- size_t eventPathSize = m_path.size();
- for (size_t j = 0; j < eventPathSize; ++j) {
- EventContext& context = *m_path[i];
- Node* nodeInCurrentTreeScope = resolver.moveToParentOrShadowHost(*context.node());
- toTouchEventContext(context).touchList(touchListType)->append(touch.cloneWithNewTarget(nodeInCurrentTreeScope));
- }
- }
+ const size_t touchListSize = touchList->length();
+ for (size_t i = 0; i < touchListSize; ++i)
+ touchTargetResolvers.append(EventRelatedNodeResolver(*touchList->item(i), type));
}
void EventPath::updateTouchLists(const TouchEvent& touchEvent)
{
- updateTouchListsInEventPath(touchEvent.touches(), TouchEventContext::Touches);
- updateTouchListsInEventPath(touchEvent.targetTouches(), TouchEventContext::TargetTouches);
- updateTouchListsInEventPath(touchEvent.changedTouches(), TouchEventContext::ChangedTouches);
+ Vector<EventRelatedNodeResolver, 16> touchTargetResolvers;
+ const size_t touchNodeCount = touchEvent.touches()->length() + touchEvent.targetTouches()->length() + touchEvent.changedTouches()->length();
+ touchTargetResolvers.reserveInitialCapacity(touchNodeCount);
+
+ addRelatedNodeResolversForTouchList(touchTargetResolvers, touchEvent.touches(), TouchEventContext::Touches);
+ addRelatedNodeResolversForTouchList(touchTargetResolvers, touchEvent.targetTouches(), TouchEventContext::TargetTouches);
+ addRelatedNodeResolversForTouchList(touchTargetResolvers, touchEvent.changedTouches(), TouchEventContext::ChangedTouches);
+
+ ASSERT(touchTargetResolvers.size() == touchNodeCount);
+ size_t eventPathSize = m_path.size();
+ for (size_t i = 0; i < eventPathSize; ++i) {
+ TouchEventContext& context = toTouchEventContext(*m_path[i]);
+ Node& nodeToMoveTo = *context.node();
+ for (size_t resolverIndex = 0; resolverIndex < touchNodeCount; ++resolverIndex) {
+ EventRelatedNodeResolver& currentResolver = touchTargetResolvers[resolverIndex];
+ Node* nodeInCurrentTreeScope = currentResolver.moveToParentOrShadowHost(nodeToMoveTo);
+ ASSERT(currentResolver.touch());
+ context.touchList(currentResolver.touchListType())->append(currentResolver.touch()->cloneWithNewTarget(nodeInCurrentTreeScope));
+ }
+ }
}
#endif