Bug 1189901: part 2: scroll-tests: serialize asyncs with Promises. r=mconley

This commit is contained in:
Avi Halachmi 2016-09-27 16:43:37 +03:00
Родитель cc4bbce3d9
Коммит b29aeabfb3
1 изменённых файлов: 105 добавлений и 63 удалений

Просмотреть файл

@ -12,10 +12,63 @@ function testScroll(target, stepSize, opt_reportFunc, opt_numSteps)
win = window;
}
var report;
/**
* Sets up the value of 'report' as a function for reporting the test result[s].
* Chooses between the "usual" tpRecordTime which the pageloader addon injects
* to pages, or a custom function in case we're a framescript which pageloader
* added to the tested page, or a debug tpRecordTime from talos-debug.js if
* running in a plain browser.
*
* @returns Promise
*/
function P_setupReportFn() {
return new Promise(function(resolve) {
report = opt_reportFunc || win.tpRecordTime;
if (report == 'PageLoader:RecordTime') {
report = function(duration, start, name) {
var msg = { time: duration, startTime: start, testName: name };
sendAsyncMessage('PageLoader:RecordTime', msg);
}
resolve();
return;
}
// Not part of the test and does nothing if we're within talos.
// Provides an alternative tpRecordTime (with some stats display) if running in a browser.
if (!report && document.head) {
var imported = document.createElement('script');
imported.addEventListener("load", function() {
report = tpRecordTime;
resolve();
});
imported.src = '../../scripts/talos-debug.js?dummy=' + Date.now(); // For some browsers to re-read
document.head.appendChild(imported);
return;
}
resolve();
});
}
function FP_wait(ms) {
return function() {
return new Promise(function(resolve) {
setTimeout(resolve, ms);
});
};
}
function rAF(fn) {
return content.requestAnimationFrame(fn);
}
function P_rAF() {
return new Promise(function(resolve) {
rAF(resolve);
});
}
function myNow() {
return (win.performance && win.performance.now) ?
@ -44,79 +97,68 @@ function testScroll(target, stepSize, opt_reportFunc, opt_numSteps)
// For reference, rAF should fire on vsync, but Gecko currently doesn't use vsync.
// Instead, it uses 1000/layout.frame_rate
// (with 60 as default value when layout.frame_rate == -1).
function startTest()
{
// We should be at the top of the page now.
var start = myNow();
var lastScrollPos = getPos();
var lastScrollTime = start;
var durations = [];
var report = opt_reportFunc || tpRecordTime;
if (report == 'PageLoader:RecordTime') {
report = function(duration) {
var msg = { time: duration, startTime: '', testName: '' };
sendAsyncMessage('PageLoader:RecordTime', msg);
}
}
function P_syncScrollTest() {
return new Promise(function(resolve) {
// We should be at the top of the page now.
var start = myNow();
var lastScrollPos = getPos();
var lastScrollTime = start;
var durations = [];
function tick() {
var now = myNow();
var duration = now - lastScrollTime;
lastScrollTime = now;
function tick() {
var now = myNow();
var duration = now - lastScrollTime;
lastScrollTime = now;
durations.push(duration);
doScrollTick();
durations.push(duration);
doScrollTick();
/* stop scrolling if we can't scroll more, or if we've reached requested number of steps */
if ((getPos() == lastScrollPos) || (opt_numSteps && (durations.length >= (opt_numSteps + 2)))) {
if (typeof(Profiler) !== "undefined") {
Profiler.pause();
/* stop scrolling if we can't scroll more, or if we've reached requested number of steps */
if ((getPos() == lastScrollPos) || (opt_numSteps && (durations.length >= (opt_numSteps + 2)))) {
if (typeof(Profiler) !== "undefined") {
Profiler.pause();
}
// Note: The first (1-5) intervals WILL be longer than the rest.
// First interval might include initial rendering and be extra slow.
// Also requestAnimationFrame needs to sync (optimally in 1 frame) after long frames.
// Suggested: Ignore the first 5 intervals.
durations.pop(); // Last step was 0.
durations.pop(); // and the prev one was shorter and with end-of-page logic, ignore both.
if (win.talosDebug)
win.talosDebug.displayData = true; // In a browser: also display all data points.
// For analysis (otherwise, it's too many data points for talos):
var sum = 0;
for (var i = 0; i < durations.length; i++)
sum += Number(durations[i]);
// Report average interval or (failsafe) 0 if no intervls were recorded
resolve(durations.length ? sum / durations.length : 0);
return;
}
// Note: The first (1-5) intervals WILL be longer than the rest.
// First interval might include initial rendering and be extra slow.
// Also requestAnimationFrame needs to sync (optimally in 1 frame) after long frames.
// Suggested: Ignore the first 5 intervals.
durations.pop(); // Last step was 0.
durations.pop(); // and the prev one was shorter and with end-of-page logic, ignore both.
if (win.talosDebug)
win.talosDebug.displayData = true; // In a browser: also display all data points.
// For analysis (otherwise, it's too many data points for talos):
var sum = 0;
for (var i = 0; i < durations.length; i++)
sum += Number(durations[i]);
// Report average interval or (failsafe) 0 if no intervls were recorded
report(durations.length ? sum / durations.length : 0);
return;
lastScrollPos = getPos();
rAF(tick);
}
lastScrollPos = getPos();
if (typeof(Profiler) !== "undefined") {
Profiler.resume();
}
rAF(tick);
}
if (typeof(Profiler) !== "undefined") {
Profiler.resume();
}
rAF(tick);
});
}
// Not part of the test and does nothing if we're within talos,
// But provides an alternative tpRecordTime (with some stats display) if running in a browser
// If a callback is provided, then we don't need this debug reporting.
if(!opt_reportFunc && document.head) {
var imported = document.createElement('script');
imported.src = '../../scripts/talos-debug.js?dummy=' + Date.now(); // For some browsers to re-read
document.head.appendChild(imported);
}
setTimeout(function(){
gotoTop();
rAF(startTest);
}, 260);
P_setupReportFn()
.then(FP_wait(260))
.then(gotoTop)
.then(P_rAF)
.then(P_syncScrollTest)
.then(function(result) { // function since 'report' might not be ready when invoking 'then'
report(result);
});
}
// This code below here is unique to tscroll.js inside of pageloader