Index: cc/rendering_stats_subscriber.cc |
diff --git a/cc/rendering_stats_subscriber.cc b/cc/rendering_stats_subscriber.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..557c7f8354c3bfdbeb66e86573b7808ba514afc7 |
--- /dev/null |
+++ b/cc/rendering_stats_subscriber.cc |
@@ -0,0 +1,85 @@ |
+// Copyright 2012 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 "config.h" |
+ |
+#include "rendering_stats_subscriber.h" |
+ |
+#include <cmath> |
+ |
+namespace { |
+// If a frame takes less than 1/70 seconds, we will assume it is an error and |
+// ignore it. |
+static const double kFrameTooFast = 1.0 / 70.0; |
+} // namespace |
+ |
+namespace cc { |
+ |
+scoped_ptr<RenderingStatsSubscriber> RenderingStatsSubscriber::create() |
+{ |
+ scoped_ptr<RenderingStatsSubscriber> subscriber(new RenderingStatsSubscriber); |
+ return subscriber.Pass(); |
+} |
+ |
+RenderingStatsSubscriber::RenderingStatsSubscriber() |
+ : is_scrolling_(false), |
+ has_scrolled_(false) |
+{} |
+ |
+RenderingStatsSubscriber::~RenderingStatsSubscriber() {} |
+ |
+void RenderingStatsSubscriber::markBeginningOfFrame(base::TimeTicks timestamp) { |
+ // We ignore timestamps that occur after the scroll. |
+ if (has_scrolled_ && !is_scrolling_) |
+ return; |
+ |
+ bool should_add_timestamp = time_stamp_history_.empty(); |
+ if (!should_add_timestamp) { |
+ base::TimeDelta delta = timestamp - time_stamp_history_.back(); |
+ should_add_timestamp = delta.InMillisecondsF() > kFrameTooFast; |
+ } |
+ if (should_add_timestamp) |
+ time_stamp_history_.push_back(timestamp); |
+} |
+ |
+void RenderingStatsSubscriber::handledScrollEvent(bool content_did_move) { |
+ if (!has_scrolled_ && content_did_move) { |
+ // We're starting a scroll. We'll want to measure the framerate during the |
+ // scroll, so we'll discard any timestamps we've gathered so far. |
+ time_stamp_history_.clear(); |
+ has_scrolled_ = true; |
+ } |
+ |
+ is_scrolling_ = content_did_move; |
+} |
+ |
+void RenderingStatsSubscriber::getFPSAndStandardDeviation( |
+ double& average_fps, |
+ double& standard_deviation) const { |
+ |
+ base::TimeDelta duration = |
+ time_stamp_history_.front() - time_stamp_history_.back(); |
+ |
+ double average_frame_duration = duration.InSecondsF() / |
+ static_cast<double>(time_stamp_history_.size()); |
+ |
+ if (average_frame_duration > 0.0) |
+ average_fps = 1.0 / average_frame_duration; |
+ |
+ if (time_stamp_history_.size() > 2) { |
+ double sum_squared_distances_to_mean = 0.0; |
+ for (size_t i = 1; i < time_stamp_history_.size(); ++i) { |
+ base::TimeDelta frame_duration = |
+ time_stamp_history_[i] - time_stamp_history_[i - 1]; |
+ double signed_distance_to_mean = |
+ average_fps - (1.0 / frame_duration.InSecondsF()); |
+ sum_squared_distances_to_mean += |
+ signed_distance_to_mean * signed_distance_to_mean; |
+ } |
+ standard_deviation = std::sqrt(sum_squared_distances_to_mean / |
+ static_cast<double>(time_stamp_history_.size() - 2)); |
+ } |
+} |
+ |
+} // namespace cc |