| Index: mojo/services/gfx/composition/cpp/frame_tracker.cc
|
| diff --git a/mojo/services/gfx/composition/cpp/frame_tracker.cc b/mojo/services/gfx/composition/cpp/frame_tracker.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d85246aa117afcc792696795dcd6ab409635771b
|
| --- /dev/null
|
| +++ b/mojo/services/gfx/composition/cpp/frame_tracker.cc
|
| @@ -0,0 +1,88 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "mojo/services/gfx/composition/cpp/frame_tracker.h"
|
| +
|
| +#include "mojo/public/cpp/environment/logging.h"
|
| +
|
| +namespace mojo {
|
| +namespace gfx {
|
| +namespace composition {
|
| +
|
| +FrameTracker::FrameTracker() {}
|
| +
|
| +FrameTracker::~FrameTracker() {}
|
| +
|
| +void FrameTracker::Clear() {
|
| + frame_count_ = 0u;
|
| + frame_info_ = mojo::gfx::composition::FrameInfo();
|
| +}
|
| +
|
| +uint64_t FrameTracker::Update(
|
| + const mojo::gfx::composition::FrameInfo& raw_frame_info,
|
| + MojoTimeTicks now) {
|
| + const int64_t old_frame_time = frame_info_.frame_time;
|
| + const int64_t old_presentation_time = frame_info_.presentation_time;
|
| + frame_info_ = raw_frame_info;
|
| +
|
| + // Ensure frame info is sane since it comes from another service.
|
| + if (frame_info_.frame_time > now) {
|
| + MOJO_LOG(WARNING) << "Frame time is in the future: frame_time="
|
| + << frame_info_.frame_time << ", now=" << now;
|
| + frame_info_.frame_time = now;
|
| + }
|
| + if (frame_info_.frame_deadline < frame_info_.frame_time) {
|
| + MOJO_LOG(WARNING)
|
| + << "Frame deadline is earlier than frame time: frame_deadline="
|
| + << frame_info_.frame_deadline
|
| + << ", frame_time=" << frame_info_.frame_time << ", now=" << now;
|
| + frame_info_.frame_deadline = frame_info_.frame_time;
|
| + }
|
| + if (frame_info_.presentation_time < frame_info_.frame_deadline) {
|
| + MOJO_LOG(WARNING) << "Presentation time is earlier than frame deadline: "
|
| + "presentation_time="
|
| + << frame_info_.presentation_time
|
| + << ", frame_deadline=" << frame_info_.frame_deadline
|
| + << ", now=" << now;
|
| + frame_info_.presentation_time = frame_info_.frame_deadline;
|
| + }
|
| +
|
| + // Compensate for significant lag by adjusting the frame time if needed
|
| + // to step past skipped frames.
|
| + uint64_t lag = now - frame_info_.frame_time;
|
| + if (frame_info_.frame_interval > 0u && lag >= frame_info_.frame_interval) {
|
| + uint64_t offset = lag % frame_info_.frame_interval;
|
| + uint64_t adjustment = now - offset - frame_info_.frame_time;
|
| + frame_info_.frame_time = now - offset;
|
| + frame_info_.frame_deadline += adjustment;
|
| + frame_info_.presentation_time += adjustment;
|
| +
|
| + // Jank warning.
|
| + // TODO(jeffbrown): Suppress this once we're happy with things.
|
| + MOJO_LOG(WARNING) << "Missed " << frame_info_.frame_interval
|
| + << " us frame deadline by " << lag << " us, skipping "
|
| + << (lag / frame_info_.frame_interval) << " frames";
|
| + }
|
| +
|
| + // Ensure monotonicity.
|
| + if (frame_count_++ == 0u)
|
| + return 0u;
|
| + if (frame_info_.frame_time < old_frame_time) {
|
| + MOJO_LOG(WARNING) << "Frame time is going backwards: new="
|
| + << frame_info_.frame_time << ", old=" << old_frame_time
|
| + << ", now=" << now;
|
| + frame_info_.frame_time = old_frame_time;
|
| + }
|
| + if (frame_info_.presentation_time < old_presentation_time) {
|
| + MOJO_LOG(WARNING) << "Presentation time is going backwards: new="
|
| + << frame_info_.presentation_time
|
| + << ", old=" << old_presentation_time << ", now=" << now;
|
| + frame_info_.presentation_time = old_presentation_time;
|
| + }
|
| + return frame_info_.frame_time - old_frame_time;
|
| +}
|
| +
|
| +} // namespace composition
|
| +} // namespace gfx
|
| +} // namespace mojo
|
|
|