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

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 typo 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
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 if (type == ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT)
50 return true;
51 return false;
sadrul 2013/10/09 19:23:27 return type == ui::...
Yufeng Shen (Slow to review) 2013/10/09 20:53:50 Done.
52 }
53
54 // This class is for converting latency info to trace buffer friendly format.
55 class LatencyInfoTracedValue : public base::debug::ConvertableToTraceFormat {
56 public:
57 static scoped_ptr<ConvertableToTraceFormat> FromValue(
58 base::Value* value);
sadrul 2013/10/09 19:23:27 Can this be scoped_ptr<base::Value> too, to clarif
Yufeng Shen (Slow to review) 2013/10/09 20:53:50 Done.
59
60 virtual ~LatencyInfoTracedValue();
61
62 virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE;
63
64 private:
65 explicit LatencyInfoTracedValue(base::Value* value);
66
67 scoped_ptr<base::Value> value_;
68
69 DISALLOW_COPY_AND_ASSIGN(LatencyInfoTracedValue);
70 };
71
72 scoped_ptr<base::debug::ConvertableToTraceFormat>
73 LatencyInfoTracedValue::FromValue(base::Value* value) {
74 LatencyInfoTracedValue* ptr = new LatencyInfoTracedValue(value);
75 scoped_ptr<LatencyInfoTracedValue> result(ptr);
76 return result.PassAs<base::debug::ConvertableToTraceFormat>();
sadrul 2013/10/09 19:23:27 You can just do: return scoped_ptr<base::debug::
Yufeng Shen (Slow to review) 2013/10/09 20:53:50 Done.
77 }
78
79 LatencyInfoTracedValue::~LatencyInfoTracedValue() {
80 }
81
82 void LatencyInfoTracedValue::AppendAsTraceFormat(std::string* out) const {
83 std::string tmp;
84 base::JSONWriter::Write(value_.get(), &tmp);
85 *out += tmp;
86 }
87
88 LatencyInfoTracedValue::LatencyInfoTracedValue(base::Value* value)
89 : value_(value) {
90 }
91
92 // Converts latencyinfo into format that can be dumped into trace buffer.
93 scoped_ptr<base::debug::ConvertableToTraceFormat> AsTraceableData(
94 const ui::LatencyInfo& latency) {
95 scoped_ptr<base::DictionaryValue> record_data(new base::DictionaryValue());
96 for (ui::LatencyInfo::LatencyMap::const_iterator it =
97 latency.latency_components.begin();
98 it != latency.latency_components.end(); ++it) {
99 base::DictionaryValue* component_info = new base::DictionaryValue();
100 component_info->SetDouble("comp_id", it->first.second);
101 component_info->SetDouble("time", it->second.event_time.ToInternalValue());
102 component_info->SetDouble("count", it->second.event_count);
103 record_data->Set(GetComponentName(it->first.first), component_info);
104 }
105 return LatencyInfoTracedValue::FromValue(record_data.release());
106 }
107
108 } // namespace
109
9 namespace ui { 110 namespace ui {
10 111
11 LatencyInfo::LatencyInfo() { 112 LatencyInfo::LatencyInfo() : trace_id(-1), terminated(false) {
12 } 113 }
13 114
14 LatencyInfo::~LatencyInfo() { 115 LatencyInfo::~LatencyInfo() {
15 } 116 }
16 117
17 void LatencyInfo::MergeWith(const LatencyInfo& other) { 118 void LatencyInfo::MergeWith(const LatencyInfo& other) {
18 for (LatencyMap::const_iterator it = other.latency_components.begin(); 119 for (LatencyMap::const_iterator it = other.latency_components.begin();
19 it != other.latency_components.end(); 120 it != other.latency_components.end();
20 ++it) { 121 ++it) {
21 AddLatencyNumberWithTimestamp(it->first.first, 122 AddLatencyNumberWithTimestamp(it->first.first,
(...skipping 14 matching lines...) Expand all
36 it->second.sequence_number, 137 it->second.sequence_number,
37 it->second.event_time, 138 it->second.event_time,
38 it->second.event_count); 139 it->second.event_count);
39 } 140 }
40 } 141 }
41 } 142 }
42 143
43 void LatencyInfo::AddLatencyNumber(LatencyComponentType component, 144 void LatencyInfo::AddLatencyNumber(LatencyComponentType component,
44 int64 id, 145 int64 id,
45 int64 component_sequence_number) { 146 int64 component_sequence_number) {
147 if (IsBeginComponent(component)) {
148 // Should only ever add begin component once.
149 CHECK(trace_id == -1);
sadrul 2013/10/09 19:23:27 CHECK_EQ(-1, trace_id)
Yufeng Shen (Slow to review) 2013/10/09 20:53:50 Done.
150 trace_id = component_sequence_number;
151 TRACE_EVENT_ASYNC_BEGIN0("benchmark",
152 "InputLatency",
153 TRACE_ID_DONT_MANGLE(trace_id));
154 }
155
46 AddLatencyNumberWithTimestamp(component, id, component_sequence_number, 156 AddLatencyNumberWithTimestamp(component, id, component_sequence_number,
47 base::TimeTicks::HighResNow(), 1); 157 base::TimeTicks::HighResNow(), 1);
158
159 if (IsTerminalComponent(component) && trace_id != -1) {
160 // Should only ever add terminal component once.
161 CHECK(!terminated);
162 terminated = true;
163 TRACE_EVENT_ASYNC_END1("benchmark",
164 "InputLatency",
165 TRACE_ID_DONT_MANGLE(trace_id),
166 "data", AsTraceableData(*this));
167 }
48 } 168 }
49 169
50 void LatencyInfo::AddLatencyNumberWithTimestamp(LatencyComponentType component, 170 void LatencyInfo::AddLatencyNumberWithTimestamp(LatencyComponentType component,
51 int64 id, 171 int64 id,
52 int64 component_sequence_number, 172 int64 component_sequence_number,
53 base::TimeTicks time, 173 base::TimeTicks time,
54 uint32 event_count) { 174 uint32 event_count) {
55 LatencyMap::key_type key = std::make_pair(component, id); 175 LatencyMap::key_type key = std::make_pair(component, id);
56 LatencyMap::iterator it = latency_components.find(key); 176 LatencyMap::iterator it = latency_components.find(key);
sadrul 2013/10/09 19:23:27 Shouldn't the checks above be in here (since this
Yufeng Shen (Slow to review) 2013/10/09 20:53:50 right, done.
57 if (it == latency_components.end()) { 177 if (it == latency_components.end()) {
58 LatencyComponent info = {component_sequence_number, time, event_count}; 178 LatencyComponent info = {component_sequence_number, time, event_count};
59 latency_components[key] = info; 179 latency_components[key] = info;
60 return; 180 return;
61 } 181 }
62 it->second.sequence_number = std::max(component_sequence_number, 182 it->second.sequence_number = std::max(component_sequence_number,
63 it->second.sequence_number); 183 it->second.sequence_number);
64 uint32 new_count = event_count + it->second.event_count; 184 uint32 new_count = event_count + it->second.event_count;
65 if (event_count > 0 && new_count != 0) { 185 if (event_count > 0 && new_count != 0) {
66 // Do a weighted average, so that the new event_time is the average of 186 // Do a weighted average, so that the new event_time is the average of
(...skipping 15 matching lines...) Expand all
82 if (output) 202 if (output)
83 *output = it->second; 203 *output = it->second;
84 return true; 204 return true;
85 } 205 }
86 206
87 void LatencyInfo::Clear() { 207 void LatencyInfo::Clear() {
88 latency_components.clear(); 208 latency_components.clear();
89 } 209 }
90 210
91 } // namespace ui 211 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698