| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ui/events/blink/compositor_thread_event_queue.h" |
| |
| #include "base/trace_event/trace_event.h" |
| #include "ui/events/blink/blink_event_util.h" |
| #include "ui/events/blink/web_input_event_traits.h" |
| |
| namespace ui { |
| |
| CompositorThreadEventQueue::CompositorThreadEventQueue() {} |
| |
| CompositorThreadEventQueue::~CompositorThreadEventQueue() {} |
| |
| void CompositorThreadEventQueue::Queue( |
| std::unique_ptr<EventWithCallback> new_event, |
| base::TimeTicks timestamp_now) { |
| if (queue_.empty() || |
| !IsContinuousGestureEvent(new_event->event().GetType()) || |
| !(queue_.back()->CanCoalesceWith(*new_event) || |
| IsCompatibleScrollorPinch(ToWebGestureEvent(new_event->event()), |
| ToWebGestureEvent(queue_.back()->event())))) { |
| if (new_event->first_original_event()) { |
| // Trace could be nested as there might be multiple events in queue. |
| // e.g. |ScrollUpdate|, |ScrollEnd|, and another scroll sequence. |
| TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("input", |
| "CompositorThreadEventQueue::Queue", |
| new_event->first_original_event()); |
| } |
| queue_.emplace_back(std::move(new_event)); |
| return; |
| } |
| |
| if (queue_.back()->CanCoalesceWith(*new_event)) { |
| queue_.back()->CoalesceWith(new_event.get(), timestamp_now); |
| return; |
| } |
| |
| // Extract the last event in queue. |
| std::unique_ptr<EventWithCallback> last_event = std::move(queue_.back()); |
| queue_.pop_back(); |
| DCHECK_LE(last_event->latency_info().trace_id(), |
| new_event->latency_info().trace_id()); |
| LatencyInfo oldest_latency = last_event->latency_info(); |
| base::TimeTicks oldest_creation_timestamp = last_event->creation_timestamp(); |
| auto combined_original_events = |
| std::make_unique<EventWithCallback::OriginalEventList>(); |
| combined_original_events->splice(combined_original_events->end(), |
| last_event->original_events()); |
| combined_original_events->splice(combined_original_events->end(), |
| new_event->original_events()); |
| |
| // Extract the second last event in queue. |
| std::unique_ptr<EventWithCallback> second_last_event = nullptr; |
| if (!queue_.empty() && |
| IsCompatibleScrollorPinch(ToWebGestureEvent(new_event->event()), |
| ToWebGestureEvent(queue_.back()->event()))) { |
| second_last_event = std::move(queue_.back()); |
| queue_.pop_back(); |
| DCHECK_LE(second_last_event->latency_info().trace_id(), |
| oldest_latency.trace_id()); |
| oldest_latency = second_last_event->latency_info(); |
| oldest_creation_timestamp = second_last_event->creation_timestamp(); |
| combined_original_events->splice(combined_original_events->begin(), |
| second_last_event->original_events()); |
| } |
| |
| std::pair<blink::WebGestureEvent, blink::WebGestureEvent> coalesced_events = |
| CoalesceScrollAndPinch( |
| second_last_event ? &ToWebGestureEvent(second_last_event->event()) |
| : nullptr, |
| ToWebGestureEvent(last_event->event()), |
| ToWebGestureEvent(new_event->event())); |
| |
| std::unique_ptr<EventWithCallback> scroll_event = |
| std::make_unique<EventWithCallback>( |
| WebInputEventTraits::Clone(coalesced_events.first), oldest_latency, |
| oldest_creation_timestamp, timestamp_now, nullptr); |
| |
| std::unique_ptr<EventWithCallback> pinch_event = |
| std::make_unique<EventWithCallback>( |
| WebInputEventTraits::Clone(coalesced_events.second), oldest_latency, |
| oldest_creation_timestamp, timestamp_now, |
| std::move(combined_original_events)); |
| |
| queue_.emplace_back(std::move(scroll_event)); |
| queue_.emplace_back(std::move(pinch_event)); |
| } |
| |
| std::unique_ptr<EventWithCallback> CompositorThreadEventQueue::Pop() { |
| std::unique_ptr<EventWithCallback> result; |
| if (!queue_.empty()) { |
| result = std::move(queue_.front()); |
| queue_.pop_front(); |
| } |
| |
| if (result->first_original_event()) { |
| TRACE_EVENT_NESTABLE_ASYNC_END2( |
| "input", "CompositorThreadEventQueue::Queue", |
| result->first_original_event(), "type", result->event().GetType(), |
| "coalesced_count", result->coalesced_count()); |
| } |
| return result; |
| } |
| |
| } // namespace ui |