1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/debug/frame_timing_tracker.h"
10 #include "base/metrics/histogram.h"
11 #include "cc/trees/layer_tree_host_impl.h"
12 #include "cc/trees/proxy.h"
16 int kSendTimingIntervalMS
= 200;
19 FrameTimingTracker::CompositeTimingEvent::CompositeTimingEvent(
21 base::TimeTicks _timestamp
)
22 : frame_id(_frame_id
), timestamp(_timestamp
) {
25 FrameTimingTracker::CompositeTimingEvent::~CompositeTimingEvent() {
28 FrameTimingTracker::MainFrameTimingEvent::MainFrameTimingEvent(
30 base::TimeTicks timestamp
,
31 base::TimeTicks end_time
)
32 : frame_id(frame_id
), timestamp(timestamp
), end_time(end_time
) {
35 FrameTimingTracker::MainFrameTimingEvent::~MainFrameTimingEvent() {
39 scoped_ptr
<FrameTimingTracker
> FrameTimingTracker::Create(
40 LayerTreeHostImpl
* layer_tree_host_impl
) {
41 return make_scoped_ptr(new FrameTimingTracker(layer_tree_host_impl
));
44 FrameTimingTracker::FrameTimingTracker(LayerTreeHostImpl
* layer_tree_host_impl
)
45 : layer_tree_host_impl_(layer_tree_host_impl
),
46 post_events_notifier_(
47 layer_tree_host_impl_
->proxy()->HasImplThread()
48 ? layer_tree_host_impl_
->proxy()->ImplThreadTaskRunner()
49 : layer_tree_host_impl_
->proxy()->MainThreadTaskRunner(),
50 base::Bind(&FrameTimingTracker::PostEvents
, base::Unretained(this)),
51 base::TimeDelta::FromMilliseconds(kSendTimingIntervalMS
)) {
54 FrameTimingTracker::~FrameTimingTracker() {
57 void FrameTimingTracker::SaveTimeStamps(
58 base::TimeTicks timestamp
,
59 const std::vector
<FrameAndRectIds
>& frame_ids
) {
60 if (!composite_events_
)
61 composite_events_
.reset(new CompositeTimingSet
);
62 for (const auto& pair
: frame_ids
) {
63 (*composite_events_
)[pair
.second
].push_back(
64 CompositeTimingEvent(pair
.first
, timestamp
));
66 if (!post_events_notifier_
.HasPendingNotification())
67 post_events_notifier_
.Schedule();
70 void FrameTimingTracker::SaveMainFrameTimeStamps(
71 const std::vector
<int64_t>& request_ids
,
72 base::TimeTicks main_frame_time
,
73 base::TimeTicks end_time
,
74 int source_frame_number
) {
75 if (!main_frame_events_
)
76 main_frame_events_
.reset(new MainFrameTimingSet
);
77 for (const auto& request
: request_ids
) {
78 std::vector
<MainFrameTimingEvent
>& events
= (*main_frame_events_
)[request
];
80 MainFrameTimingEvent(source_frame_number
, main_frame_time
, end_time
));
82 if (!post_events_notifier_
.HasPendingNotification())
83 post_events_notifier_
.Schedule();
86 scoped_ptr
<FrameTimingTracker::CompositeTimingSet
>
87 FrameTimingTracker::GroupCompositeCountsByRectId() {
88 if (!composite_events_
)
89 return make_scoped_ptr(new CompositeTimingSet
);
90 for (auto& infos
: *composite_events_
) {
92 infos
.second
.begin(), infos
.second
.end(),
93 [](const CompositeTimingEvent
& lhs
, const CompositeTimingEvent
& rhs
) {
94 return lhs
.timestamp
< rhs
.timestamp
;
97 return composite_events_
.Pass();
100 scoped_ptr
<FrameTimingTracker::MainFrameTimingSet
>
101 FrameTimingTracker::GroupMainFrameCountsByRectId() {
102 if (!main_frame_events_
)
103 return make_scoped_ptr(new MainFrameTimingSet
);
104 for (auto& infos
: *main_frame_events_
) {
106 infos
.second
.begin(), infos
.second
.end(),
107 [](const MainFrameTimingEvent
& lhs
, const MainFrameTimingEvent
& rhs
) {
108 return lhs
.timestamp
< rhs
.timestamp
;
111 return main_frame_events_
.Pass();
114 void FrameTimingTracker::PostEvents() {
115 layer_tree_host_impl_
->PostFrameTimingEvents(GroupCompositeCountsByRectId(),
116 GroupMainFrameCountsByRectId());