1 // Copyright 2013 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.
8 * @fileoverview This file provides the RenderingStats object, used
9 * to characterize rendering smoothness.
12 var getTimeMs = (function() {
13 if (window.performance)
14 return (performance.now ||
18 performance.webkitNow).bind(window.performance);
20 return function() { return new Date().getTime(); };
23 var requestAnimationFrame = (function() {
24 return window.requestAnimationFrame ||
25 window.webkitRequestAnimationFrame ||
26 window.mozRequestAnimationFrame ||
27 window.oRequestAnimationFrame ||
28 window.msRequestAnimationFrame ||
30 window.setTimeout(callback, 1000 / 60);
35 * Tracks rendering performance using the gpuBenchmarking.renderingStats API.
38 function GpuBenchmarkingRenderingStats() {
41 GpuBenchmarkingRenderingStats.prototype.start = function() {
42 this.startTime_ = getTimeMs();
43 this.initialStats_ = this.getRenderingStats_();
46 GpuBenchmarkingRenderingStats.prototype.stop = function() {
47 this.stopTime_ = getTimeMs();
48 this.finalStats_ = this.getRenderingStats_();
51 GpuBenchmarkingRenderingStats.prototype.getStartValues = function() {
52 if (!this.initialStats_)
53 throw new Error('Start not called.');
55 if (!this.finalStats_)
56 throw new Error('Stop was not called.');
58 return this.initialStats_;
61 GpuBenchmarkingRenderingStats.prototype.getEndValues = function() {
62 if (!this.initialStats_)
63 throw new Error('Start not called.');
65 if (!this.finalStats_)
66 throw new Error('Stop was not called.');
68 return this.finalStats_;
71 GpuBenchmarkingRenderingStats.prototype.getDeltas = function() {
72 if (!this.initialStats_)
73 throw new Error('Start not called.');
75 if (!this.finalStats_)
76 throw new Error('Stop was not called.');
79 for (var key in this.finalStats_)
80 stats[key] = this.finalStats_[key] - this.initialStats_[key];
84 GpuBenchmarkingRenderingStats.prototype.isUsingGpuBenchmarking = function() {
88 GpuBenchmarkingRenderingStats.prototype.getRenderingStats_ = function() {
89 var stats = chrome.gpuBenchmarking.renderingStats();
90 stats.totalTimeInSeconds = getTimeMs() / 1000;
95 * Tracks rendering performance using requestAnimationFrame.
98 function RafRenderingStats() {
99 this.recording_ = false;
100 this.frameTimes_ = [];
103 RafRenderingStats.prototype.start = function() {
105 throw new Error('Already started.');
106 this.recording_ = true;
107 requestAnimationFrame(this.recordFrameTime_.bind(this));
110 RafRenderingStats.prototype.stop = function() {
111 this.recording_ = false;
114 RafRenderingStats.prototype.getStartValues = function() {
116 results.numAnimationFrames = 0;
117 results.numFramesSentToScreen = 0;
118 results.droppedFrameCount = 0;
122 RafRenderingStats.prototype.getEndValues = function() {
124 results.numAnimationFrames = this.frameTimes_.length - 1;
125 results.numFramesSentToScreen = results.numAnimationFrames;
126 results.droppedFrameCount = this.getDroppedFrameCount_(this.frameTimes_);
130 RafRenderingStats.prototype.getDeltas = function() {
131 var endValues = this.getEndValues();
132 endValues.totalTimeInSeconds = (
133 this.frameTimes_[this.frameTimes_.length - 1] -
134 this.frameTimes_[0]) / 1000;
138 RafRenderingStats.prototype.isUsingGpuBenchmarking = function() {
142 RafRenderingStats.prototype.recordFrameTime_ = function(timestamp) {
143 if (!this.recording_)
146 this.frameTimes_.push(timestamp);
147 requestAnimationFrame(this.recordFrameTime_.bind(this));
150 RafRenderingStats.prototype.getDroppedFrameCount_ = function(frameTimes) {
151 var droppedFrameCount = 0;
152 var droppedFrameThreshold = 1000 / 55;
153 for (var i = 1; i < frameTimes.length; i++) {
154 var frameTime = frameTimes[i] - frameTimes[i-1];
155 if (frameTime > droppedFrameThreshold)
156 droppedFrameCount += Math.floor(frameTime / droppedFrameThreshold);
158 return droppedFrameCount;
161 function RenderingStats() {
162 if (window.chrome && chrome.gpuBenchmarking &&
163 chrome.gpuBenchmarking.renderingStats) {
164 return new GpuBenchmarkingRenderingStats();
166 return new RafRenderingStats();
169 window.__RenderingStats = RenderingStats;