skia2/tools/skottie-wasm-perf/skottie-wasm-perf.js
Kevin Lubick f8823b5726 Reland "[canvaskit] Change SkRects to be arrays, not objects."
This is a reland of bdc214a50e

The CPU version of SkottieWasm is timing out for reasons unknown,
but the GPU version is happy. I think we can get rid of the CPU
version of the job since it has been more or less superseded by
the SkottieFrames one (and the latter is more stable).

Original change's description:
> [canvaskit] Change SkRects to be arrays, not objects.
>
> This changes several APIs, so there are lots of breaking
> notes in the Changelog.
>
> This made the "draw 100 colored regions" benchmark about
> 20% faster (1ms -> .8ms).
>
> In theory, rendering should stay the same.
>
> Change-Id: Ib80b15e2d980ad5d568fff4460d2b529766c1b36
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/312491
> Reviewed-by: Nathaniel Nifong <nifong@google.com>

Change-Id: I674aba85ecfb30b72e94cbaf89b2d97bfae3b7a4
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/315142
Reviewed-by: Nathaniel Nifong <nifong@google.com>
2020-09-03 14:31:38 +00:00

190 lines
4.9 KiB
JavaScript

/**
* Command line application to run Skottie-WASM perf on a Lottie file in the
* browser and then exporting the result.
*
*/
const puppeteer = require('puppeteer');
const express = require('express');
const fs = require('fs');
const commandLineArgs = require('command-line-args');
const commandLineUsage= require('command-line-usage');
const fetch = require('node-fetch');
const opts = [
{
name: 'canvaskit_js',
typeLabel: '{underline file}',
description: 'The path to canvaskit.js.'
},
{
name: 'canvaskit_wasm',
typeLabel: '{underline file}',
description: 'The path to canvaskit.wasm.'
},
{
name: 'input',
typeLabel: '{underline file}',
description: 'The Lottie JSON file to process.'
},
{
name: 'output',
typeLabel: '{underline file}',
description: 'The perf file to write. Defaults to perf.json',
},
{
name: 'use_gpu',
description: 'Whether we should run in non-headless mode with GPU.',
type: Boolean,
},
{
name: 'port',
description: 'The port number to use, defaults to 8081.',
type: Number,
},
{
name: 'help',
alias: 'h',
type: Boolean,
description: 'Print this usage guide.'
},
];
const usage = [
{
header: 'Skottie WASM Perf',
content: "Command line application to run Skottie-WASM perf."
},
{
header: 'Options',
optionList: opts,
},
];
// Parse and validate flags.
const options = commandLineArgs(opts);
if (!options.output) {
options.output = 'perf.json';
}
if (!options.port) {
options.port = 8081;
}
if (options.help) {
console.log(commandLineUsage(usage));
process.exit(0);
}
if (!options.canvaskit_js) {
console.error('You must supply path to canvaskit.js.');
console.log(commandLineUsage(usage));
process.exit(1);
}
if (!options.canvaskit_wasm) {
console.error('You must supply path to canvaskit.wasm.');
console.log(commandLineUsage(usage));
process.exit(1);
}
if (!options.input) {
console.error('You must supply a Lottie JSON filename.');
console.log(commandLineUsage(usage));
process.exit(1);
}
// Start up a web server to serve the three files we need.
let canvasKitJS = fs.readFileSync(options.canvaskit_js, 'utf8');
let canvasKitWASM = fs.readFileSync(options.canvaskit_wasm, 'binary');
let driverHTML = fs.readFileSync('skottie-wasm-perf.html', 'utf8');
let lottieJSON = fs.readFileSync(options.input, 'utf8');
const app = express();
app.get('/', (req, res) => res.send(driverHTML));
app.get('/res/canvaskit.wasm', function(req, res) {
res.type('application/wasm');
res.send(new Buffer(canvasKitWASM, 'binary'));
});
app.get('/res/canvaskit.js', (req, res) => res.send(canvasKitJS));
app.get('/res/lottie.json', (req, res) => res.send(lottieJSON));
app.listen(options.port, () => console.log('- Local web server started.'))
// Utility function.
async function wait(ms) {
await new Promise(resolve => setTimeout(() => resolve(), ms));
return ms;
}
let hash = "#cpu";
if (options.use_gpu) {
hash = "#gpu";
}
const targetURL = `http://localhost:${options.port}/${hash}`;
const viewPort = {width: 1000, height: 1000};
// Drive chrome to load the web page from the server we have running.
async function driveBrowser() {
console.log('- Launching chrome for ' + options.input);
let browser;
let page;
const headless = !options.use_gpu;
let browser_args = [
'--no-sandbox',
'--disable-setuid-sandbox',
'--window-size=' + viewPort.width + ',' + viewPort.height,
];
if (options.use_gpu) {
browser_args.push('--ignore-gpu-blacklist');
browser_args.push('--ignore-gpu-blocklist');
browser_args.push('--enable-gpu-rasterization');
}
console.log("Running with headless: " + headless + " args: " + browser_args);
try {
browser = await puppeteer.launch({headless: headless, args: browser_args});
page = await browser.newPage();
await page.setViewport(viewPort);
} catch (e) {
console.log('Could not open the browser.', e);
process.exit(1);
}
console.log("Loading " + targetURL);
try {
// Start trace.
await page.tracing.start({
path: options.output,
screenshots: false,
categories: ["blink", "cc", "gpu"]
});
await page.goto(targetURL, {
timeout: 60000,
waitUntil: 'networkidle0'
});
console.log('Waiting 90s for run to be done');
await page.waitForFunction(`(window._skottieDone === true) || window._error`, {
timeout: 90000,
});
const err = await page.evaluate('window._error');
if (err) {
console.log(`ERROR: ${err}`)
process.exit(1);
}
// Stop Trace.
await page.tracing.stop();
} catch(e) {
console.log('Timed out while loading or drawing. Either the JSON file was ' +
'too big or hit a bug.', e);
await browser.close();
process.exit(1);
}
await browser.close();
// Need to call exit() because the web server is still running.
process.exit(0);
}
driveBrowser();