switch (type) {
CASE_TYPE(INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_BEGIN_PLUGIN_COMPONENT);
+ CASE_TYPE(INPUT_EVENT_LATENCY_BEGIN_SCROLL_UPDATE_MAIN_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_SCROLL_UPDATE_RWH_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_UI_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_COMPONENT);
+ CASE_TYPE(INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_ACKED_TOUCH_COMPONENT);
CASE_TYPE(WINDOW_SNAPSHOT_FRAME_NUMBER_COMPONENT);
+ CASE_TYPE(WINDOW_OLD_SNAPSHOT_FRAME_NUMBER_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_MOUSE_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_TOUCH_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_GESTURE_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_COMMIT_FAILED_COMPONENT);
+ CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_COMMIT_NO_UPDATE_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_SWAP_FAILED_COMPONENT);
- CASE_TYPE(LATENCY_INFO_LIST_TERMINATED_OVERFLOW_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_PLUGIN_COMPONENT);
default:
DLOG(WARNING) << "Unhandled LatencyComponentType.\n";
case ui::INPUT_EVENT_LATENCY_TERMINATED_GESTURE_COMPONENT:
case ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT:
case ui::INPUT_EVENT_LATENCY_TERMINATED_COMMIT_FAILED_COMPONENT:
+ case ui::INPUT_EVENT_LATENCY_TERMINATED_COMMIT_NO_UPDATE_COMPONENT:
case ui::INPUT_EVENT_LATENCY_TERMINATED_SWAP_FAILED_COMPONENT:
- case ui::LATENCY_INFO_LIST_TERMINATED_OVERFLOW_COMPONENT:
case ui::INPUT_EVENT_LATENCY_TERMINATED_PLUGIN_COMPONENT:
return true;
default:
bool IsBeginComponent(ui::LatencyComponentType type) {
return (type == ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT ||
- type == ui::INPUT_EVENT_LATENCY_BEGIN_PLUGIN_COMPONENT);
+ type == ui::INPUT_EVENT_LATENCY_BEGIN_PLUGIN_COMPONENT ||
+ type == ui::INPUT_EVENT_LATENCY_BEGIN_SCROLL_UPDATE_MAIN_COMPONENT);
}
// This class is for converting latency info to trace buffer friendly format.
record_data->Set(GetComponentName(it->first.first), component_info);
}
record_data->SetDouble("trace_id", latency.trace_id);
+
+ scoped_ptr<base::ListValue> coordinates(new base::ListValue());
+ for (size_t i = 0; i < latency.input_coordinates_size; i++) {
+ scoped_ptr<base::DictionaryValue> coordinate_pair(
+ new base::DictionaryValue());
+ coordinate_pair->SetDouble("x", latency.input_coordinates[i].x);
+ coordinate_pair->SetDouble("y", latency.input_coordinates[i].y);
+ coordinates->Append(coordinate_pair.release());
+ }
+ record_data->Set("coordinates", coordinates.release());
return LatencyInfoTracedValue::FromValue(record_data.PassAs<base::Value>());
}
namespace ui {
-LatencyInfo::LatencyInfo() : trace_id(-1), terminated(false) {
+LatencyInfo::InputCoordinate::InputCoordinate() : x(0), y(0) {
+}
+
+LatencyInfo::InputCoordinate::InputCoordinate(float x, float y) : x(x), y(y) {
+}
+
+LatencyInfo::LatencyInfo()
+ : input_coordinates_size(0), trace_id(-1), terminated(false) {
}
LatencyInfo::~LatencyInfo() {
<< latency_info.size() << " is too big.";
return false;
}
+ for (size_t i = 0; i < latency_info.size(); i++) {
+ if (latency_info[i].input_coordinates_size > kMaxInputCoordinates) {
+ LOG(ERROR) << referring_msg << ", coordinate vector size "
+ << latency_info[i].input_coordinates_size << " is too big.";
+ return false;
+ }
+ }
+
return true;
}
int64 component_sequence_number,
base::TimeTicks time,
uint32 event_count) {
+
+ static const unsigned char* benchmark_enabled =
+ TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED("benchmark");
+
if (IsBeginComponent(component)) {
// Should only ever add begin component once.
CHECK_EQ(-1, trace_id);
trace_id = component_sequence_number;
- TRACE_EVENT_ASYNC_BEGIN0("benchmark",
- "InputLatency",
- TRACE_ID_DONT_MANGLE(trace_id));
+
+ if (*benchmark_enabled) {
+ // The timestamp for ASYNC_BEGIN trace event is used for drawing the
+ // beginning of the trace event in trace viewer. For better visualization,
+ // for an input event, we want to draw the beginning as when the event is
+ // originally created, e.g. the timestamp of its ORIGINAL/UI_COMPONENT,
+ // not when we actually issue the ASYNC_BEGIN trace event.
+ LatencyComponent component;
+ int64 ts = 0;
+ if (FindLatency(INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
+ 0,
+ &component) ||
+ FindLatency(INPUT_EVENT_LATENCY_UI_COMPONENT,
+ 0,
+ &component)) {
+ // The timestamp stored in ORIGINAL/UI_COMPONENT is using clock
+ // CLOCK_MONOTONIC while TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0
+ // expects timestamp using CLOCK_MONOTONIC or CLOCK_SYSTEM_TRACE (on
+ // CrOS). So we need to adjust the diff between in CLOCK_MONOTONIC and
+ // CLOCK_SYSTEM_TRACE. Note that the diff is drifting overtime so we
+ // can't use a static value.
+ int64 diff = base::TimeTicks::HighResNow().ToInternalValue() -
+ base::TimeTicks::NowFromSystemTraceTime().ToInternalValue();
+ ts = component.event_time.ToInternalValue() - diff;
+ } else {
+ ts = base::TimeTicks::NowFromSystemTraceTime().ToInternalValue();
+ }
+ TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0(
+ "benchmark",
+ "InputLatency",
+ TRACE_ID_DONT_MANGLE(trace_id),
+ ts);
+ }
+
TRACE_EVENT_FLOW_BEGIN0(
"input", "LatencyInfo.Flow", TRACE_ID_DONT_MANGLE(trace_id));
}
// Should only ever add terminal component once.
CHECK(!terminated);
terminated = true;
- TRACE_EVENT_ASYNC_END1("benchmark",
- "InputLatency",
- TRACE_ID_DONT_MANGLE(trace_id),
- "data", AsTraceableData(*this));
+
+ if (*benchmark_enabled) {
+ TRACE_EVENT_ASYNC_END1("benchmark",
+ "InputLatency",
+ TRACE_ID_DONT_MANGLE(trace_id),
+ "data", AsTraceableData(*this));
+ }
+
TRACE_EVENT_FLOW_END0(
"input", "LatencyInfo.Flow", TRACE_ID_DONT_MANGLE(trace_id));
}