1 // Copyright (c) 2012 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.
5 // Run benchmark for at least this many milliseconds.
6 var minTotalTimeMs = 10 * 1000;
7 // Run benchmark at least this many times.
9 // Discard results for this many milliseconds after startup.
10 var warmUpTimeMs = 1000;
11 var benchmarkStartTime;
13 var loadingTimesMs = [];
17 var now = (function() {
18 if (window.performance)
19 return (window.performance.now ||
20 window.performance.webkitNow).bind(window.performance);
21 return Date.now.bind(window);
24 getImageFormat = function() {
25 if (document.location.search) {
26 return document.location.search.substr(1);
31 prepareImageElement = function() {
32 img = document.createElement('img');
33 // Scale the image down to the display size to make sure the entire image is
34 // decoded. If the image is much larger than the display, some browsers might
35 // only decode the visible portion of the image, which would skew the results
37 img.setAttribute('width', '100%');
38 img.setAttribute('height', '100%');
39 document.body.appendChild(img);
40 console.log("Running benchmark for at least " + minTotalTimeMs +
41 " ms and at least " + minIterations + " times.");
42 document.getElementById('status').innerHTML = "Benchmark running.";
43 setStatus(getImageFormat().toUpperCase() + " benchmark running.");
44 benchmarkStartTimeMs = now();
47 setStatus = function(status) {
48 document.getElementById('status').innerHTML = status;
51 runBenchmark = function() {
52 setStatus("Preparing benchmark.");
53 prepareImageElement();
57 var iteration = (new Date).getTime();
59 startLoadingImage = function() {
60 img.style.display = 'none';
61 img.setAttribute('onload', '');
62 img.setAttribute('src', '');
63 img.addEventListener('load', onImageLoaded);
65 // Setting 'src' and 'display' above causes a repaint. Let it finish before
66 // loading a new image. Ensures loading and painting don't overlap.
67 requestAnimationFrame(function() {
68 loadStartTimeMs = now();
69 // Use a unique URL for each test iteration to work around image caching.
70 img.setAttribute('src', 'droids.' + getImageFormat() + '?' + iteration);
75 var requestAnimationFrame = (function() {
76 return window.requestAnimationFrame ||
77 window.webkitRequestAnimationFrame ||
78 window.mozRequestAnimationFrame ||
79 window.oRequestAnimationFrame ||
80 window.msRequestAnimationFrame ||
82 window.setTimeout(callback, 1000 / 60);
86 onImageLoaded = function() {
88 var loadingTimeMs = nowMs - loadStartTimeMs;
89 if (nowMs - benchmarkStartTimeMs >= warmUpTimeMs) {
90 loadingTimesMs.push(loadingTimeMs);
92 if (nowMs - benchmarkStartTimeMs < minTotalTimeMs ||
93 loadingTimesMs.length < minIterations) {
94 // Repaint happens right after the image is loaded. Make sure painting
95 // is completed before making the image visible. Setting the image to
96 // visible will start decoding. After decoding and painting are completed
97 // we'll start next test iteration.
98 // Double rAF is needed here otherwise the image is barely visible.
99 requestAnimationFrame(function() {
100 img.style.display = '';
101 requestAnimationFrame(startLoadingImage);
105 console.log("loadingTimes: " + loadingTimesMs);
106 setStatus(getImageFormat().toUpperCase() + " benchmark finished: " +
111 averageLoadingTimeMs = function() {
112 if (!loadingTimesMs.length)
115 for (var i = 0; i < loadingTimesMs.length; ++i) {
116 total += loadingTimesMs[i];
118 return total / loadingTimesMs.length;