190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file. 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/debug/trace_event.h" 64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/json/json_writer.h" 74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/stringprintf.h" 968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/events/latency_info.h" 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <algorithm> 1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace { 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const size_t kMaxLatencyInfoNumber = 100; 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char* GetComponentName(ui::LatencyComponentType type) { 184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#define CASE_TYPE(t) case ui::t: return #t 194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) switch (type) { 204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CASE_TYPE(INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT); 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CASE_TYPE(INPUT_EVENT_LATENCY_BEGIN_PLUGIN_COMPONENT); 226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) CASE_TYPE(INPUT_EVENT_LATENCY_BEGIN_SCROLL_UPDATE_MAIN_COMPONENT); 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CASE_TYPE(INPUT_EVENT_LATENCY_SCROLL_UPDATE_RWH_COMPONENT); 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CASE_TYPE(INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT); 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CASE_TYPE(INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT); 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CASE_TYPE(INPUT_EVENT_LATENCY_UI_COMPONENT); 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CASE_TYPE(INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_COMPONENT); 286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) CASE_TYPE(INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT); 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CASE_TYPE(INPUT_EVENT_LATENCY_ACKED_TOUCH_COMPONENT); 30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CASE_TYPE(WINDOW_SNAPSHOT_FRAME_NUMBER_COMPONENT); 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CASE_TYPE(WINDOW_OLD_SNAPSHOT_FRAME_NUMBER_COMPONENT); 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_MOUSE_COMPONENT); 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_TOUCH_COMPONENT); 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_GESTURE_COMPONENT); 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT); 36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_COMMIT_FAILED_COMPONENT); 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_COMMIT_NO_UPDATE_COMPONENT); 38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_SWAP_FAILED_COMPONENT); 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_PLUGIN_COMPONENT); 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) default: 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DLOG(WARNING) << "Unhandled LatencyComponentType.\n"; 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#undef CASE_TYPE 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return "unknown"; 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool IsTerminalComponent(ui::LatencyComponentType type) { 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) switch (type) { 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case ui::INPUT_EVENT_LATENCY_TERMINATED_MOUSE_COMPONENT: 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case ui::INPUT_EVENT_LATENCY_TERMINATED_TOUCH_COMPONENT: 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case ui::INPUT_EVENT_LATENCY_TERMINATED_GESTURE_COMPONENT: 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT: 54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case ui::INPUT_EVENT_LATENCY_TERMINATED_COMMIT_FAILED_COMPONENT: 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case ui::INPUT_EVENT_LATENCY_TERMINATED_COMMIT_NO_UPDATE_COMPONENT: 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case ui::INPUT_EVENT_LATENCY_TERMINATED_SWAP_FAILED_COMPONENT: 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case ui::INPUT_EVENT_LATENCY_TERMINATED_PLUGIN_COMPONENT: 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) default: 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool IsBeginComponent(ui::LatencyComponentType type) { 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return (type == ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT || 666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) type == ui::INPUT_EVENT_LATENCY_BEGIN_PLUGIN_COMPONENT || 676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) type == ui::INPUT_EVENT_LATENCY_BEGIN_SCROLL_UPDATE_MAIN_COMPONENT); 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// This class is for converting latency info to trace buffer friendly format. 714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class LatencyInfoTracedValue : public base::debug::ConvertableToTraceFormat { 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static scoped_refptr<ConvertableToTraceFormat> FromValue( 744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<base::Value> value); 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE; 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private: 794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) explicit LatencyInfoTracedValue(base::Value* value); 804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual ~LatencyInfoTracedValue(); 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<base::Value> value_; 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(LatencyInfoTracedValue); 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)scoped_refptr<base::debug::ConvertableToTraceFormat> 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)LatencyInfoTracedValue::FromValue(scoped_ptr<base::Value> value) { 894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return scoped_refptr<base::debug::ConvertableToTraceFormat>( 904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new LatencyInfoTracedValue(value.release())); 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)LatencyInfoTracedValue::~LatencyInfoTracedValue() { 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void LatencyInfoTracedValue::AppendAsTraceFormat(std::string* out) const { 974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string tmp; 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::JSONWriter::Write(value_.get(), &tmp); 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *out += tmp; 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)LatencyInfoTracedValue::LatencyInfoTracedValue(base::Value* value) 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : value_(value) { 1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Converts latencyinfo into format that can be dumped into trace buffer. 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)scoped_refptr<base::debug::ConvertableToTraceFormat> AsTraceableData( 1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const ui::LatencyInfo& latency) { 1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<base::DictionaryValue> record_data(new base::DictionaryValue()); 1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (ui::LatencyInfo::LatencyMap::const_iterator it = 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) latency.latency_components.begin(); 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) it != latency.latency_components.end(); ++it) { 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::DictionaryValue* component_info = new base::DictionaryValue(); 1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) component_info->SetDouble("comp_id", it->first.second); 1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) component_info->SetDouble("time", it->second.event_time.ToInternalValue()); 1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) component_info->SetDouble("count", it->second.event_count); 1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) record_data->Set(GetComponentName(it->first.first), component_info); 1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) record_data->SetDouble("trace_id", latency.trace_id); 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<base::ListValue> coordinates(new base::ListValue()); 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (size_t i = 0; i < latency.input_coordinates_size; i++) { 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<base::DictionaryValue> coordinate_pair( 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new base::DictionaryValue()); 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci coordinate_pair->SetDouble("x", latency.input_coordinates[i].x); 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci coordinate_pair->SetDouble("y", latency.input_coordinates[i].y); 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci coordinates->Append(coordinate_pair.release()); 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci record_data->Set("coordinates", coordinates.release()); 1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return LatencyInfoTracedValue::FromValue(record_data.PassAs<base::Value>()); 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace ui { 13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciLatencyInfo::InputCoordinate::InputCoordinate() : x(0), y(0) { 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciLatencyInfo::InputCoordinate::InputCoordinate(float x, float y) : x(x), y(y) { 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciLatencyInfo::LatencyInfo() 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : input_coordinates_size(0), trace_id(-1), terminated(false) { 14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)LatencyInfo::~LatencyInfo() { 14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool LatencyInfo::Verify(const std::vector<LatencyInfo>& latency_info, 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* referring_msg) { 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (latency_info.size() > kMaxLatencyInfoNumber) { 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(ERROR) << referring_msg << ", LatencyInfo vector size " 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << latency_info.size() << " is too big."; 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (size_t i = 0; i < latency_info.size(); i++) { 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (latency_info[i].input_coordinates_size > kMaxInputCoordinates) { 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci LOG(ERROR) << referring_msg << ", coordinate vector size " 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << latency_info[i].input_coordinates_size << " is too big."; 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void LatencyInfo::CopyLatencyFrom(const LatencyInfo& other, 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LatencyComponentType type) { 17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (LatencyMap::const_iterator it = other.latency_components.begin(); 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it != other.latency_components.end(); 17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ++it) { 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (it->first.first == type) { 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddLatencyNumberWithTimestamp(it->first.first, 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it->first.second, 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it->second.sequence_number, 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it->second.event_time, 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it->second.event_count); 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1833240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid LatencyInfo::AddNewLatencyFrom(const LatencyInfo& other) { 1843240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch for (LatencyMap::const_iterator it = other.latency_components.begin(); 1853240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch it != other.latency_components.end(); 1863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch ++it) { 1873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (!FindLatency(it->first.first, it->first.second, NULL)) { 1883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch AddLatencyNumberWithTimestamp(it->first.first, 1893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch it->first.second, 1903240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch it->second.sequence_number, 1913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch it->second.event_time, 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it->second.event_count); 1933240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 1943240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 1953240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch} 1963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void LatencyInfo::AddLatencyNumber(LatencyComponentType component, 19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int64 id, 19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int64 component_sequence_number) { 20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AddLatencyNumberWithTimestamp(component, id, component_sequence_number, 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeTicks::HighResNow(), 1); 20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void LatencyInfo::AddLatencyNumberWithTimestamp(LatencyComponentType component, 20590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int64 id, 20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int64 component_sequence_number, 20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::TimeTicks time, 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32 event_count) { 2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) static const unsigned char* benchmark_enabled = 2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED("benchmark"); 2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (IsBeginComponent(component)) { 2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Should only ever add begin component once. 215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CHECK_EQ(-1, trace_id); 2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) trace_id = component_sequence_number; 2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (*benchmark_enabled) { 2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // The timestamp for ASYNC_BEGIN trace event is used for drawing the 2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // beginning of the trace event in trace viewer. For better visualization, 2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // for an input event, we want to draw the beginning as when the event is 2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // originally created, e.g. the timestamp of its ORIGINAL/UI_COMPONENT, 2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // not when we actually issue the ASYNC_BEGIN trace event. 2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LatencyComponent component; 2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int64 ts = 0; 2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (FindLatency(INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0, 2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &component) || 2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FindLatency(INPUT_EVENT_LATENCY_UI_COMPONENT, 2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0, 2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &component)) { 2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // The timestamp stored in ORIGINAL/UI_COMPONENT is using clock 2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // CLOCK_MONOTONIC while TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0 2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // expects timestamp using CLOCK_MONOTONIC or CLOCK_SYSTEM_TRACE (on 2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // CrOS). So we need to adjust the diff between in CLOCK_MONOTONIC and 2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // CLOCK_SYSTEM_TRACE. Note that the diff is drifting overtime so we 2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // can't use a static value. 2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int64 diff = base::TimeTicks::HighResNow().ToInternalValue() - 2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::TimeTicks::NowFromSystemTraceTime().ToInternalValue(); 2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ts = component.event_time.ToInternalValue() - diff; 2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ts = base::TimeTicks::NowFromSystemTraceTime().ToInternalValue(); 2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0( 2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "benchmark", 2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "InputLatency", 2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_ID_DONT_MANGLE(trace_id), 2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ts); 2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 251e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch TRACE_EVENT_FLOW_BEGIN0( 252e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "input", "LatencyInfo.Flow", TRACE_ID_DONT_MANGLE(trace_id)); 2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LatencyMap::key_type key = std::make_pair(component, id); 25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LatencyMap::iterator it = latency_components.find(key); 25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (it == latency_components.end()) { 25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LatencyComponent info = {component_sequence_number, time, event_count}; 25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) latency_components[key] = info; 2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) it->second.sequence_number = std::max(component_sequence_number, 2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) it->second.sequence_number); 2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32 new_count = event_count + it->second.event_count; 2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (event_count > 0 && new_count != 0) { 2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Do a weighted average, so that the new event_time is the average of 2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // the times of events currently in this structure with the time passed 2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // into this method. 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) it->second.event_time += (time - it->second.event_time) * event_count / 2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new_count; 2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) it->second.event_count = new_count; 2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (IsTerminalComponent(component) && trace_id != -1) { 2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Should only ever add terminal component once. 2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CHECK(!terminated); 2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) terminated = true; 2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (*benchmark_enabled) { 2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_ASYNC_END1("benchmark", 2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "InputLatency", 2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_ID_DONT_MANGLE(trace_id), 2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "data", AsTraceableData(*this)); 2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 286e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch TRACE_EVENT_FLOW_END0( 287e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "input", "LatencyInfo.Flow", TRACE_ID_DONT_MANGLE(trace_id)); 28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool LatencyInfo::FindLatency(LatencyComponentType type, 292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 id, 293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LatencyComponent* output) const { 294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LatencyMap::const_iterator it = latency_components.find( 295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::make_pair(type, id)); 296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (it == latency_components.end()) 297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (output) 299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *output = it->second; 300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return true; 301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void LatencyInfo::RemoveLatency(LatencyComponentType type) { 304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LatencyMap::iterator it = latency_components.begin(); 305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) while (it != latency_components.end()) { 306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (it->first.first == type) { 307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LatencyMap::iterator tmp = it; 308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ++it; 309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) latency_components.erase(tmp); 310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it++; 312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 31690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void LatencyInfo::Clear() { 31790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) latency_components.clear(); 31890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void LatencyInfo::TraceEventType(const char* event_type) { 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TRACE_EVENT_ASYNC_STEP_INTO0("benchmark", 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "InputLatency", 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TRACE_ID_DONT_MANGLE(trace_id), 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) event_type); 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 32790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace ui 328