OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 /** | 5 /** |
6 * @fileoverview Perform various "gestures" and calculate average frame rate. | 6 * @fileoverview Perform various "gestures" and calculate average frame rate. |
7 * "Gestures" are recorded scrolling behaviors in terms of time (ms) and | 7 * "Gestures" are recorded scrolling behaviors in terms of time (ms) and |
8 * absolute positions. | 8 * absolute positions. |
9 * | 9 * |
10 * How to run a single gesture: | 10 * How to run a single gesture: |
(...skipping 16 matching lines...) Expand all Loading... |
27 * 5) Copy the output from "JSON.stringify(__recording)" in the console. | 27 * 5) Copy the output from "JSON.stringify(__recording)" in the console. |
28 * 6) Paste the output in this file as a new member of __gestures. | 28 * 6) Paste the output in this file as a new member of __gestures. |
29 * 7) Copy the formatting from other gestures. | 29 * 7) Copy the formatting from other gestures. |
30 * Example: | 30 * Example: |
31 * new_gesture_name: [ | 31 * new_gesture_name: [ |
32 * {"time_ms":1, "y":0}, | 32 * {"time_ms":1, "y":0}, |
33 * ... pasted output ... | 33 * ... pasted output ... |
34 * ], | 34 * ], |
35 */ | 35 */ |
36 | 36 |
| 37 var __initialized = true; |
37 var __running = false; | 38 var __running = false; |
38 var __running_all = false; | 39 var __running_all = false; |
39 var __old_title = ""; | 40 var __old_title = ""; |
40 var __raf_is_live = false; | 41 var __raf_is_live = false; |
41 var __raf; | 42 var __raf; |
42 | 43 |
43 var __t_last; | 44 var __t_last; |
44 var __t_est; | 45 var __t_est; |
45 var __t_est_total; | 46 var __t_est_total; |
46 var __t_est_squared_total; | 47 var __t_est_squared_total; |
47 var __t_count; | 48 var __t_count; |
48 var __t_start; | 49 var __t_start; |
49 | 50 |
50 var __queued_gesture_functions; | 51 var __queued_gesture_functions; |
51 var __results; | 52 var __results; |
52 | 53 |
53 var __recording = []; | 54 var __recording = []; |
54 var __advance_gesture; | 55 var __advance_gesture; |
55 var __gestures = { | 56 |
56 none: [ | 57 // This flag indicates whether the test page contains an animation loop |
| 58 // For more on testing animated pages, see head_animation.js |
| 59 var __animation = false; |
| 60 |
| 61 var __gesture_library = { |
| 62 init: [ |
| 63 {"time_ms":1, "y":0}, |
| 64 {"time_ms":5, "y":10} |
| 65 ], |
| 66 stationary: [ |
57 {"time_ms":1, "y":0}, | 67 {"time_ms":1, "y":0}, |
58 {"time_ms":5000, "y":0} | 68 {"time_ms":5000, "y":0} |
59 ], | 69 ], |
60 steady: [ | |
61 {"time_ms":1, "y":0}, | |
62 {"time_ms":5, "y":10} | |
63 ], | |
64 reading: [ | 70 reading: [ |
65 {"time_ms":1, "y":0}, | 71 {"time_ms":1, "y":0}, |
66 {"time_ms":842, "y":40}, | 72 {"time_ms":842, "y":40}, |
67 {"time_ms":858, "y":67}, | 73 {"time_ms":858, "y":67}, |
68 {"time_ms":874, "y":94}, | 74 {"time_ms":874, "y":94}, |
69 {"time_ms":890, "y":149}, | 75 {"time_ms":890, "y":149}, |
70 {"time_ms":907, "y":203}, | 76 {"time_ms":907, "y":203}, |
71 {"time_ms":923, "y":257}, | 77 {"time_ms":923, "y":257}, |
72 {"time_ms":939, "y":311}, | 78 {"time_ms":939, "y":311}, |
73 {"time_ms":955, "y":393}, | 79 {"time_ms":955, "y":393}, |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 {"time_ms":911, "y":1273}, | 160 {"time_ms":911, "y":1273}, |
155 {"time_ms":941, "y":1275}, | 161 {"time_ms":941, "y":1275}, |
156 {"time_ms":958, "y":1282}, | 162 {"time_ms":958, "y":1282}, |
157 {"time_ms":976, "y":1288}, | 163 {"time_ms":976, "y":1288}, |
158 {"time_ms":993, "y":1291}, | 164 {"time_ms":993, "y":1291}, |
159 {"time_ms":1022, "y":1294}, | 165 {"time_ms":1022, "y":1294}, |
160 {"time_ms":1055, "y":1302} | 166 {"time_ms":1055, "y":1302} |
161 ], | 167 ], |
162 }; | 168 }; |
163 | 169 |
| 170 // Stretch the duration of a gesture by a given factor |
| 171 function __gesture_stretch(gesture, stretch_factor) { |
| 172 // clone the gesture |
| 173 var new_gesture = JSON.parse(JSON.stringify(gesture)); |
| 174 for (var i = 0; i < new_gesture.length; ++i) { |
| 175 new_gesture[i].time_ms *= stretch_factor; |
| 176 } |
| 177 return new_gesture; |
| 178 } |
| 179 |
| 180 // Gesture set to use for testing, initialized with default gesture set. |
| 181 // Redefine in test file to use a different set of gestures. |
| 182 var __gestures = { |
| 183 none: __gesture_library["stationary"], |
| 184 steady: __gesture_library["init"], |
| 185 reading: __gesture_library["reading"], |
| 186 mouse_wheel: __gesture_library["mouse_wheel"], |
| 187 mac_fling: __gesture_library["mac_fling"], |
| 188 }; |
| 189 |
164 function __init_stats() { | 190 function __init_stats() { |
165 __t_last = undefined; | 191 __t_last = undefined; |
166 __t_est = undefined; | 192 __t_est = undefined; |
167 __t_est_total = 0; | 193 __t_est_total = 0; |
168 __t_est_squared_total = 0; | 194 __t_est_squared_total = 0; |
169 __t_count = 0; | 195 __t_count = 0; |
170 } | 196 } |
171 __init_stats(); | 197 __init_stats(); |
172 | 198 |
| 199 function __init_raf() { |
| 200 if ("requestAnimationFrame" in window) |
| 201 __raf = requestAnimationFrame; |
| 202 else if ("webkitRequestAnimationFrame" in window) |
| 203 __raf = webkitRequestAnimationFrame; |
| 204 else if ("mozRequestAnimationFrame" in window) |
| 205 __raf = mozRequestAnimationFrame; |
| 206 else if ("oRequestAnimationFrame" in window) |
| 207 __raf = oRequestAnimationFrame; |
| 208 else if ("msRequestAnimationFrame" in window) |
| 209 __raf = msRequestAnimationFrame; |
| 210 else |
| 211 // No raf implementation available, fake it with 16ms timeouts |
| 212 __raf = function(callback, element) { |
| 213 setTimeout(callback, 16); |
| 214 } |
| 215 } |
| 216 __init_raf(); |
| 217 |
173 function __calc_results() { | 218 function __calc_results() { |
174 var M = __t_est_total / __t_count; | 219 var M = __t_est_total / __t_count; |
175 var X = __t_est_squared_total / __t_count; | 220 var X = __t_est_squared_total / __t_count; |
176 var V = X - M * M; | 221 var V = X - M * M; |
177 var S = Math.sqrt(V); | 222 var S = Math.sqrt(V); |
178 | 223 |
179 var R = new Object(); | 224 var R = new Object(); |
180 R.mean = 1000.0 / M; | 225 R.mean = 1000.0 / M; |
181 R.sigma = R.mean - 1000.0 / (M + S); | 226 R.sigma = R.mean - 1000.0 / (M + S); |
182 return R; | 227 return R; |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 y = gestures[i].y + dy; | 366 y = gestures[i].y + dy; |
322 gestures.push({ | 367 gestures.push({ |
323 time_ms: gestures[i].time_ms + dtime_ms, | 368 time_ms: gestures[i].time_ms + dtime_ms, |
324 y: y, | 369 y: y, |
325 }); | 370 }); |
326 } | 371 } |
327 return __create_gesture_function(gestures); | 372 return __create_gesture_function(gestures); |
328 } | 373 } |
329 | 374 |
330 function __sched_update() { | 375 function __sched_update() { |
331 if (!__raf) { | |
332 if ("webkitRequestAnimationFrame" in window) | |
333 __raf = webkitRequestAnimationFrame; | |
334 else if ("mozRequestAnimationFrame" in window) | |
335 __raf = mozRequestAnimationFrame; | |
336 } | |
337 __raf(function() { | 376 __raf(function() { |
338 __raf_is_live = true; | 377 __raf_is_live = true; |
| 378 // In case __raf falls back to using setTimeout, we must schedule the next |
| 379 // update before rendering the current update to help maintain the |
| 380 // regularity of update intervals. |
| 381 __sched_update(); |
339 if (__running) { | 382 if (__running) { |
340 // Only update the FPS if a gesture movement occurs. Otherwise, the frame | 383 // Only update the FPS if a gesture movement occurs. Otherwise, the frame |
341 // rate average becomes inaccurate after any pause. | 384 // rate average becomes inaccurate after any pause. |
342 if (__advance_gesture()) | 385 if (__advance_gesture()) |
343 __update_fps(); | 386 __update_fps(); |
344 else | 387 else |
345 __t_last = new Date().getTime(); | 388 __t_last = new Date().getTime(); |
346 } | 389 } |
347 __sched_update(); | |
348 }, document.body); | 390 }, document.body); |
349 } | 391 } |
350 | 392 |
351 function __start_recording() { | 393 function __start_recording() { |
352 __start(__advance_gesture_recording); | 394 __start(__advance_gesture_recording); |
353 } | 395 } |
354 | 396 |
355 function __make_body_composited() { | 397 function __make_body_composited() { |
356 document.body.style.webkitTransform = "translateZ(0)"; | 398 document.body.style.webkitTransform = "translateZ(0)"; |
357 } | 399 } |
358 | 400 |
359 function __start(gesture_function) { | 401 function __start(gesture_function) { |
360 if (__running) | 402 if (__running) |
361 return; | 403 return; |
362 // Attempt to create a gesture function from a string name. | 404 // Attempt to create a gesture function from a string name. |
363 if (typeof gesture_function == "string") { | 405 if (typeof gesture_function == "string") { |
364 if (!__gestures[gesture_function]) | 406 if (!__gestures[gesture_function]) { |
365 throw new Error("Unrecognized gesture name"); | 407 if (!__gesture_library[gesture_function]) |
| 408 throw new Error("Unrecognized gesture name"); |
| 409 else |
| 410 gesture_function = __create_repeating_gesture_function( |
| 411 __gesture_library[gesture_function]); |
| 412 } |
366 else | 413 else |
367 gesture_function = __create_repeating_gesture_function( | 414 gesture_function = __create_repeating_gesture_function( |
368 __gestures[gesture_function]); | 415 __gestures[gesture_function]); |
369 } | 416 } |
370 else if (typeof gesture_function != "function") | 417 else if (typeof gesture_function != "function") |
371 throw new Error("Argument is not a function or gesture name"); | 418 throw new Error("Argument is not a function or gesture name"); |
372 | 419 |
373 __old_title = document.title; | 420 __old_title = document.title; |
374 __advance_gesture = gesture_function; | 421 __advance_gesture = gesture_function; |
375 __t_start = new Date().getTime(); | 422 __t_start = new Date().getTime(); |
376 __running = true; | 423 __running = true; |
377 if (!__raf_is_live) { | 424 if (!__raf_is_live && !__animation) { |
378 __sched_update(); | 425 __sched_update(); |
379 } | 426 } |
380 } | 427 } |
381 | 428 |
382 function __start_all() { | 429 function __start_all() { |
383 __queued_gesture_functions = []; | 430 __queued_gesture_functions = []; |
384 __results = { | 431 __results = { |
385 gestures: [], | 432 gestures: [], |
386 means: [], | 433 means: [], |
387 sigmas: [], | 434 sigmas: [], |
388 }; | 435 }; |
389 | 436 |
390 for (var gesture in __gestures) { | 437 for (var gesture in __gestures) { |
391 __results.gestures.push(gesture); | 438 __results.gestures.push(gesture); |
392 __queued_gesture_functions.push(gesture); | 439 __queued_gesture_functions.push(gesture); |
393 } | 440 } |
394 __running_all = true; | 441 __running_all = true; |
395 // Run steady gesture once to cache the webpage layout for subsequent tests. | 442 // Run init gesture once to cache the webpage layout for subsequent tests. |
396 __start("steady"); | 443 __start("init"); |
397 } | 444 } |
398 | 445 |
399 function __stop() { | 446 function __stop() { |
400 __running = false; | 447 __running = false; |
401 document.title = __old_title; | 448 document.title = __old_title; |
402 window.__scrolledTo = undefined; | 449 window.__scrolledTo = undefined; |
403 | 450 |
404 if (__running_all) { | 451 if (__running_all) { |
405 var results = __calc_results(); | 452 var results = __calc_results(); |
406 __results.means.push(results.mean); | 453 __results.means.push(results.mean); |
(...skipping 13 matching lines...) Expand all Loading... |
420 __running = false; | 467 __running = false; |
421 __running_all = false; | 468 __running_all = false; |
422 document.title = __old_title; | 469 document.title = __old_title; |
423 document.body.scrollTop = 0; | 470 document.body.scrollTop = 0; |
424 __init_stats(); | 471 __init_stats(); |
425 } | 472 } |
426 | 473 |
427 function __force_compositor() { | 474 function __force_compositor() { |
428 document.body.style.webkitTransform = "translateZ(0)"; | 475 document.body.style.webkitTransform = "translateZ(0)"; |
429 } | 476 } |
OLD | NEW |