| // 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; |
| } |