OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 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 "mojo/ui/choreographer.h" | 5 #include "mojo/ui/choreographer.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "mojo/public/cpp/system/time.h" | 9 #include "mojo/public/cpp/system/time.h" |
10 | 10 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 if (draw_scheduled_) { | 51 if (draw_scheduled_) { |
52 draw_scheduled_ = false; | 52 draw_scheduled_ = false; |
53 | 53 |
54 // To reduce latency and jank, anticipate the next frame to be drawn by | 54 // To reduce latency and jank, anticipate the next frame to be drawn by |
55 // scheduling it early. | 55 // scheduling it early. |
56 // | 56 // |
57 // TODO(jeffbrown): Reenable this once issue #604 is fixed. Unfortunately | 57 // TODO(jeffbrown): Reenable this once issue #604 is fixed. Unfortunately |
58 // this exacerbates starvation issues in the Mojo message pump. | 58 // this exacerbates starvation issues in the Mojo message pump. |
59 // ScheduleFrame(); | 59 // ScheduleFrame(); |
60 | 60 |
61 // Ensure frame info is sane since it comes from another service. | 61 base::TimeDelta time_delta = base::TimeDelta::FromMicroseconds( |
62 // TODO(jeffbrown): Would be better to report an error to the client | 62 frame_tracker_.Update(*frame_info, mojo::GetTimeTicksNow())); |
63 // who can shut things down if needed. | 63 delegate_->OnDraw(frame_tracker_.frame_info(), time_delta); |
64 MojoTimeTicks now = mojo::GetTimeTicksNow(); | |
65 if (frame_info->frame_time > now) { | |
66 LOG(WARNING) << "Frame time is in the future: frame_time=" | |
67 << frame_info->frame_time << ", now=" << now; | |
68 frame_info->frame_time = now; | |
69 } | |
70 if (frame_info->frame_deadline < frame_info->frame_time) { | |
71 LOG(WARNING) | |
72 << "Frame deadline is earlier than frame time: frame_deadline=" | |
73 << frame_info->frame_deadline | |
74 << ", frame_time=" << frame_info->frame_time << ", now=" << now; | |
75 frame_info->frame_deadline = frame_info->frame_time; | |
76 } | |
77 if (frame_info->presentation_time < frame_info->frame_deadline) { | |
78 LOG(WARNING) << "Presentation time is earlier than frame deadline: " | |
79 "presentation_time=" | |
80 << frame_info->presentation_time | |
81 << ", frame_deadline=" << frame_info->frame_deadline | |
82 << ", now=" << now; | |
83 frame_info->presentation_time = frame_info->frame_deadline; | |
84 } | |
85 | |
86 // Compensate for significant lag by adjusting the frame time if needed | |
87 // to step past skipped frames. | |
88 uint64_t lag = now - frame_info->frame_time; | |
89 if (frame_info->frame_interval > 0u && lag > frame_info->frame_interval) { | |
90 uint64_t offset = lag % frame_info->frame_interval; | |
91 uint64_t adjustment = now - offset - frame_info->frame_time; | |
92 frame_info->frame_time = now - offset; | |
93 frame_info->frame_deadline += adjustment; | |
94 frame_info->presentation_time += adjustment; | |
95 | |
96 // Jank warning. | |
97 // TODO(jeffbrown): Suppress this once we're happy with things. | |
98 LOG(WARNING) << "Missed " << frame_info->frame_interval | |
99 << " us frame deadline by " << lag << " us, skipping " | |
100 << (lag / frame_info->frame_interval) << " frames"; | |
101 } | |
102 | |
103 // Ensure frame time isn't going backwards, just in case the compositor's | |
104 // timing is seriously broken. | |
105 base::TimeDelta time_delta; | |
106 if (last_frame_info_) { | |
107 DCHECK(frame_info->frame_time >= last_frame_info_->frame_time); | |
108 time_delta = base::TimeDelta::FromMicroseconds( | |
109 frame_info->frame_time - last_frame_info_->frame_time); | |
110 } | |
111 | |
112 // Invoke the callback. | |
113 last_frame_info_ = frame_info.Pass(); | |
114 delegate_->OnDraw(*last_frame_info_, time_delta); | |
115 } | 64 } |
116 } | 65 } |
117 | 66 |
118 } // namespace ui | 67 } // namespace ui |
119 } // namespace mojo | 68 } // namespace mojo |
OLD | NEW |