Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/renderer_host/input/touch_event_queue.h" | 5 #include "content/browser/renderer_host/input/touch_event_queue.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 452 } | 452 } |
| 453 } | 453 } |
| 454 | 454 |
| 455 TouchEventQueue::~TouchEventQueue() { | 455 TouchEventQueue::~TouchEventQueue() { |
| 456 if (!touch_queue_.empty()) | 456 if (!touch_queue_.empty()) |
| 457 STLDeleteElements(&touch_queue_); | 457 STLDeleteElements(&touch_queue_); |
| 458 } | 458 } |
| 459 | 459 |
| 460 void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) { | 460 void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) { |
| 461 TRACE_EVENT0("input", "TouchEventQueue::QueueEvent"); | 461 TRACE_EVENT0("input", "TouchEventQueue::QueueEvent"); |
| 462 LOG(ERROR) << "======= mDebug " << __FUNCTION__ | |
| 463 << " t=" << WebInputEventTraits::GetName(event.event.type) | |
| 464 << " |q|=" << touch_queue_.size(); | |
| 462 | 465 |
| 463 // If the queueing of |event| was triggered by an ack dispatch, defer | 466 // If the queueing of |event| was triggered by an ack dispatch, defer |
| 464 // processing the event until the dispatch has finished. | 467 // processing the event until the dispatch has finished. |
| 465 if (touch_queue_.empty() && !dispatching_touch_ack_) { | 468 if (touch_queue_.empty() && !dispatching_touch_ack_) { |
| 466 // Optimization of the case without touch handlers. Removing this path | 469 // Optimization of the case without touch handlers. Removing this path |
| 467 // yields identical results, but this avoids unnecessary allocations. | 470 // yields identical results, but this avoids unnecessary allocations. |
| 468 PreFilterResult filter_result = FilterBeforeForwarding(event.event); | 471 PreFilterResult filter_result = FilterBeforeForwarding(event.event); |
| 469 if (filter_result != FORWARD_TO_RENDERER) { | 472 if (filter_result != FORWARD_TO_RENDERER) { |
| 470 client_->OnFilteringTouchEvent(event.event); | 473 client_->OnFilteringTouchEvent(event.event); |
| 471 client_->OnTouchEventAck(event, | 474 client_->OnTouchEventAck(event, |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 485 // If the last queued touch-event was a touch-move, and the current event is | 488 // If the last queued touch-event was a touch-move, and the current event is |
| 486 // also a touch-move, then the events can be coalesced into a single event. | 489 // also a touch-move, then the events can be coalesced into a single event. |
| 487 if (touch_queue_.size() > 1) { | 490 if (touch_queue_.size() > 1) { |
| 488 CoalescedWebTouchEvent* last_event = touch_queue_.back(); | 491 CoalescedWebTouchEvent* last_event = touch_queue_.back(); |
| 489 if (last_event->CoalesceEventIfPossible(event)) | 492 if (last_event->CoalesceEventIfPossible(event)) |
| 490 return; | 493 return; |
| 491 } | 494 } |
| 492 touch_queue_.push_back(new CoalescedWebTouchEvent(event, false)); | 495 touch_queue_.push_back(new CoalescedWebTouchEvent(event, false)); |
| 493 } | 496 } |
| 494 | 497 |
| 498 void TouchEventQueue::PrependTouchScrollNotification() { | |
| 499 TRACE_EVENT0("input", "TouchEventQueue::PrependTouchScrollNotification"); | |
| 500 LOG(ERROR) << "======= mDebug " << __FUNCTION__ | |
| 501 << " |q|=" << touch_queue_.size(); | |
| 502 | |
| 503 TouchEventWithLatencyInfo touch; | |
| 504 touch.event.type = WebInputEvent::TouchScrollStarted; | |
| 505 touch.event.uniqueTouchEventId = 12345; | |
| 506 touch.event.touchesLength = 0; | |
| 507 | |
| 508 // Skip the head of the queue to avoid messing up with in-flight event's ack. | |
| 509 auto it = touch_queue_.begin(); | |
| 510 if (it != touch_queue_.end()) | |
| 511 ++it; | |
| 512 touch_queue_.insert(it, new CoalescedWebTouchEvent(touch, false)); | |
| 513 } | |
| 514 | |
| 515 | |
| 495 void TouchEventQueue::ProcessTouchAck(InputEventAckState ack_result, | 516 void TouchEventQueue::ProcessTouchAck(InputEventAckState ack_result, |
| 496 const LatencyInfo& latency_info, | 517 const LatencyInfo& latency_info, |
| 497 const uint32_t unique_touch_event_id) { | 518 const uint32_t unique_touch_event_id) { |
| 498 TRACE_EVENT0("input", "TouchEventQueue::ProcessTouchAck"); | 519 TRACE_EVENT0("input", "TouchEventQueue::ProcessTouchAck"); |
| 499 | 520 |
| 500 // We receive an ack for async touchmove from render. | 521 // We receive an ack for async touchmove from render. |
| 501 if (!ack_pending_async_touchmove_ids_.empty() && | 522 if (!ack_pending_async_touchmove_ids_.empty() && |
| 502 ack_pending_async_touchmove_ids_.front() == unique_touch_event_id) { | 523 ack_pending_async_touchmove_ids_.front() == unique_touch_event_id) { |
| 503 // Remove the first touchmove from the ack_pending_async_touchmove queue. | 524 // Remove the first touchmove from the ack_pending_async_touchmove queue. |
| 504 ack_pending_async_touchmove_ids_.pop_front(); | 525 ack_pending_async_touchmove_ids_.pop_front(); |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 739 | 760 |
| 740 // Note that acking the touch-event may result in multiple gestures being sent | 761 // Note that acking the touch-event may result in multiple gestures being sent |
| 741 // to the renderer, or touch-events being queued. | 762 // to the renderer, or touch-events being queued. |
| 742 base::AutoReset<bool> dispatching_touch_ack(&dispatching_touch_ack_, true); | 763 base::AutoReset<bool> dispatching_touch_ack(&dispatching_touch_ack_, true); |
| 743 acked_event->DispatchAckToClient(ack_result, optional_latency_info, client_); | 764 acked_event->DispatchAckToClient(ack_result, optional_latency_info, client_); |
| 744 } | 765 } |
| 745 | 766 |
| 746 scoped_ptr<CoalescedWebTouchEvent> TouchEventQueue::PopTouchEvent() { | 767 scoped_ptr<CoalescedWebTouchEvent> TouchEventQueue::PopTouchEvent() { |
| 747 DCHECK(!touch_queue_.empty()); | 768 DCHECK(!touch_queue_.empty()); |
| 748 scoped_ptr<CoalescedWebTouchEvent> event(touch_queue_.front()); | 769 scoped_ptr<CoalescedWebTouchEvent> event(touch_queue_.front()); |
| 770 LOG(ERROR) << "======= mDebug " << __FUNCTION__ | |
| 771 << " t=" << WebInputEventTraits::GetName( | |
| 772 event->coalesced_event().event.type) | |
| 773 << " |q|=" << touch_queue_.size(); | |
| 749 touch_queue_.pop_front(); | 774 touch_queue_.pop_front(); |
| 750 return event; | 775 return event; |
| 751 } | 776 } |
| 752 | 777 |
| 753 void TouchEventQueue::SendTouchEventImmediately( | 778 void TouchEventQueue::SendTouchEventImmediately( |
| 754 TouchEventWithLatencyInfo* touch) { | 779 TouchEventWithLatencyInfo* touch) { |
| 755 // For touchmove events, compare touch points position from current event | 780 // For touchmove events, compare touch points position from current event |
| 756 // to last sent event and update touch points state. | 781 // to last sent event and update touch points state. |
| 757 if (touch->event.type == WebInputEvent::TouchMove) { | 782 if (touch->event.type == WebInputEvent::TouchMove) { |
| 758 CHECK(last_sent_touchevent_); | 783 CHECK(last_sent_touchevent_); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 824 return ACK_WITH_NO_CONSUMER_EXISTS; | 849 return ACK_WITH_NO_CONSUMER_EXISTS; |
| 825 | 850 |
| 826 if (touchmove_slop_suppressor_->FilterEvent(event)) | 851 if (touchmove_slop_suppressor_->FilterEvent(event)) |
| 827 return ACK_WITH_NOT_CONSUMED; | 852 return ACK_WITH_NOT_CONSUMED; |
| 828 | 853 |
| 829 if (drop_remaining_touches_in_sequence_ && | 854 if (drop_remaining_touches_in_sequence_ && |
| 830 event.type != WebInputEvent::TouchCancel) { | 855 event.type != WebInputEvent::TouchCancel) { |
| 831 return ACK_WITH_NO_CONSUMER_EXISTS; | 856 return ACK_WITH_NO_CONSUMER_EXISTS; |
| 832 } | 857 } |
| 833 | 858 |
| 859 if (event.type == WebInputEvent::TouchScrollStarted) | |
| 860 return FORWARD_TO_RENDERER; | |
|
tdresser
2016/03/16 14:56:31
Are we returning before this for some TouchScrollS
mustaq
2016/03/16 15:15:40
That's a possibility of course, but not in the cas
| |
| 861 | |
| 834 if (event.type == WebInputEvent::TouchStart) { | 862 if (event.type == WebInputEvent::TouchStart) { |
| 835 return (has_handlers_ || has_handler_for_current_sequence_) | 863 return (has_handlers_ || has_handler_for_current_sequence_) |
| 836 ? FORWARD_TO_RENDERER | 864 ? FORWARD_TO_RENDERER |
| 837 : ACK_WITH_NO_CONSUMER_EXISTS; | 865 : ACK_WITH_NO_CONSUMER_EXISTS; |
| 838 } | 866 } |
| 839 | 867 |
| 840 if (has_handler_for_current_sequence_) { | 868 if (has_handler_for_current_sequence_) { |
| 841 // Only forward a touch if it has a non-stationary pointer that is active | 869 // Only forward a touch if it has a non-stationary pointer that is active |
| 842 // in the current touch sequence. | 870 // in the current touch sequence. |
| 843 for (size_t i = 0; i < event.touchesLength; ++i) { | 871 for (size_t i = 0; i < event.touchesLength; ++i) { |
| 844 const WebTouchPoint& point = event.touches[i]; | 872 const WebTouchPoint& point = event.touches[i]; |
| 845 if (point.state == WebTouchPoint::StateStationary) | 873 if (point.state == WebTouchPoint::StateStationary) |
| 846 continue; | 874 continue; |
| 847 | 875 |
| 848 // |last_sent_touchevent_| will be non-null as long as there is an | 876 // |last_sent_touchevent_| will be non-null as long as there is an |
| 849 // active touch sequence being forwarded to the renderer. | 877 // active touch sequence being forwarded to the renderer. |
| 850 if (!last_sent_touchevent_) | 878 if (!last_sent_touchevent_) |
| 851 continue; | 879 continue; |
| 852 | 880 |
| 853 for (size_t j = 0; j < last_sent_touchevent_->touchesLength; ++j) { | 881 for (size_t j = 0; j < last_sent_touchevent_->touchesLength; ++j) { |
| 854 if (point.id != last_sent_touchevent_->touches[j].id) | 882 if (point.id != last_sent_touchevent_->touches[j].id) |
| 855 continue; | 883 continue; |
| 856 | 884 |
| 857 if (event.type != WebInputEvent::TouchMove) | 885 if (event.type != WebInputEvent::TouchMove) |
| 858 return FORWARD_TO_RENDERER; | 886 return FORWARD_TO_RENDERER; |
|
mustaq
2016/03/16 15:15:40
Here is a possible problem: for touchmoves as well
tdresser
2016/03/16 15:39:15
Yeah, that's causing the behavior you're seeing.
mustaq
2016/03/16 15:44:11
Got the culprit: when sent_touch_event_ is the new
| |
| 859 | 887 |
| 860 // All pointers in TouchMove events may have state as StateMoved, | 888 // All pointers in TouchMove events may have state as StateMoved, |
| 861 // even though none of the pointers have not changed in real. | 889 // even though none of the pointers have not changed in real. |
| 862 // Forward these events when at least one pointer has changed. | 890 // Forward these events when at least one pointer has changed. |
| 863 if (HasPointChanged(last_sent_touchevent_->touches[j], point)) | 891 if (HasPointChanged(last_sent_touchevent_->touches[j], point)) |
| 864 return FORWARD_TO_RENDERER; | 892 return FORWARD_TO_RENDERER; |
| 865 | 893 |
| 866 // This is a TouchMove event for which we have yet to find a | 894 // This is a TouchMove event for which we have yet to find a |
| 867 // non-stationary pointer. Continue checking the next pointers | 895 // non-stationary pointer. Continue checking the next pointers |
| 868 // in the |event|. | 896 // in the |event|. |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 881 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) | 909 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) |
| 882 send_touch_events_async_ = false; | 910 send_touch_events_async_ = false; |
| 883 has_handler_for_current_sequence_ |= | 911 has_handler_for_current_sequence_ |= |
| 884 ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS; | 912 ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS; |
| 885 } else if (WebTouchEventTraits::IsTouchSequenceEnd(event)) { | 913 } else if (WebTouchEventTraits::IsTouchSequenceEnd(event)) { |
| 886 has_handler_for_current_sequence_ = false; | 914 has_handler_for_current_sequence_ = false; |
| 887 } | 915 } |
| 888 } | 916 } |
| 889 | 917 |
| 890 } // namespace content | 918 } // namespace content |
| OLD | NEW |