Commit 7d1d3be2 authored by Ella Ge's avatar Ella Ge Committed by Commit Bot

Add scroll prediction to AverageLag metric

This CL adds another field predicted_scroll_update_delta to keeps the
scroll delta after prediction. And also updates the AverageLag to
take the predicted_scroll_update_delta into account.

Bug: 946212
Change-Id: I1ba2bc5bd644c630d53d7f02d6ab4c4c4259f09b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1549346
Commit-Queue: Ella Ge <eirage@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarTimothy Dresser <tdresser@chromium.org>
Cr-Commit-Position: refs/heads/master@{#648709}
parent 869eaa37
...@@ -57,16 +57,13 @@ bool WasHandled(InputEventAckState state) { ...@@ -57,16 +57,13 @@ bool WasHandled(InputEventAckState state) {
std::unique_ptr<InputEvent> ScaleEvent(const WebInputEvent& event, std::unique_ptr<InputEvent> ScaleEvent(const WebInputEvent& event,
double scale, double scale,
const ui::LatencyInfo latency_info) { const ui::LatencyInfo& latency_info) {
std::unique_ptr<blink::WebInputEvent> event_in_viewport = std::unique_ptr<blink::WebInputEvent> event_in_viewport =
ui::ScaleWebInputEvent(event, scale); ui::ScaleWebInputEvent(event, scale);
if (event_in_viewport) { if (event_in_viewport) {
ui::LatencyInfo scaled_latency_info(latency_info);
scaled_latency_info.set_scroll_update_delta(
latency_info.scroll_update_delta() * scale);
return std::make_unique<InputEvent>( return std::make_unique<InputEvent>(
ui::WebScopedInputEvent(event_in_viewport.release()), ui::WebScopedInputEvent(event_in_viewport.release()),
scaled_latency_info); latency_info.ScaledBy(scale));
} }
return std::make_unique<InputEvent>(ui::WebInputEventTraits::Clone(event), return std::make_unique<InputEvent>(ui::WebInputEventTraits::Clone(event),
......
...@@ -174,6 +174,8 @@ void RenderWidgetHostLatencyTracker::OnInputEvent( ...@@ -174,6 +174,8 @@ void RenderWidgetHostLatencyTracker::OnInputEvent(
has_seen_first_gesture_scroll_update_ = true; has_seen_first_gesture_scroll_update_ = true;
latency->set_scroll_update_delta( latency->set_scroll_update_delta(
static_cast<const WebGestureEvent&>(event).data.scroll_update.delta_y); static_cast<const WebGestureEvent&>(event).data.scroll_update.delta_y);
latency->set_predicted_scroll_update_delta(
static_cast<const WebGestureEvent&>(event).data.scroll_update.delta_y);
} }
} }
......
...@@ -50,7 +50,8 @@ class EventWithCallback { ...@@ -50,7 +50,8 @@ class EventWithCallback {
const blink::WebInputEvent& event() const { return *event_; } const blink::WebInputEvent& event() const { return *event_; }
blink::WebInputEvent* event_pointer() { return event_.get(); } blink::WebInputEvent* event_pointer() { return event_.get(); }
const LatencyInfo latency_info() const { return latency_; } const LatencyInfo& latency_info() const { return latency_; }
LatencyInfo* mutable_latency_info() { return &latency_; }
base::TimeTicks creation_timestamp() const { return creation_timestamp_; } base::TimeTicks creation_timestamp() const { return creation_timestamp_; }
base::TimeTicks last_coalesced_timestamp() const { base::TimeTicks last_coalesced_timestamp() const {
return last_coalesced_timestamp_; return last_coalesced_timestamp_;
......
...@@ -263,7 +263,6 @@ void InputHandlerProxy::DispatchSingleInputEvent( ...@@ -263,7 +263,6 @@ void InputHandlerProxy::DispatchSingleInputEvent(
std::unique_ptr<EventWithCallback> event_with_callback, std::unique_ptr<EventWithCallback> event_with_callback,
const base::TimeTicks now) { const base::TimeTicks now) {
ui::LatencyInfo monitored_latency_info = event_with_callback->latency_info(); ui::LatencyInfo monitored_latency_info = event_with_callback->latency_info();
std::unique_ptr<cc::SwapPromiseMonitor> latency_info_swap_promise_monitor = std::unique_ptr<cc::SwapPromiseMonitor> latency_info_swap_promise_monitor =
input_handler_->CreateLatencyInfoSwapPromiseMonitor( input_handler_->CreateLatencyInfoSwapPromiseMonitor(
&monitored_latency_info); &monitored_latency_info);
...@@ -301,12 +300,8 @@ void InputHandlerProxy::DispatchQueuedInputEvents() { ...@@ -301,12 +300,8 @@ void InputHandlerProxy::DispatchQueuedInputEvents() {
base::TimeTicks now = tick_clock_->NowTicks(); base::TimeTicks now = tick_clock_->NowTicks();
while (!compositor_event_queue_->empty()) { while (!compositor_event_queue_->empty()) {
std::unique_ptr<EventWithCallback> event_with_callback = std::unique_ptr<EventWithCallback> event_with_callback =
compositor_event_queue_->Pop(); scroll_predictor_->ResampleScrollEvents(compositor_event_queue_->Pop(),
if (scroll_predictor_) { now);
scroll_predictor_->ResampleScrollEvents(
event_with_callback->original_events(), now,
event_with_callback->event_pointer());
}
DispatchSingleInputEvent(std::move(event_with_callback), now); DispatchSingleInputEvent(std::move(event_with_callback), now);
} }
......
...@@ -55,20 +55,23 @@ void ScrollPredictor::ResetOnGestureScrollBegin(const WebGestureEvent& event) { ...@@ -55,20 +55,23 @@ void ScrollPredictor::ResetOnGestureScrollBegin(const WebGestureEvent& event) {
} }
} }
void ScrollPredictor::ResampleScrollEvents( std::unique_ptr<EventWithCallback> ScrollPredictor::ResampleScrollEvents(
const EventWithCallback::OriginalEventList& original_events, std::unique_ptr<EventWithCallback> event_with_callback,
base::TimeTicks frame_time, base::TimeTicks frame_time) {
WebInputEvent* event) {
if (!should_resample_scroll_events_) if (!should_resample_scroll_events_)
return; return event_with_callback;
const EventWithCallback::OriginalEventList& original_events =
event_with_callback->original_events();
if (event->GetType() == WebInputEvent::kGestureScrollUpdate) { if (event_with_callback->event().GetType() ==
WebInputEvent::kGestureScrollUpdate) {
// TODO(eirage): When scroll events are coalesced with pinch, we can have // TODO(eirage): When scroll events are coalesced with pinch, we can have
// empty original event list. In that case, we can't use the original events // empty original event list. In that case, we can't use the original events
// to update the prediction. We don't want to use the aggregated event to // to update the prediction. We don't want to use the aggregated event to
// update because of the event time stamp, so skip the prediction for now. // update because of the event time stamp, so skip the prediction for now.
if (original_events.empty()) if (original_events.empty())
return; return event_with_callback;
TRACE_EVENT_BEGIN0("input", "ScrollPredictor::ResampleScrollEvents"); TRACE_EVENT_BEGIN0("input", "ScrollPredictor::ResampleScrollEvents");
...@@ -80,14 +83,18 @@ void ScrollPredictor::ResampleScrollEvents( ...@@ -80,14 +83,18 @@ void ScrollPredictor::ResampleScrollEvents(
UpdatePrediction(coalesced_event.event_, frame_time); UpdatePrediction(coalesced_event.event_, frame_time);
if (enable_resampling_ && should_resample_scroll_events_) if (enable_resampling_ && should_resample_scroll_events_)
ResampleEvent(frame_time, event); ResampleEvent(frame_time, event_with_callback->event_pointer(),
event_with_callback->mutable_latency_info());
TRACE_EVENT_END2("input", "ScrollPredictor::ResampleScrollEvents", TRACE_EVENT_END2("input", "ScrollPredictor::ResampleScrollEvents",
"OriginalPosition", current_accumulated_delta_.ToString(), "OriginalPosition", current_accumulated_delta_.ToString(),
"PredictedPosition", last_accumulated_delta_.ToString()); "PredictedPosition", last_accumulated_delta_.ToString());
} else if (event->GetType() == WebInputEvent::kGestureScrollEnd) { } else if (event_with_callback->event().GetType() ==
WebInputEvent::kGestureScrollEnd) {
should_resample_scroll_events_ = false; should_resample_scroll_events_ = false;
} }
return event_with_callback;
} }
void ScrollPredictor::Reset() { void ScrollPredictor::Reset() {
...@@ -118,7 +125,8 @@ void ScrollPredictor::UpdatePrediction(const WebScopedInputEvent& event, ...@@ -118,7 +125,8 @@ void ScrollPredictor::UpdatePrediction(const WebScopedInputEvent& event,
} }
void ScrollPredictor::ResampleEvent(base::TimeTicks time_stamp, void ScrollPredictor::ResampleEvent(base::TimeTicks time_stamp,
WebInputEvent* event) { WebInputEvent* event,
LatencyInfo* latency_info) {
DCHECK(event->GetType() == WebInputEvent::kGestureScrollUpdate); DCHECK(event->GetType() == WebInputEvent::kGestureScrollUpdate);
WebGestureEvent* gesture_event = static_cast<WebGestureEvent*>(event); WebGestureEvent* gesture_event = static_cast<WebGestureEvent*>(event);
...@@ -145,6 +153,8 @@ void ScrollPredictor::ResampleEvent(base::TimeTicks time_stamp, ...@@ -145,6 +153,8 @@ void ScrollPredictor::ResampleEvent(base::TimeTicks time_stamp,
(new_delta.y() * gesture_event->data.scroll_update.delta_y < 0) (new_delta.y() * gesture_event->data.scroll_update.delta_y < 0)
? 0 ? 0
: new_delta.y(); : new_delta.y();
// Sync the predicted delta_y to latency_info for AverageLag metric.
latency_info->set_predicted_scroll_update_delta(new_delta.y());
last_accumulated_delta_.Offset(gesture_event->data.scroll_update.delta_x, last_accumulated_delta_.Offset(gesture_event->data.scroll_update.delta_x,
gesture_event->data.scroll_update.delta_y); gesture_event->data.scroll_update.delta_y);
......
...@@ -35,10 +35,9 @@ class ScrollPredictor { ...@@ -35,10 +35,9 @@ class ScrollPredictor {
// Resampling GestureScrollUpdate events. Updates the prediction with events // Resampling GestureScrollUpdate events. Updates the prediction with events
// in original events list, and apply the prediction to the aggregated GSU // in original events list, and apply the prediction to the aggregated GSU
// event if enable_resampling is true. // event if enable_resampling is true.
void ResampleScrollEvents( std::unique_ptr<EventWithCallback> ResampleScrollEvents(
const EventWithCallback::OriginalEventList& original_events, std::unique_ptr<EventWithCallback> event_with_callback,
base::TimeTicks frame_time, base::TimeTicks frame_time);
blink::WebInputEvent* event);
private: private:
friend class test::InputHandlerProxyEventQueueTest; friend class test::InputHandlerProxyEventQueueTest;
...@@ -53,7 +52,9 @@ class ScrollPredictor { ...@@ -53,7 +52,9 @@ class ScrollPredictor {
base::TimeTicks frame_time); base::TimeTicks frame_time);
// Apply resampled deltaX/deltaY to gesture events // Apply resampled deltaX/deltaY to gesture events
void ResampleEvent(base::TimeTicks frame_time, blink::WebInputEvent* event); void ResampleEvent(base::TimeTicks frame_time,
blink::WebInputEvent* event,
LatencyInfo* latency_info);
// Reports prediction accuracy UMA histogram. Calculates position in current // Reports prediction accuracy UMA histogram. Calculates position in current
// event time and compute the distance between real event and predicted event. // event time and compute the distance between real event and predicted event.
......
...@@ -78,12 +78,18 @@ class ScrollPredictorTest : public testing::Test { ...@@ -78,12 +78,18 @@ class ScrollPredictorTest : public testing::Test {
void HandleResampleScrollEvents(WebScopedInputEvent& event, void HandleResampleScrollEvents(WebScopedInputEvent& event,
double time_delta_in_milliseconds = 0) { double time_delta_in_milliseconds = 0) {
scroll_predictor_->ResampleScrollEvents( std::unique_ptr<EventWithCallback> event_with_callback =
original_events_, std::make_unique<EventWithCallback>(std::move(event), LatencyInfo(),
base::TimeTicks(),
base::NullCallback());
event_with_callback->original_events() = std::move(original_events_);
event_with_callback = scroll_predictor_->ResampleScrollEvents(
std::move(event_with_callback),
WebInputEvent::GetStaticTimeStampForTests() + WebInputEvent::GetStaticTimeStampForTests() +
base::TimeDelta::FromMillisecondsD(time_delta_in_milliseconds), base::TimeDelta::FromMillisecondsD(time_delta_in_milliseconds));
event.get());
original_events_.clear(); event = WebInputEventTraits::Clone(event_with_callback->event());
} }
bool PredictionAvailable(ui::InputPredictor::InputData* result, bool PredictionAvailable(ui::InputPredictor::InputData* result,
......
...@@ -90,7 +90,7 @@ void AverageLagTracker::AddLatencyInFrame( ...@@ -90,7 +90,7 @@ void AverageLagTracker::AddLatencyInFrame(
last_event_timestamp_ = event_timestamp; last_event_timestamp_ = event_timestamp;
last_event_accumulated_delta_ += latency.scroll_update_delta(); last_event_accumulated_delta_ += latency.scroll_update_delta();
last_rendered_accumulated_delta_ += latency.scroll_update_delta(); last_rendered_accumulated_delta_ += latency.predicted_scroll_update_delta();
} }
float AverageLagTracker::LagBetween(base::TimeTicks front_time, float AverageLagTracker::LagBetween(base::TimeTicks front_time,
......
...@@ -30,9 +30,13 @@ class AverageLagTrackerTest : public testing::Test { ...@@ -30,9 +30,13 @@ class AverageLagTrackerTest : public testing::Test {
void SyntheticTouchScrollBeginLatencyInfo(base::TimeTicks event_time, void SyntheticTouchScrollBeginLatencyInfo(base::TimeTicks event_time,
base::TimeTicks frame_time, base::TimeTicks frame_time,
float delta) { float delta,
float predicted_delta = 0) {
ui::LatencyInfo touch_latency(ui::SourceEventType::TOUCH); ui::LatencyInfo touch_latency(ui::SourceEventType::TOUCH);
touch_latency.set_scroll_update_delta(delta); touch_latency.set_scroll_update_delta(delta);
touch_latency.set_predicted_scroll_update_delta(
predicted_delta != 0 ? predicted_delta : delta);
touch_latency.AddLatencyNumberWithTimestamp( touch_latency.AddLatencyNumberWithTimestamp(
ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT, ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT,
event_time, 1); event_time, 1);
...@@ -45,9 +49,12 @@ class AverageLagTrackerTest : public testing::Test { ...@@ -45,9 +49,12 @@ class AverageLagTrackerTest : public testing::Test {
void SyntheticTouchScrollUpdateLatencyInfo(base::TimeTicks event_time, void SyntheticTouchScrollUpdateLatencyInfo(base::TimeTicks event_time,
base::TimeTicks frame_time, base::TimeTicks frame_time,
float delta) { float delta,
float predicted_delta = 0) {
ui::LatencyInfo touch_latency(ui::SourceEventType::TOUCH); ui::LatencyInfo touch_latency(ui::SourceEventType::TOUCH);
touch_latency.set_scroll_update_delta(delta); touch_latency.set_scroll_update_delta(delta);
touch_latency.set_predicted_scroll_update_delta(
predicted_delta != 0 ? predicted_delta : delta);
touch_latency.AddLatencyNumberWithTimestamp( touch_latency.AddLatencyNumberWithTimestamp(
ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT, event_time, ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT, event_time,
1); 1);
...@@ -244,5 +251,125 @@ TEST_F(AverageLagTrackerTest, ChangeDirectionInFrame) { ...@@ -244,5 +251,125 @@ TEST_F(AverageLagTrackerTest, ChangeDirectionInFrame) {
ElementsAre(Bucket(12, 1))); ElementsAre(Bucket(12, 1)));
} }
// A simple case without scroll prediction to compare with the two with
// prediction cases below.
TEST_F(AverageLagTrackerTest, NoScrollPrediction) {
// ScrollBegin, at t=5, finter_pos=5px.
base::TimeTicks event_time = MillisecondsToTimeTicks(5);
base::TimeTicks frame_time = MillisecondsToTimeTicks(10);
SyntheticTouchScrollBeginLatencyInfo(event_time, frame_time,
5 /* scroll_delta */);
// ScrollUpdate, at t=15, finger_pos=15px.
event_time = MillisecondsToTimeTicks(15);
frame_time = MillisecondsToTimeTicks(20);
SyntheticTouchScrollUpdateLatencyInfo(event_time, frame_time,
10 /* scroll_delta */);
// ScrollUpdate, at t=25, finger_pos=25px.
event_time = MillisecondsToTimeTicks(25);
frame_time = MillisecondsToTimeTicks(30);
SyntheticTouchScrollUpdateLatencyInfo(event_time, frame_time,
10 /* scroll_delta */);
// Another ScrollBegin to flush unfinished frames.
event_time = MillisecondsToTimeTicks(1000);
frame_time = MillisecondsToTimeTicks(1000);
SyntheticTouchScrollBeginLatencyInfo(event_time, frame_time, 0);
// Prediction hasn't take affect on ScrollBegin so it'll stay the same.
EXPECT_THAT(histogram_tester().GetAllSamples(
"Event.Latency.ScrollBegin.Touch.AverageLag"),
ElementsAre(Bucket(7, 1)));
// At t=10, finger_pos = 10px, rendered_pos = 5px.
// At t=20, finger_pos = 20px, rendered_pos = 15px.
// At t=30, finger_pos = 25px, rendered_pos = 25px.
// AverageLag = ((5px+15px)*10ms/2 + (5px+10px)*5ms/2 + 10px*5ms)/20ms
// = 9.375
EXPECT_THAT(histogram_tester().GetAllSamples(
"Event.Latency.ScrollUpdate.Touch.AverageLag"),
ElementsAre(Bucket(9, 1)));
}
// Test AverageLag with perfect scroll prediction.
TEST_F(AverageLagTrackerTest, ScrollPrediction) {
// ScrollBegin, at t=5, finter_pos=5px.
// Predict frame_time=10, predicted_pos = 10px.
base::TimeTicks event_time = MillisecondsToTimeTicks(5);
base::TimeTicks frame_time = MillisecondsToTimeTicks(10);
SyntheticTouchScrollBeginLatencyInfo(
event_time, frame_time, 5 /* scroll_delta */, 10 /* predicted_delta */);
// ScrollUpdate, at t=15, finger_pos=15px.
// Predict frame_time=20, predicted_pos = 20px.
event_time = MillisecondsToTimeTicks(15);
frame_time = MillisecondsToTimeTicks(20);
SyntheticTouchScrollUpdateLatencyInfo(
event_time, frame_time, 10 /* scroll_delta */, 10 /* predicted_delta */);
// ScrollUpdate, at t=25, finger_pos=25px.
// Predict frame_time=30, predicted_pos = 30px.
event_time = MillisecondsToTimeTicks(25);
frame_time = MillisecondsToTimeTicks(30);
SyntheticTouchScrollUpdateLatencyInfo(
event_time, frame_time, 10 /* scroll_delta */, 10 /* predicted_delta */);
// Another ScrollBegin to flush unfinished frames.
event_time = MillisecondsToTimeTicks(1000);
frame_time = MillisecondsToTimeTicks(1000);
SyntheticTouchScrollBeginLatencyInfo(event_time, frame_time, 0);
// Prediction hasn't take affect on ScrollBegin so it'll stay the same.
EXPECT_THAT(histogram_tester().GetAllSamples(
"Event.Latency.ScrollBegin.Touch.AverageLag"),
ElementsAre(Bucket(7, 1)));
// At t=10, finger_pos = 10px, rendered_pos = 10px.
// At t=20, finger_pos = 20px, rendered_pos = 20px.
// At t=30, finger_pos = 25px, rendered_pos = 30px.
// AverageLag = ((0px+10px)*10ms/2 + (0px+5px)*10ms/2 + 5px*5ms)/20ms
// = 4.375px
EXPECT_THAT(histogram_tester().GetAllSamples(
"Event.Latency.ScrollUpdate.Touch.AverageLag"),
ElementsAre(Bucket(4, 1)));
}
// Test AverageLag with imperfect scroll prediction.
TEST_F(AverageLagTrackerTest, ImperfectScrollPrediction) {
// ScrollBegin, at t=5, finter_pos=5px.
// Predict frame_time=10, predicted_pos(over) = 12px.
base::TimeTicks event_time = MillisecondsToTimeTicks(5);
base::TimeTicks frame_time = MillisecondsToTimeTicks(10);
SyntheticTouchScrollBeginLatencyInfo(
event_time, frame_time, 5 /* scroll_delta */, 12 /* predicted_delta */);
// ScrollUpdate, at t=15, finger_pos=15px.
// Predict frame_time=20, predicted_pos(under) = 17px.
event_time = MillisecondsToTimeTicks(15);
frame_time = MillisecondsToTimeTicks(20);
SyntheticTouchScrollUpdateLatencyInfo(
event_time, frame_time, 10 /* scroll_delta */, 5 /* predicted_delta */);
// ScrollUpdate, at t=25, finger_pos=25px.
// Predict frame_time=30, predicted_pos(over) = 31px.
event_time = MillisecondsToTimeTicks(25);
frame_time = MillisecondsToTimeTicks(30);
SyntheticTouchScrollUpdateLatencyInfo(
event_time, frame_time, 10 /* scroll_delta */, 14 /* predicted_delta */);
// Another ScrollBegin to flush unfinished frames.
event_time = MillisecondsToTimeTicks(1000);
frame_time = MillisecondsToTimeTicks(1000);
SyntheticTouchScrollBeginLatencyInfo(event_time, frame_time, 0);
EXPECT_THAT(histogram_tester().GetAllSamples(
"Event.Latency.ScrollBegin.Touch.AverageLag"),
ElementsAre(Bucket(7, 1)));
// AverageLag = ((2px*2ms/2+8px*8ms/2)+ ((3px+8px)*5ms/2+8px*5ms))/20ms
// = 5.075px
EXPECT_THAT(histogram_tester().GetAllSamples(
"Event.Latency.ScrollUpdate.Touch.AverageLag"),
ElementsAre(Bucket(5, 1)));
}
} // namespace } // namespace
} // namespace ui } // namespace ui
...@@ -41,6 +41,7 @@ void ParamTraits<ui::LatencyInfo>::Write(base::Pickle* m, const param_type& p) { ...@@ -41,6 +41,7 @@ void ParamTraits<ui::LatencyInfo>::Write(base::Pickle* m, const param_type& p) {
WriteParam(m, p.terminated_); WriteParam(m, p.terminated_);
WriteParam(m, p.source_event_type_); WriteParam(m, p.source_event_type_);
WriteParam(m, p.scroll_update_delta_); WriteParam(m, p.scroll_update_delta_);
WriteParam(m, p.predicted_scroll_update_delta_);
} }
bool ParamTraits<ui::LatencyInfo>::Read(const base::Pickle* m, bool ParamTraits<ui::LatencyInfo>::Read(const base::Pickle* m,
...@@ -65,6 +66,8 @@ bool ParamTraits<ui::LatencyInfo>::Read(const base::Pickle* m, ...@@ -65,6 +66,8 @@ bool ParamTraits<ui::LatencyInfo>::Read(const base::Pickle* m,
return false; return false;
if (!ReadParam(m, iter, &p->scroll_update_delta_)) if (!ReadParam(m, iter, &p->scroll_update_delta_))
return false; return false;
if (!ReadParam(m, iter, &p->predicted_scroll_update_delta_))
return false;
return true; return true;
} }
...@@ -87,6 +90,8 @@ void ParamTraits<ui::LatencyInfo>::Log(const param_type& p, std::string* l) { ...@@ -87,6 +90,8 @@ void ParamTraits<ui::LatencyInfo>::Log(const param_type& p, std::string* l) {
LogParam(p.source_event_type_, l); LogParam(p.source_event_type_, l);
l->append(" "); l->append(" ");
LogParam(p.scroll_update_delta_, l); LogParam(p.scroll_update_delta_, l);
l->append(" ");
LogParam(p.predicted_scroll_update_delta_, l);
} }
} // namespace IPC } // namespace IPC
...@@ -18,6 +18,7 @@ TEST(LatencyInfoParamTraitsTest, Basic) { ...@@ -18,6 +18,7 @@ TEST(LatencyInfoParamTraitsTest, Basic) {
latency.set_trace_id(5); latency.set_trace_id(5);
latency.set_ukm_source_id(10); latency.set_ukm_source_id(10);
latency.set_scroll_update_delta(12.5); latency.set_scroll_update_delta(12.5);
latency.set_predicted_scroll_update_delta(12.5);
ASSERT_FALSE(latency.terminated()); ASSERT_FALSE(latency.terminated());
latency.AddLatencyNumber(INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT); latency.AddLatencyNumber(INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT);
latency.AddLatencyNumber(INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT); latency.AddLatencyNumber(INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT);
...@@ -37,6 +38,8 @@ TEST(LatencyInfoParamTraitsTest, Basic) { ...@@ -37,6 +38,8 @@ TEST(LatencyInfoParamTraitsTest, Basic) {
EXPECT_EQ(latency.ukm_source_id(), output.ukm_source_id()); EXPECT_EQ(latency.ukm_source_id(), output.ukm_source_id());
EXPECT_EQ(latency.terminated(), output.terminated()); EXPECT_EQ(latency.terminated(), output.terminated());
EXPECT_EQ(latency.scroll_update_delta(), output.scroll_update_delta()); EXPECT_EQ(latency.scroll_update_delta(), output.scroll_update_delta());
EXPECT_EQ(latency.predicted_scroll_update_delta(),
output.predicted_scroll_update_delta());
EXPECT_TRUE(output.FindLatency(INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, EXPECT_TRUE(output.FindLatency(INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
nullptr)); nullptr));
......
...@@ -126,7 +126,8 @@ LatencyInfo::LatencyInfo(SourceEventType type) ...@@ -126,7 +126,8 @@ LatencyInfo::LatencyInfo(SourceEventType type)
began_(false), began_(false),
terminated_(false), terminated_(false),
source_event_type_(type), source_event_type_(type),
scroll_update_delta_(0) {} scroll_update_delta_(0),
predicted_scroll_update_delta_(0) {}
LatencyInfo::LatencyInfo(const LatencyInfo& other) = default; LatencyInfo::LatencyInfo(const LatencyInfo& other) = default;
...@@ -139,7 +140,8 @@ LatencyInfo::LatencyInfo(int64_t trace_id, bool terminated) ...@@ -139,7 +140,8 @@ LatencyInfo::LatencyInfo(int64_t trace_id, bool terminated)
began_(false), began_(false),
terminated_(terminated), terminated_(terminated),
source_event_type_(SourceEventType::UNKNOWN), source_event_type_(SourceEventType::UNKNOWN),
scroll_update_delta_(0) {} scroll_update_delta_(0),
predicted_scroll_update_delta_(0) {}
bool LatencyInfo::Verify(const std::vector<LatencyInfo>& latency_info, bool LatencyInfo::Verify(const std::vector<LatencyInfo>& latency_info,
const char* referring_msg) { const char* referring_msg) {
...@@ -325,6 +327,15 @@ void LatencyInfo::CoalesceScrollUpdateWith(const LatencyInfo& other) { ...@@ -325,6 +327,15 @@ void LatencyInfo::CoalesceScrollUpdateWith(const LatencyInfo& other) {
} }
scroll_update_delta_ += other.scroll_update_delta(); scroll_update_delta_ += other.scroll_update_delta();
predicted_scroll_update_delta_ += other.predicted_scroll_update_delta();
}
LatencyInfo LatencyInfo::ScaledBy(float scale) const {
ui::LatencyInfo scaled_latency_info(*this);
scaled_latency_info.set_scroll_update_delta(scroll_update_delta_ * scale);
scaled_latency_info.set_predicted_scroll_update_delta(
predicted_scroll_update_delta_ * scale);
return scaled_latency_info;
} }
std::unique_ptr<base::trace_event::ConvertableToTraceFormat> std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
......
...@@ -174,6 +174,9 @@ class LatencyInfo { ...@@ -174,6 +174,9 @@ class LatencyInfo {
// event's scroll_update_delta and the SCROLL_UPDATE_LAST_EVENT_COMPONENT. // event's scroll_update_delta and the SCROLL_UPDATE_LAST_EVENT_COMPONENT.
void CoalesceScrollUpdateWith(const LatencyInfo& other); void CoalesceScrollUpdateWith(const LatencyInfo& other);
// Scale scroll_update_delta and predicted_scroll_update_delta.
LatencyInfo ScaledBy(float scale) const;
const LatencyMap& latency_components() const { return latency_components_; } const LatencyMap& latency_components() const { return latency_components_; }
const SourceEventType& source_event_type() const { const SourceEventType& source_event_type() const {
...@@ -194,6 +197,12 @@ class LatencyInfo { ...@@ -194,6 +197,12 @@ class LatencyInfo {
const std::string& trace_name() const { return trace_name_; } const std::string& trace_name() const { return trace_name_; }
void set_scroll_update_delta(float delta) { scroll_update_delta_ = delta; } void set_scroll_update_delta(float delta) { scroll_update_delta_ = delta; }
float scroll_update_delta() const { return scroll_update_delta_; } float scroll_update_delta() const { return scroll_update_delta_; }
void set_predicted_scroll_update_delta(float delta) {
predicted_scroll_update_delta_ = delta;
}
float predicted_scroll_update_delta() const {
return predicted_scroll_update_delta_;
}
private: private:
void AddLatencyNumberWithTimestampImpl(LatencyComponentType component, void AddLatencyNumberWithTimestampImpl(LatencyComponentType component,
...@@ -226,6 +235,7 @@ class LatencyInfo { ...@@ -226,6 +235,7 @@ class LatencyInfo {
SourceEventType source_event_type_; SourceEventType source_event_type_;
float scroll_update_delta_; float scroll_update_delta_;
float predicted_scroll_update_delta_;
#if !defined(OS_IOS) #if !defined(OS_IOS)
friend struct IPC::ParamTraits<ui::LatencyInfo>; friend struct IPC::ParamTraits<ui::LatencyInfo>;
......
...@@ -82,4 +82,5 @@ struct LatencyInfo { ...@@ -82,4 +82,5 @@ struct LatencyInfo {
bool terminated; bool terminated;
SourceEventType source_event_type; SourceEventType source_event_type;
float scroll_update_delta; float scroll_update_delta;
float predicted_scroll_update_delta;
}; };
...@@ -121,6 +121,12 @@ float StructTraits<ui::mojom::LatencyInfoDataView, ...@@ -121,6 +121,12 @@ float StructTraits<ui::mojom::LatencyInfoDataView,
return info.scroll_update_delta(); return info.scroll_update_delta();
} }
// static
float StructTraits<ui::mojom::LatencyInfoDataView, ui::LatencyInfo>::
predicted_scroll_update_delta(const ui::LatencyInfo& info) {
return info.predicted_scroll_update_delta();
}
// static // static
bool StructTraits<ui::mojom::LatencyInfoDataView, ui::LatencyInfo>::Read( bool StructTraits<ui::mojom::LatencyInfoDataView, ui::LatencyInfo>::Read(
ui::mojom::LatencyInfoDataView data, ui::mojom::LatencyInfoDataView data,
...@@ -136,6 +142,7 @@ bool StructTraits<ui::mojom::LatencyInfoDataView, ui::LatencyInfo>::Read( ...@@ -136,6 +142,7 @@ bool StructTraits<ui::mojom::LatencyInfoDataView, ui::LatencyInfo>::Read(
out->terminated_ = data.terminated(); out->terminated_ = data.terminated();
out->source_event_type_ = MojoSourceEventTypeToUI(data.source_event_type()); out->source_event_type_ = MojoSourceEventTypeToUI(data.source_event_type());
out->scroll_update_delta_ = data.scroll_update_delta(); out->scroll_update_delta_ = data.scroll_update_delta();
out->predicted_scroll_update_delta_ = data.predicted_scroll_update_delta();
return true; return true;
} }
......
...@@ -55,6 +55,7 @@ struct StructTraits<ui::mojom::LatencyInfoDataView, ui::LatencyInfo> { ...@@ -55,6 +55,7 @@ struct StructTraits<ui::mojom::LatencyInfoDataView, ui::LatencyInfo> {
static ui::mojom::SourceEventType source_event_type( static ui::mojom::SourceEventType source_event_type(
const ui::LatencyInfo& info); const ui::LatencyInfo& info);
static float scroll_update_delta(const ui::LatencyInfo& info); static float scroll_update_delta(const ui::LatencyInfo& info);
static float predicted_scroll_update_delta(const ui::LatencyInfo& info);
static bool Read(ui::mojom::LatencyInfoDataView data, ui::LatencyInfo* out); static bool Read(ui::mojom::LatencyInfoDataView data, ui::LatencyInfo* out);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment