Skip to content

Commit

Permalink
Revert "Add RAF tests to blink_perf.canvas benchmark."
Browse files Browse the repository at this point in the history
This reverts commit 7149ab7.
https://chromium-review.googlesource.com/c/chromium/src/+/1300038

TBR=nednguyen@google.com

Bug: 908515
Change-Id: I08a2b7adbf9fa20c8ccc2d8b6573981f0828c12d
Reviewed-on: https://chromium-review.googlesource.com/c/1351501
Reviewed-by: Caleb Rouleau <crouleau@chromium.org>
Reviewed-by: Fernando Serboncini <fserb@chromium.org>
Commit-Queue: Caleb Rouleau <crouleau@chromium.org>
Cr-Commit-Position: refs/heads/master@{#610974}
  • Loading branch information
CalebRouleau committed Nov 26, 2018
1 parent 1ac2b95 commit 9743711
Show file tree
Hide file tree
Showing 26 changed files with 695 additions and 6,060 deletions.
22 changes: 0 additions & 22 deletions docs/speed/benchmark/harnesses/blink_perf.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,28 +147,6 @@ Example of tracing asynchronous tests:

[simple-blob-measure-async.html](https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/perf_tests/test_data/simple-blob-measure-async.html)

## Canvas Tests

The sub-framework [canvas_runner.js](https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/perf_tests/canvas/resources/canvas_runner.js) is used for
tests in the `canvas` directory. This can measure rasterization and GPU time
using requestAnimationFrame (RAF) and contains a callback framework for video.

Normal tests using `runTest()` work similarly to the asynchronous test above,
but crucially wait for RAF after completing a single trial of
`MEASURE_DRAW_TIMES` runs.

RAF tests are triggered by appending the query string `raf` (case insensitive)
to the test's url. These tests wait for RAF to return before making a
measurement. This way rasterization and GPU time are included in the
measurement.

For example:

The test [gpu-bound-shader.html](https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/perf_tests/canvas/gpu-bound-shader.html) is just measuring
CPU, and thus looks extremely fast as the test is just one slow shader.

The url `gpu-bound-shader.html?raf` will measure rasterization and GPU time as
well, thus giving a more realistic measurement of performance.

## Running Tests

Expand Down
4 changes: 0 additions & 4 deletions third_party/blink/perf_tests/canvas/OWNERS

This file was deleted.

79 changes: 0 additions & 79 deletions third_party/blink/perf_tests/canvas/gpu-bound-shader.html

This file was deleted.

243 changes: 85 additions & 158 deletions third_party/blink/perf_tests/canvas/resources/canvas_runner.js
Original file line number Diff line number Diff line change
@@ -1,171 +1,98 @@
/*
Runs canvas performance tests to calculate runs/sec for test.doRun().
This module works in two different ways, depending on requestAnimationFrame
(RAF). The query string `RAF` in the url determines which test is run.
*/
// CanvasRunner is a wrapper of PerformanceTests/resources/runner.js for canvas tests.
(function () {
var MEASURE_DRAW_TIMES = 50;
var MAX_MEASURE_DRAW_TIMES = 1000;
var MAX_MEASURE_TIME_PER_FRAME = 1000; // 1 sec
var IS_RAF_TEST = (
document.location.search.substr(1,).toUpperCase() === "RAF");
var currentTest = null;
var isTestDone = false;

var CanvasRunner = {};

CanvasRunner.start = function (test) {
PerfTestRunner.startMeasureValuesAsync({
unit: 'runs/s',
description: test.description,
done: testDone,
run: function() {
if (!test.doRun) {
CanvasRunner.logFatalError("doRun must be set.");
return;
}
currentTest = test;
if (IS_RAF_TEST === true) {
runTestRAF();
} else {
runTest();
}
}});
}

// Times the CPU on the main thread
function runTest() {
try {
if (currentTest.preRun)
currentTest.preRun();
var MEASURE_DRAW_TIMES = 50;
var MAX_MEASURE_DRAW_TIMES = 1000;
var MAX_MEASURE_TIME_PER_FRAME = 1000; // 1 sec
var currentTest = null;
var isTestDone = false;

var CanvasRunner = {};

CanvasRunner.start = function (test) {
PerfTestRunner.startMeasureValuesAsync({
unit: 'runs/s',
description: test.description,
done: testDone,
run: function() {
if (!test.doRun) {
CanvasRunner.logFatalError("doRun must be set.");
return;
}
currentTest = test;
runTest();
}});
}

var start = PerfTestRunner.now();
var count = 0;
while ((PerfTestRunner.now() - start <= MAX_MEASURE_TIME_PER_FRAME) &&
(count * MEASURE_DRAW_TIMES < MAX_MEASURE_DRAW_TIMES)) {
for (var i = 0; i < MEASURE_DRAW_TIMES; i++) {
currentTest.doRun();
function runTest() {
try {
if (currentTest.preRun)
currentTest.preRun();

var start = PerfTestRunner.now();
var count = 0;
while ((PerfTestRunner.now() - start <= MAX_MEASURE_TIME_PER_FRAME) && (count * MEASURE_DRAW_TIMES < MAX_MEASURE_DRAW_TIMES)) {
for (var i = 0; i < MEASURE_DRAW_TIMES; i++) {
currentTest.doRun();
}
count++;
}
if (currentTest.ensureComplete)
currentTest.ensureComplete();
var elapsedTime = PerfTestRunner.now() - start;
if (currentTest.postRun)
currentTest.postRun();

PerfTestRunner.measureValueAsync(MEASURE_DRAW_TIMES * count * 1000 / elapsedTime);
} catch(err) {
CanvasRunner.logFatalError("test fails due to GPU issue. " + err);
return;
}
count++;
}
if (currentTest.ensureComplete)
currentTest.ensureComplete();
var elapsedTime = PerfTestRunner.now() - start;
if (currentTest.postRun)
currentTest.postRun();

let runsPerSecond = MEASURE_DRAW_TIMES * count * 1000 / elapsedTime;
PerfTestRunner.measureValueAsync(runsPerSecond);
} catch(err) {
CanvasRunner.logFatalError("test fails due to GPU issue. " + err);
throw err;
if (!isTestDone)
requestAnimationFrame(runTest);
}

if (!isTestDone)
requestAnimationFrame(runTest);
}

// Times CPU + raster + GPU for draw calls, invoked with the ?RAF query string
// All times in milliseconds
function runTestRAF() {
// How long in ms we want each trial to take
// Must be much greater than 16 (16ms is the v-sync rate)
const GOAL_TIME = 200;

function runTrial(numRuns) {
if (currentTest.preRun) currentTest.preRun();
let startTime = PerfTestRunner.now();
for (var i = 0; i < numRuns; i++) {
currentTest.doRun();
}
requestAnimationFrame(() => {
let elapsedTime = PerfTestRunner.now() - startTime;
let runsPerSecond = numRuns * 1000 / elapsedTime;
PerfTestRunner.measureValueAsync(runsPerSecond);
if (!isTestDone) runTrial(numRuns, startTime);
});
if (currentTest.ensureComplete) currentTest.ensureComplete();
if (currentTest.postRun) currentTest.postRun();
function testDone() {
isTestDone = true;
}

// Figure out how many times currentTest.doRun() + RAF will be required
// to last GOAL_TIME
function calculateNumberOfRuns(resolve, numRuns) {
numRuns = numRuns || 1;
if (currentTest.preRun) currentTest.preRun();
const startTime = PerfTestRunner.now();

for (var i = 0; i < numRuns; i++) {
currentTest.doRun();
}

requestAnimationFrame(() => {
let elapsedTime = PerfTestRunner.now() - startTime;
if (elapsedTime >= GOAL_TIME) {
const timePerRun = elapsedTime / numRuns;
const numRunsFinal = Math.round(GOAL_TIME / timePerRun);
if (currentTest.ensureComplete) currentTest.ensureComplete();
if (currentTest.postRun) currentTest.postRun();
resolve(numRunsFinal);
} else {
calculateNumberOfRuns(resolve, numRuns * 2);
}
});
CanvasRunner.logFatalError = function (text) {
PerfTestRunner.logFatalError(text);
}

try {
new Promise(function(resolve, reject) {
calculateNumberOfRuns(resolve);
}).then(function(numberOfRuns) {
runTrial(numberOfRuns);
});
} catch(err) {
CanvasRunner.logFatalError("test fails due to GPU issue. " + err);
throw err;
CanvasRunner.startPlayingAndWaitForVideo = function (video, callback) {
var gotPlaying = false;
var gotTimeUpdate = false;

var maybeCallCallback = function() {
if (gotPlaying && gotTimeUpdate && callback) {
callback(video);
callback = undefined;
video.removeEventListener('playing', playingListener, true);
video.removeEventListener('timeupdate', timeupdateListener, true);
}
};

var playingListener = function() {
gotPlaying = true;
maybeCallCallback();
};

var timeupdateListener = function() {
// Checking to make sure the current time has advanced beyond
// the start time seems to be a reliable heuristic that the
// video element has data that can be consumed.
if (video.currentTime > 0.0) {
gotTimeUpdate = true;
maybeCallCallback();
}
};

video.addEventListener('playing', playingListener, true);
video.addEventListener('timeupdate', timeupdateListener, true);
video.loop = true;
video.play();
}
}

function testDone() {
isTestDone = true;
}

CanvasRunner.logFatalError = function (text) {
PerfTestRunner.logFatalError(text);
}

CanvasRunner.startPlayingAndWaitForVideo = function (video, callback) {
var gotPlaying = false;
var gotTimeUpdate = false;

var maybeCallCallback = function() {
if (gotPlaying && gotTimeUpdate && callback) {
callback(video);
callback = undefined;
video.removeEventListener('playing', playingListener, true);
video.removeEventListener('timeupdate', timeupdateListener, true);
}
};

var playingListener = function() {
gotPlaying = true;
maybeCallCallback();
};

var timeupdateListener = function() {
// Checking to make sure the current time has advanced beyond
// the start time seems to be a reliable heuristic that the
// video element has data that can be consumed.
if (video.currentTime > 0.0) {
gotTimeUpdate = true;
maybeCallCallback();
}
};

video.addEventListener('playing', playingListener, true);
video.addEventListener('timeupdate', timeupdateListener, true);
video.loop = true;
video.play();
}

window.CanvasRunner = CanvasRunner;
window.CanvasRunner = CanvasRunner;
})();
Loading

0 comments on commit 9743711

Please sign in to comment.