// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Run benchmark for at least this many milliseconds.
var minTotalTimeMs = 10 * 1000;
// Run benchmark at least this many times.
var minIterations = 5;
// Discard results for this many milliseconds after startup.
var warmUpTimeMs = 1000;
var benchmarkStartTime;
var loadStartTimeMs;
var loadingTimesMs = [];
var isDone = false;
var img;
var now = (function() {
if (window.performance)
return (window.performance.now ||
window.performance.webkitNow).bind(window.performance);
return Date.now.bind(window);
})();
getImageFormat = function() {
if (document.location.search) {
return document.location.search.substr(1);
}
return "jpg";
}
prepareImageElement = function() {
img = document.createElement('img');
// Scale the image down to the display size to make sure the entire image is
// decoded. If the image is much larger than the display, some browsers might
// only decode the visible portion of the image, which would skew the results
// of this test.
img.setAttribute('width', '100%');
img.setAttribute('height', '100%');
document.body.appendChild(img);
console.log("Running benchmark for at least " + minTotalTimeMs +
" ms and at least " + minIterations + " times.");
document.getElementById('status').innerHTML = "Benchmark running.";
setStatus(getImageFormat().toUpperCase() + " benchmark running.");
benchmarkStartTimeMs = now();
}
setStatus = function(status) {
document.getElementById('status').innerHTML = status;
}
runBenchmark = function() {
setStatus("Preparing benchmark.");
prepareImageElement();
startLoadingImage();
}
var iteration = (new Date).getTime();
startLoadingImage = function() {
img.style.display = 'none';
img.setAttribute('onload', '');
img.setAttribute('src', '');
img.addEventListener('load', onImageLoaded);
// Setting 'src' and 'display' above causes a repaint. Let it finish before
// loading a new image. Ensures loading and painting don't overlap.
requestAnimationFrame(function() {
loadStartTimeMs = now();
// Use a unique URL for each test iteration to work around image caching.
img.setAttribute('src', 'droids.' + getImageFormat() + '?' + iteration);
iteration += 1;
});
}
var requestAnimationFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})().bind(window);
onImageLoaded = function() {
var nowMs = now();
var loadingTimeMs = nowMs - loadStartTimeMs;
if (nowMs - benchmarkStartTimeMs >= warmUpTimeMs) {
loadingTimesMs.push(loadingTimeMs);
}
if (nowMs - benchmarkStartTimeMs < minTotalTimeMs ||
loadingTimesMs.length < minIterations) {
// Repaint happens right after the image is loaded. Make sure painting
// is completed before making the image visible. Setting the image to
// visible will start decoding. After decoding and painting are completed
// we'll start next test iteration.
// Double rAF is needed here otherwise the image is barely visible.
requestAnimationFrame(function() {
img.style.display = '';
requestAnimationFrame(startLoadingImage);
});
} else {
isDone = true;
console.log("loadingTimes: " + loadingTimesMs);
setStatus(getImageFormat().toUpperCase() + " benchmark finished: " +
loadingTimesMs);
}
}
averageLoadingTimeMs = function() {
if (!loadingTimesMs.length)
return 0;
var total = 0;
for (var i = 0; i < loadingTimesMs.length; ++i) {
total += loadingTimesMs[i];
}
return total / loadingTimesMs.length;
}