Changeset 116466 in webkit
- Timestamp:
- May 8, 2012 4:50:52 PM (12 years ago)
- Location:
- trunk/Source/WebKit2
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit2/ChangeLog
r116449 r116466 1 2012-05-06 Jon Lee <jonlee@apple.com> 2 3 [WK2] Push wheel events if there are too many in queue 4 https://bugs.webkit.org/show_bug.cgi?id=85747 5 <rdar://problem/11390790> 6 7 Reviewed by Anders Carlsson. 8 9 It is possible that a whole bunch of messages added to the message queue, or a series 10 of long-running messages, cause unresponsiveness. The reason for this is that we have 11 a scroll event waiting for acknowledgment from the web process before it sends the next 12 event. And in the time between the user has scrolled, causing a large backlog of scroll 13 events to be held in the UI process. 14 15 We should push new scroll events if the queue accumulates too many of them. 16 17 * UIProcess/WebPageProxy.h: The vector m_currentlyProcessedWheelEvents used to hold the 18 series of wheel events that were coalesced and sent as a single wheel event to the web 19 process. When the web process acknowledges this with didReceiveEvent, the UI process 20 cleared that vector, then tried to coalesce the next wheel event to send. Now we might have 21 multiple sets of coalesced wheel events that we are sending to the web process. To keep 22 track of these sets, m_currentlyProcessedWheelEvents now is a queue of Vectors. 23 (WebPageProxy): 24 * UIProcess/WebPageProxy.cpp: Add new constant wheelEventQueueSizeThreshold representing 25 the threshold of scroll events to look for before we start pushing events. 26 (WebKit::canCoalesce): Move static function so that handleWheelEvent() has access. No changes. 27 (WebKit::coalesce): Move static function so that handleWheelEvent() has access. No changes. 28 (WebKit::coalescedWheelEvent): Move static function so that handleWheelEvent() has access. No changes. 29 (WebKit::WebPageProxy::handleWheelEvent): If we are currently waiting for acknowledgment 30 from the web process that a wheel event has been handled, we add it to the queue. We 31 check to see that the queue size is within our threshold before we return early. Otherwise 32 we will start pushing events in the queue. Refactor the rest of the function into 33 processNextQueuedWheelEvent() and sendWheelEvent(). If we are not currently waiting for 34 acknowledgment, nor have events in the queue, then we send the current wheel event. 35 (WebKit::WebPageProxy::processNextQueuedWheelEvent): Try to coalesce events based on the 36 wheel event at the head of the queue, and send that event to the web process. 37 (WebKit::WebPageProxy::sendWheelEvent): Refactored from handleWheelEvent(). 38 (WebKit::WebPageProxy::didReceiveEvent): Instead of clearing m_currentlyProcessedWheelEvents, 39 which contained the set of one coalesced wheel event, we pull the head Vector, which 40 contains the same set of events. Refactor to use processNextQueuedWheelEvent(). 41 1 42 2012-05-08 Timothy Hatcher <timothy@apple.com> 2 43 -
trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp
r116178 r116466 110 110 using namespace WebCore; 111 111 112 // Represents the number of wheel events we can hold in the queue before we start pushing them preemptively. 113 static const unsigned wheelEventQueueSizeThreshold = 10; 114 112 115 namespace WebKit { 113 116 … … 986 989 } 987 990 991 #if MERGE_WHEEL_EVENTS 992 static bool canCoalesce(const WebWheelEvent& a, const WebWheelEvent& b) 993 { 994 if (a.position() != b.position()) 995 return false; 996 if (a.globalPosition() != b.globalPosition()) 997 return false; 998 if (a.modifiers() != b.modifiers()) 999 return false; 1000 if (a.granularity() != b.granularity()) 1001 return false; 1002 #if PLATFORM(MAC) 1003 if (a.phase() != b.phase()) 1004 return false; 1005 if (a.momentumPhase() != b.momentumPhase()) 1006 return false; 1007 if (a.hasPreciseScrollingDeltas() != b.hasPreciseScrollingDeltas()) 1008 return false; 1009 #endif 1010 1011 return true; 1012 } 1013 1014 static WebWheelEvent coalesce(const WebWheelEvent& a, const WebWheelEvent& b) 1015 { 1016 ASSERT(canCoalesce(a, b)); 1017 1018 FloatSize mergedDelta = a.delta() + b.delta(); 1019 FloatSize mergedWheelTicks = a.wheelTicks() + b.wheelTicks(); 1020 1021 #if PLATFORM(MAC) 1022 return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.granularity(), b.phase(), b.momentumPhase(), b.hasPreciseScrollingDeltas(), b.modifiers(), b.timestamp(), b.directionInvertedFromDevice()); 1023 #else 1024 return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.granularity(), b.modifiers(), b.timestamp()); 1025 #endif 1026 } 1027 #endif // MERGE_WHEEL_EVENTS 1028 1029 static WebWheelEvent coalescedWheelEvent(Deque<NativeWebWheelEvent>& queue, Vector<NativeWebWheelEvent>& coalescedEvents) 1030 { 1031 ASSERT(!queue.isEmpty()); 1032 ASSERT(coalescedEvents.isEmpty()); 1033 1034 #if MERGE_WHEEL_EVENTS 1035 NativeWebWheelEvent firstEvent = queue.takeFirst(); 1036 coalescedEvents.append(firstEvent); 1037 1038 WebWheelEvent event = firstEvent; 1039 while (!queue.isEmpty() && canCoalesce(event, queue.first())) { 1040 NativeWebWheelEvent firstEvent = queue.takeFirst(); 1041 coalescedEvents.append(firstEvent); 1042 event = coalesce(event, firstEvent); 1043 } 1044 1045 return event; 1046 #else 1047 while (!queue.isEmpty()) 1048 coalescedEvents.append(queue.takeFirst()); 1049 return coalescedEvents.last(); 1050 #endif 1051 } 1052 988 1053 void WebPageProxy::handleWheelEvent(const NativeWebWheelEvent& event) 989 1054 { … … 993 1058 if (!m_currentlyProcessedWheelEvents.isEmpty()) { 994 1059 m_wheelEventQueue.append(event); 995 return; 996 } 997 998 m_currentlyProcessedWheelEvents.append(event); 999 1060 if (m_wheelEventQueue.size() < wheelEventQueueSizeThreshold) 1061 return; 1062 // The queue has too many wheel events, so push a new event. 1063 } 1064 1065 if (!m_wheelEventQueue.isEmpty()) { 1066 processNextQueuedWheelEvent(); 1067 return; 1068 } 1069 1070 OwnPtr<Vector<NativeWebWheelEvent> > coalescedWheelEvent = adoptPtr(new Vector<NativeWebWheelEvent>); 1071 coalescedWheelEvent->append(event); 1072 m_currentlyProcessedWheelEvents.append(coalescedWheelEvent.release()); 1073 sendWheelEvent(event); 1074 } 1075 1076 void WebPageProxy::processNextQueuedWheelEvent() 1077 { 1078 OwnPtr<Vector<NativeWebWheelEvent> > nextCoalescedEvent = adoptPtr(new Vector<NativeWebWheelEvent>); 1079 WebWheelEvent nextWheelEvent = coalescedWheelEvent(m_wheelEventQueue, *nextCoalescedEvent.get()); 1080 m_currentlyProcessedWheelEvents.append(nextCoalescedEvent.release()); 1081 sendWheelEvent(nextWheelEvent); 1082 } 1083 1084 void WebPageProxy::sendWheelEvent(const WebWheelEvent& event) 1085 { 1000 1086 process()->responsivenessTimer()->start(); 1001 1087 … … 1004 1090 process()->sendSync(Messages::WebPage::WheelEventSyncForTesting(event), Messages::WebPage::WheelEventSyncForTesting::Reply(handled), m_pageID); 1005 1091 didReceiveEvent(event.type(), handled); 1006 } else 1007 process()->send(Messages::EventDispatcher::WheelEvent(m_pageID, event, canGoBack(), canGoForward()), 0); 1092 return; 1093 } 1094 1095 process()->send(Messages::EventDispatcher::WheelEvent(m_pageID, event, canGoBack(), canGoForward()), 0); 1008 1096 } 1009 1097 … … 2968 3056 } 2969 3057 2970 #if MERGE_WHEEL_EVENTS2971 static bool canCoalesce(const WebWheelEvent& a, const WebWheelEvent& b)2972 {2973 if (a.position() != b.position())2974 return false;2975 if (a.globalPosition() != b.globalPosition())2976 return false;2977 if (a.modifiers() != b.modifiers())2978 return false;2979 if (a.granularity() != b.granularity())2980 return false;2981 #if PLATFORM(MAC)2982 if (a.phase() != b.phase())2983 return false;2984 if (a.momentumPhase() != b.momentumPhase())2985 return false;2986 if (a.hasPreciseScrollingDeltas() != b.hasPreciseScrollingDeltas())2987 return false;2988 #endif2989 2990 return true;2991 }2992 2993 static WebWheelEvent coalesce(const WebWheelEvent& a, const WebWheelEvent& b)2994 {2995 ASSERT(canCoalesce(a, b));2996 2997 FloatSize mergedDelta = a.delta() + b.delta();2998 FloatSize mergedWheelTicks = a.wheelTicks() + b.wheelTicks();2999 3000 #if PLATFORM(MAC)3001 return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.granularity(), b.phase(), b.momentumPhase(), b.hasPreciseScrollingDeltas(), b.modifiers(), b.timestamp(), b.directionInvertedFromDevice());3002 #else3003 return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.granularity(), b.modifiers(), b.timestamp());3004 #endif3005 }3006 #endif3007 3008 static WebWheelEvent coalescedWheelEvent(Deque<NativeWebWheelEvent>& queue, Vector<NativeWebWheelEvent>& coalescedEvents)3009 {3010 ASSERT(!queue.isEmpty());3011 ASSERT(coalescedEvents.isEmpty());3012 3013 #if MERGE_WHEEL_EVENTS3014 NativeWebWheelEvent firstEvent = queue.takeFirst();3015 coalescedEvents.append(firstEvent);3016 3017 WebWheelEvent event = firstEvent;3018 while (!queue.isEmpty() && canCoalesce(event, queue.first())) {3019 NativeWebWheelEvent firstEvent = queue.takeFirst();3020 coalescedEvents.append(firstEvent);3021 event = coalesce(event, firstEvent);3022 }3023 3024 return event;3025 #else3026 while (!queue.isEmpty())3027 coalescedEvents.append(queue.takeFirst());3028 return coalescedEvents.last();3029 #endif3030 }3031 3032 3058 void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled) 3033 3059 { … … 3092 3118 ASSERT(!m_currentlyProcessedWheelEvents.isEmpty()); 3093 3119 3120 OwnPtr<Vector<NativeWebWheelEvent> > oldestCoalescedEvent = m_currentlyProcessedWheelEvents.takeFirst(); 3121 3094 3122 // FIXME: Dispatch additional events to the didNotHandleWheelEvent client function. 3095 3123 if (!handled && m_uiClient.implementsDidNotHandleWheelEvent()) 3096 m_uiClient.didNotHandleWheelEvent(this, m_currentlyProcessedWheelEvents.last()); 3097 3098 m_currentlyProcessedWheelEvents.clear(); 3099 3100 if (!m_wheelEventQueue.isEmpty()) { 3101 WebWheelEvent newWheelEvent = coalescedWheelEvent(m_wheelEventQueue, m_currentlyProcessedWheelEvents); 3102 3103 process()->responsivenessTimer()->start(); 3104 process()->send(Messages::EventDispatcher::WheelEvent(m_pageID, newWheelEvent, canGoBack(), canGoForward()), 0); 3105 } 3106 3124 m_uiClient.didNotHandleWheelEvent(this, oldestCoalescedEvent->last()); 3125 3126 if (!m_wheelEventQueue.isEmpty()) 3127 processNextQueuedWheelEvent(); 3107 3128 break; 3108 3129 } -
trunk/Source/WebKit2/UIProcess/WebPageProxy.h
r115650 r116466 904 904 #endif 905 905 906 void processNextQueuedWheelEvent(); 907 void sendWheelEvent(const WebWheelEvent&); 908 906 909 PageClient* m_pageClient; 907 910 WebLoaderClient m_loaderClient; … … 1025 1028 Deque<NativeWebKeyboardEvent> m_keyEventQueue; 1026 1029 Deque<NativeWebWheelEvent> m_wheelEventQueue; 1027 Vector<NativeWebWheelEvent> m_currentlyProcessedWheelEvents;1030 Deque<OwnPtr<Vector<NativeWebWheelEvent> > > m_currentlyProcessedWheelEvents; 1028 1031 1029 1032 bool m_processingMouseMoveEvent;
Note: See TracChangeset
for help on using the changeset viewer.