Commit 6f5d230b authored by nduca@chromium.org's avatar nduca@chromium.org

Use only the steady gesture in frame rate tests.

Store frame intervals in an array rather than throwing them away. This is to
enable more-detailed study of frame rates.

Report error as sigma directly, instead of 60 - 1000/sigma. This should help
understand whether standard deviation is even the right metric to use for frame
rate instability.


Review URL: http://codereview.chromium.org/8536008

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112774 0039d316-1c4b-4281-b951-d872f2087c98
parent f024fd5d
...@@ -41,12 +41,10 @@ var __old_title = ""; ...@@ -41,12 +41,10 @@ var __old_title = "";
var __raf_is_live = false; var __raf_is_live = false;
var __raf; var __raf;
var __t_start;
var __t_last; var __t_last;
var __t_est; var __t_est;
var __t_est_total; var __t_frame_intervals;
var __t_est_squared_total;
var __t_count;
var __t_start;
var __queued_gesture_functions; var __queued_gesture_functions;
var __results; var __results;
...@@ -67,6 +65,10 @@ var __gesture_library = { ...@@ -67,6 +65,10 @@ var __gesture_library = {
{"time_ms":1, "y":0}, {"time_ms":1, "y":0},
{"time_ms":5000, "y":0} {"time_ms":5000, "y":0}
], ],
steady: [
{"time_ms":1, "y":0},
{"time_ms":500, "y":400}
],
reading: [ reading: [
{"time_ms":1, "y":0}, {"time_ms":1, "y":0},
{"time_ms":842, "y":40}, {"time_ms":842, "y":40},
...@@ -180,22 +182,31 @@ function __gesture_stretch(gesture, stretch_factor) { ...@@ -180,22 +182,31 @@ function __gesture_stretch(gesture, stretch_factor) {
// Gesture set to use for testing, initialized with default gesture set. // Gesture set to use for testing, initialized with default gesture set.
// Redefine in test file to use a different set of gestures. // Redefine in test file to use a different set of gestures.
var __gestures = { var __gestures = {
none: __gesture_library["stationary"], steady: __gesture_library["steady"],
steady: __gesture_library["init"],
reading: __gesture_library["reading"],
mouse_wheel: __gesture_library["mouse_wheel"],
mac_fling: __gesture_library["mac_fling"],
}; };
function __init_stats() { function __init_stats() {
__t_last = undefined; __t_last = undefined;
__t_est = undefined; __t_est = undefined;
__t_est_total = 0; __t_frame_intervals = [];
__t_est_squared_total = 0;
__t_count = 0;
} }
__init_stats(); __init_stats();
var __cur_chrome_interval;
function __init_time() {
if (chrome.Interval) {
__cur_chrome_interval = new chrome.Interval();
__cur_chrome_interval.start();
}
}
__init_time();
function __get_time() {
if (__cur_chrome_interval)
return __cur_chrome_interval.microseconds() / 1000;
return new Date().getTime();
}
function __init_raf() { function __init_raf() {
if ("requestAnimationFrame" in window) if ("requestAnimationFrame" in window)
__raf = requestAnimationFrame; __raf = requestAnimationFrame;
...@@ -211,30 +222,39 @@ function __init_raf() { ...@@ -211,30 +222,39 @@ function __init_raf() {
// No raf implementation available, fake it with 16ms timeouts // No raf implementation available, fake it with 16ms timeouts
__raf = function(callback, element) { __raf = function(callback, element) {
setTimeout(callback, 16); setTimeout(callback, 16);
} };
} }
__init_raf(); __init_raf();
function __calc_results() { function __calc_results() {
var M = __t_est_total / __t_count; var M = 0.0;
var X = __t_est_squared_total / __t_count; var N = __t_frame_intervals.length;
var V = X - M * M;
var S = Math.sqrt(V); for (var i = 0; i < N; i++)
M += __t_frame_intervals[i];
M = M / N;
var V = 0.0;
for (var i = 0; i < N; i++) {
var v = __t_frame_intervals[i] - M;
V += v * v;
}
var S = Math.sqrt(V / (N - 1));
var R = new Object(); var R = new Object();
R.mean = 1000.0 / M; R.mean = M;
R.sigma = R.mean - 1000.0 / (M + S); R.sigma = S;
return R; return R;
} }
function __calc_results_total() { function __calc_results_total() {
if (!__results) { if (!__results) {
return; return {};
} }
var size = __results.gestures.length; var size = __results.gestures.length;
var mean = 0; var mean = 0;
var variance = 0; var variance = 0;
var sigma;
// Remove any intial caching test(s). // Remove any intial caching test(s).
while (__results.means.length != size) { while (__results.means.length != size) {
...@@ -247,7 +267,7 @@ function __calc_results_total() { ...@@ -247,7 +267,7 @@ function __calc_results_total() {
} }
mean /= size; mean /= size;
variance /= size; variance /= size;
sigma = Math.sqrt(variance); var sigma = Math.sqrt(variance);
var results = new Object(); var results = new Object();
// GTest expects a comma-separated string for lists. // GTest expects a comma-separated string for lists.
...@@ -259,8 +279,8 @@ function __calc_results_total() { ...@@ -259,8 +279,8 @@ function __calc_results_total() {
return results; return results;
} }
function __update_fps() { function __record_frame_time() {
var t_now = new Date().getTime(); var t_now = __get_time();
if (window.__t_last) { if (window.__t_last) {
var t_delta = t_now - __t_last; var t_delta = t_now - __t_last;
if (window.__t_est) { if (window.__t_est) {
...@@ -268,12 +288,11 @@ function __update_fps() { ...@@ -268,12 +288,11 @@ function __update_fps() {
} else { } else {
__t_est = t_delta; __t_est = t_delta;
} }
var fps = 1000.0 / __t_est;
document.title = "FPS: " + (fps | 0);
__t_est_total += t_delta; __t_frame_intervals.push(t_delta);
__t_est_squared_total += t_delta * t_delta;
__t_count++; var fps = 1000.0 / __t_est;
document.title = "FPS: " + fps;
} }
__t_last = t_now; __t_last = t_now;
} }
...@@ -283,7 +302,7 @@ function __advance_gesture_recording() { ...@@ -283,7 +302,7 @@ function __advance_gesture_recording() {
var y = document.body.scrollTop; var y = document.body.scrollTop;
// Only add a gesture if the scroll position changes. // Only add a gesture if the scroll position changes.
if (__recording.length == 0 || y != __recording[__recording.length - 1].y) { if (__recording.length == 0 || y != __recording[__recording.length - 1].y) {
var time_ms = new Date().getTime() - __t_start; var time_ms = __get_time() - __t_start;
__recording.push({ time_ms: time_ms, y: y }); __recording.push({ time_ms: time_ms, y: y });
return true; return true;
} }
...@@ -319,7 +338,7 @@ function __create_gesture_function(gestures) { ...@@ -319,7 +338,7 @@ function __create_gesture_function(gestures) {
__stop(); __stop();
return false; return false;
} }
var time_cur = new Date().getTime() - __t_start; var time_cur = __get_time() - __t_start;
if (time_cur <= gestures[i0].time_ms) if (time_cur <= gestures[i0].time_ms)
return false; return false;
...@@ -377,15 +396,15 @@ function __sched_update() { ...@@ -377,15 +396,15 @@ function __sched_update() {
__raf_is_live = true; __raf_is_live = true;
// In case __raf falls back to using setTimeout, we must schedule the next // In case __raf falls back to using setTimeout, we must schedule the next
// update before rendering the current update to help maintain the // update before rendering the current update to help maintain the
// regularity of update intervals. // regularity of update frame_intervals.
__sched_update(); __sched_update();
if (__running) { if (__running) {
// Only update the FPS if a gesture movement occurs. Otherwise, the frame // Only update the FPS if a gesture movement occurs. Otherwise, the frame
// rate average becomes inaccurate after any pause. // rate average becomes inaccurate after any pause.
if (__advance_gesture()) if (__advance_gesture())
__update_fps(); __record_frame_time();
else else
__t_last = new Date().getTime(); __t_last = __get_time();
} }
}, document.body); }, document.body);
} }
...@@ -419,7 +438,7 @@ function __start(gesture_function) { ...@@ -419,7 +438,7 @@ function __start(gesture_function) {
__old_title = document.title; __old_title = document.title;
__advance_gesture = gesture_function; __advance_gesture = gesture_function;
__t_start = new Date().getTime(); __t_start = __get_time();
__running = true; __running = true;
if (!__raf_is_live && !__animation) { if (!__raf_is_live && !__animation) {
__sched_update(); __sched_update();
......
...@@ -84,6 +84,12 @@ class FrameRateTest ...@@ -84,6 +84,12 @@ class FrameRateTest
if (HasFlag(kUseReferenceBuild)) if (HasFlag(kUseReferenceBuild))
UseReferenceBuild(); UseReferenceBuild();
// Turn on chrome.Interval to get higher-resolution timestamps on frames.
launch_arguments_.AppendSwitch(switches::kEnableBenchmarking);
// Required additional argument to make the kEnableBenchmarking switch work.
launch_arguments_.AppendSwitch(switches::kEnableStatsTable);
// UI tests boot up render views starting from about:blank. This causes // UI tests boot up render views starting from about:blank. This causes
// the renderer to start up thinking it cannot use the GPU. To work // the renderer to start up thinking it cannot use the GPU. To work
// around that, and allow the frame rate test to use the GPU, we must // around that, and allow the frame rate test to use the GPU, we must
...@@ -132,7 +138,8 @@ class FrameRateTest ...@@ -132,7 +138,8 @@ class FrameRateTest
void RunTest(const std::string& name) { void RunTest(const std::string& name) {
if (HasFlag(kUseGpu) && !IsGpuAvailable()) { if (HasFlag(kUseGpu) && !IsGpuAvailable()) {
printf("Test skipped: requires gpu\n"); printf("Test skipped: requires gpu. Pass --enable-gpu on the command "
"line if use of GPU is desired.\n");
return; return;
} }
...@@ -218,7 +225,7 @@ class FrameRateTest ...@@ -218,7 +225,7 @@ class FrameRateTest
ASSERT_TRUE(results.find("means") != results.end()); ASSERT_TRUE(results.find("means") != results.end());
ASSERT_TRUE(results.find("sigmas") != results.end()); ASSERT_TRUE(results.find("sigmas") != results.end());
std::string trace_name = "fps" + GetSuffixForTestFlags(); std::string trace_name = "interval" + GetSuffixForTestFlags();
printf("GESTURES %s: %s= [%s] [%s] [%s]\n", name.c_str(), printf("GESTURES %s: %s= [%s] [%s] [%s]\n", name.c_str(),
trace_name.c_str(), trace_name.c_str(),
results["gestures"].c_str(), results["gestures"].c_str(),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment