blob: f78d742b43ab43df35c13bc7b856dc2c6ab10f90 [file] [log] [blame]
// 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/memory/ptr_util.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()) ||
!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();
oldest_latency.set_coalesced();
base::TimeTicks oldest_creation_timestamp = last_event->creation_timestamp();
auto combined_original_events =
base::MakeUnique<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_latency.set_coalesced();
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 =
base::MakeUnique<EventWithCallback>(
WebInputEventTraits::Clone(coalesced_events.first), oldest_latency,
oldest_creation_timestamp, timestamp_now, nullptr);
std::unique_ptr<EventWithCallback> pinch_event =
base::MakeUnique<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