Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: ui/events/latency_info.cc

Issue 25022003: Report LatencyInfo through trace buffer (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: fix compile error Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/events/latency_info.h ('k') | ui/events/latency_info_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "base/debug/trace_event.h"
6 #include "base/json/json_writer.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/strings/stringprintf.h"
5 #include "ui/events/latency_info.h" 9 #include "ui/events/latency_info.h"
6 10
7 #include <algorithm> 11 #include <algorithm>
8 12
13 namespace {
14 const char* GetComponentName(ui::LatencyComponentType type) {
15 #define CASE_TYPE(t) case ui::t: return #t
16 switch (type) {
17 CASE_TYPE(INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT);
18 CASE_TYPE(INPUT_EVENT_LATENCY_SCROLL_UPDATE_RWH_COMPONENT);
19 CASE_TYPE(INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT);
20 CASE_TYPE(INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT);
21 CASE_TYPE(INPUT_EVENT_LATENCY_UI_COMPONENT);
22 CASE_TYPE(INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_COMPONENT);
23 CASE_TYPE(INPUT_EVENT_LATENCY_ACKED_TOUCH_COMPONENT);
24 CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_MOUSE_COMPONENT);
25 CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_TOUCH_COMPONENT);
26 CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_GESTURE_COMPONENT);
27 CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT);
28 default:
29 DLOG(WARNING) << "Unhandled LatencyComponentType.\n";
30 break;
31 }
32 #undef CASE_TYPE
33 return "unknown";
34 }
35
36 bool IsTerminalComponent(ui::LatencyComponentType type) {
37 switch (type) {
38 case ui::INPUT_EVENT_LATENCY_TERMINATED_MOUSE_COMPONENT:
39 case ui::INPUT_EVENT_LATENCY_TERMINATED_TOUCH_COMPONENT:
40 case ui::INPUT_EVENT_LATENCY_TERMINATED_GESTURE_COMPONENT:
41 case ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT:
42 return true;
43 default:
44 return false;
45 }
46 }
47
48 bool IsBeginComponent(ui::LatencyComponentType type) {
49 return (type == ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT);
50 }
51
52 // This class is for converting latency info to trace buffer friendly format.
53 class LatencyInfoTracedValue : public base::debug::ConvertableToTraceFormat {
54 public:
55 static scoped_refptr<ConvertableToTraceFormat> FromValue(
56 scoped_ptr<base::Value> value);
57
58 virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE;
59
60 private:
61 explicit LatencyInfoTracedValue(base::Value* value);
62 virtual ~LatencyInfoTracedValue();
63
64 scoped_ptr<base::Value> value_;
65
66 DISALLOW_COPY_AND_ASSIGN(LatencyInfoTracedValue);
67 };
68
69 scoped_refptr<base::debug::ConvertableToTraceFormat>
70 LatencyInfoTracedValue::FromValue(scoped_ptr<base::Value> value) {
71 return scoped_refptr<base::debug::ConvertableToTraceFormat>(
72 new LatencyInfoTracedValue(value.release()));
73 }
74
75 LatencyInfoTracedValue::~LatencyInfoTracedValue() {
76 }
77
78 void LatencyInfoTracedValue::AppendAsTraceFormat(std::string* out) const {
79 std::string tmp;
80 base::JSONWriter::Write(value_.get(), &tmp);
81 *out += tmp;
82 }
83
84 LatencyInfoTracedValue::LatencyInfoTracedValue(base::Value* value)
85 : value_(value) {
86 }
87
88 // Converts latencyinfo into format that can be dumped into trace buffer.
89 scoped_refptr<base::debug::ConvertableToTraceFormat> AsTraceableData(
90 const ui::LatencyInfo& latency) {
91 scoped_ptr<base::DictionaryValue> record_data(new base::DictionaryValue());
92 for (ui::LatencyInfo::LatencyMap::const_iterator it =
93 latency.latency_components.begin();
94 it != latency.latency_components.end(); ++it) {
95 base::DictionaryValue* component_info = new base::DictionaryValue();
96 component_info->SetDouble("comp_id", it->first.second);
97 component_info->SetDouble("time", it->second.event_time.ToInternalValue());
98 component_info->SetDouble("count", it->second.event_count);
99 record_data->Set(GetComponentName(it->first.first), component_info);
100 }
101 return LatencyInfoTracedValue::FromValue(record_data.PassAs<base::Value>());
102 }
103
104 } // namespace
105
9 namespace ui { 106 namespace ui {
10 107
11 LatencyInfo::LatencyInfo() { 108 LatencyInfo::LatencyInfo() : trace_id(-1), terminated(false) {
12 } 109 }
13 110
14 LatencyInfo::~LatencyInfo() { 111 LatencyInfo::~LatencyInfo() {
15 } 112 }
16 113
17 void LatencyInfo::MergeWith(const LatencyInfo& other) { 114 void LatencyInfo::MergeWith(const LatencyInfo& other) {
18 for (LatencyMap::const_iterator it = other.latency_components.begin(); 115 for (LatencyMap::const_iterator it = other.latency_components.begin();
19 it != other.latency_components.end(); 116 it != other.latency_components.end();
20 ++it) { 117 ++it) {
21 AddLatencyNumberWithTimestamp(it->first.first, 118 AddLatencyNumberWithTimestamp(it->first.first,
22 it->first.second, 119 it->first.second,
23 it->second.sequence_number, 120 it->second.sequence_number,
24 it->second.event_time, 121 it->second.event_time,
25 it->second.event_count); 122 it->second.event_count,
123 false);
26 } 124 }
27 } 125 }
28 126
29 void LatencyInfo::AddNewLatencyFrom(const LatencyInfo& other) { 127 void LatencyInfo::AddNewLatencyFrom(const LatencyInfo& other) {
30 for (LatencyMap::const_iterator it = other.latency_components.begin(); 128 for (LatencyMap::const_iterator it = other.latency_components.begin();
31 it != other.latency_components.end(); 129 it != other.latency_components.end();
32 ++it) { 130 ++it) {
33 if (!FindLatency(it->first.first, it->first.second, NULL)) { 131 if (!FindLatency(it->first.first, it->first.second, NULL)) {
34 AddLatencyNumberWithTimestamp(it->first.first, 132 AddLatencyNumberWithTimestamp(it->first.first,
35 it->first.second, 133 it->first.second,
36 it->second.sequence_number, 134 it->second.sequence_number,
37 it->second.event_time, 135 it->second.event_time,
38 it->second.event_count); 136 it->second.event_count,
137 false);
39 } 138 }
40 } 139 }
41 } 140 }
42 141
43 void LatencyInfo::AddLatencyNumber(LatencyComponentType component, 142 void LatencyInfo::AddLatencyNumber(LatencyComponentType component,
44 int64 id, 143 int64 id,
45 int64 component_sequence_number) { 144 int64 component_sequence_number) {
46 AddLatencyNumberWithTimestamp(component, id, component_sequence_number, 145 AddLatencyNumberWithTimestamp(component, id, component_sequence_number,
47 base::TimeTicks::HighResNow(), 1); 146 base::TimeTicks::HighResNow(), 1, true);
48 } 147 }
49 148
50 void LatencyInfo::AddLatencyNumberWithTimestamp(LatencyComponentType component, 149 void LatencyInfo::AddLatencyNumberWithTimestamp(LatencyComponentType component,
51 int64 id, 150 int64 id,
52 int64 component_sequence_number, 151 int64 component_sequence_number,
53 base::TimeTicks time, 152 base::TimeTicks time,
54 uint32 event_count) { 153 uint32 event_count,
154 bool dump_to_trace) {
155 if (dump_to_trace && IsBeginComponent(component)) {
156 // Should only ever add begin component once.
157 CHECK_EQ(-1, trace_id);
158 trace_id = component_sequence_number;
159 TRACE_EVENT_ASYNC_BEGIN0("benchmark",
160 "InputLatency",
161 TRACE_ID_DONT_MANGLE(trace_id));
162 }
163
55 LatencyMap::key_type key = std::make_pair(component, id); 164 LatencyMap::key_type key = std::make_pair(component, id);
56 LatencyMap::iterator it = latency_components.find(key); 165 LatencyMap::iterator it = latency_components.find(key);
57 if (it == latency_components.end()) { 166 if (it == latency_components.end()) {
58 LatencyComponent info = {component_sequence_number, time, event_count}; 167 LatencyComponent info = {component_sequence_number, time, event_count};
59 latency_components[key] = info; 168 latency_components[key] = info;
60 return; 169 } else {
170 it->second.sequence_number = std::max(component_sequence_number,
171 it->second.sequence_number);
172 uint32 new_count = event_count + it->second.event_count;
173 if (event_count > 0 && new_count != 0) {
174 // Do a weighted average, so that the new event_time is the average of
175 // the times of events currently in this structure with the time passed
176 // into this method.
177 it->second.event_time += (time - it->second.event_time) * event_count /
178 new_count;
179 it->second.event_count = new_count;
180 }
61 } 181 }
62 it->second.sequence_number = std::max(component_sequence_number, 182
63 it->second.sequence_number); 183 if (dump_to_trace && IsTerminalComponent(component) && trace_id != -1) {
64 uint32 new_count = event_count + it->second.event_count; 184 // Should only ever add terminal component once.
65 if (event_count > 0 && new_count != 0) { 185 CHECK(!terminated);
66 // Do a weighted average, so that the new event_time is the average of 186 terminated = true;
67 // the times of events currently in this structure with the time passed 187 TRACE_EVENT_ASYNC_END1("benchmark",
68 // into this method. 188 "InputLatency",
69 it->second.event_time += (time - it->second.event_time) * event_count / 189 TRACE_ID_DONT_MANGLE(trace_id),
70 new_count; 190 "data", AsTraceableData(*this));
71 it->second.event_count = new_count;
72 } 191 }
73 } 192 }
74 193
75 bool LatencyInfo::FindLatency(LatencyComponentType type, 194 bool LatencyInfo::FindLatency(LatencyComponentType type,
76 int64 id, 195 int64 id,
77 LatencyComponent* output) const { 196 LatencyComponent* output) const {
78 LatencyMap::const_iterator it = latency_components.find( 197 LatencyMap::const_iterator it = latency_components.find(
79 std::make_pair(type, id)); 198 std::make_pair(type, id));
80 if (it == latency_components.end()) 199 if (it == latency_components.end())
81 return false; 200 return false;
82 if (output) 201 if (output)
83 *output = it->second; 202 *output = it->second;
84 return true; 203 return true;
85 } 204 }
86 205
87 void LatencyInfo::Clear() { 206 void LatencyInfo::Clear() {
88 latency_components.clear(); 207 latency_components.clear();
89 } 208 }
90 209
91 } // namespace ui 210 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/latency_info.h ('k') | ui/events/latency_info_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698