skia2/experimental/canvaskit/perf/animation.bench.js
Kevin Lubick 65846c04e0 [canvaskit] Add .ready() which is a real promise
Prior to this, CanvasKit was unintentionally a thenable, which means if
it was used to resolve a Promise, certain logic would be called which
would put it into an infinite loop. By adding a .ready() which returns
a proper Promise and removes the .then(), this should make the CanvasKit
libary safer.

For now, the .then() still exists unless .ready() is called. .then will
be removed unconditionally in 0.4.0 which will be out after all known
clients (e.g. jsfiddle.skia.org) are changed.

See: https://github.com/kripken/emscripten/issues/5820

Bug: skia:
Change-Id: Ie4093f6b0ce03070ef737941693b06dfff93f61c
Reviewed-on: https://skia-review.googlesource.com/c/181177
Reviewed-by: Joe Gregorio <jcgregorio@google.com>
2019-01-04 19:48:19 +00:00

168 lines
5.7 KiB
JavaScript

// The increased timeout is especially needed with larger binaries
// like in the debug/gpu build
jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000;
describe('CanvasKit\'s Animation', function() {
// Note, don't try to print the CanvasKit object - it can cause Karma/Jasmine to lock up.
var CanvasKit = null;
const LoadCanvasKit = new Promise(function(resolve, reject) {
if (CanvasKit) {
resolve();
} else {
CanvasKitInit({
locateFile: (file) => '/canvaskit/'+file,
}).ready().then((_CanvasKit) => {
CanvasKit = _CanvasKit;
resolve();
});
}
});
const LOTTIE_ANIMATIONS = ['lego_loader', 'drinks', 'confetti', 'onboarding'];
let container = document.createElement('div');
document.body.appendChild(container);
beforeEach(function() {
container.innerHTML = `
<canvas width=600 height=600 id=test></canvas>`;
});
afterEach(function() {
container.innerHTML = '';
});
function fetchAndText(url) {
return new Promise(function(resolve, reject) {
fetch(url).then((resp) => {
resp.text().then((str) => {
expect(str).toBeTruthy();
resolve(str);
});
}).catch(reject);
});
}
LOTTIE_ANIMATIONS.forEach((animStr) => {
let promises = [fetchAndText(`/assets/${animStr}.json`), LoadCanvasKit];
it(`animation loading for ${animStr}`, function(done) {
let jsonStr = '';
function setup(ctx) {
expect(jsonStr).toBeTruthy();
}
function test(ctx) {
const animation = CanvasKit.MakeAnimation(jsonStr);
animation.delete();
}
function teardown(ctx) {}
Promise.all(promises).then((responses) => {
// The result from the first promise, that is, the JSON string
// fetched by fetchAndText
jsonStr = responses[0];
benchmarkAndReport(`${animStr}_animation_load`, setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
it(`animation frames in order for ${animStr}`, function(done) {
let jsonStr = '';
function setup(ctx) {
expect(jsonStr).toBeTruthy();
ctx.animation = CanvasKit.MakeAnimation(jsonStr);
expect(ctx.animation).toBeTruthy();
ctx.timer = 0;
}
function test(ctx) {
ctx.animation.seek(ctx.timer);
ctx.timer += 0.01;
if (ctx.timer > 1.0) {
ctx.timer = 0;
}
}
function teardown(ctx) {
ctx.animation.delete();
}
Promise.all(promises).then((responses) => {
// The result from the first promise, that is, the JSON string
// fetched by fetchAndText
jsonStr = responses[0];
benchmarkAndReport(`${animStr}_animation_in_order`, setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
it(`animation frames in random order for ${animStr}`, function(done) {
let jsonStr = '';
function setup(ctx) {
expect(jsonStr).toBeTruthy();
ctx.animation = CanvasKit.MakeAnimation(jsonStr);
expect(ctx.animation).toBeTruthy();
}
function test(ctx) {
ctx.animation.seek(Math.random());
}
function teardown(ctx) {
ctx.animation.delete();
}
Promise.all(promises).then((responses) => {
// The result from the first promise, that is, the JSON string
// fetched by fetchAndText
jsonStr = responses[0];
benchmarkAndReport(`${animStr}_animation_random_order`, setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
it(`renders to an HTML canvas ${animStr}`, function(done) {
let jsonStr = '';
function setup(ctx) {
expect(jsonStr).toBeTruthy();
ctx.animation = CanvasKit.MakeAnimation(jsonStr);
expect(ctx.animation).toBeTruthy();
ctx.animation.seek(0.5);
ctx.surface = CanvasKit.MakeCanvasSurface('test');
ctx.canvas = ctx.surface.getCanvas();
ctx.clear = CanvasKit.Color(255, 255, 255, 0.0); // transparent
}
function test(ctx) {
// This emulates what would need to be done do accurately
// draw one frame.
ctx.canvas.clear(ctx.clear);
ctx.animation.render(ctx.canvas);
ctx.surface.flush();
}
function teardown(ctx) {
ctx.animation.delete();
ctx.surface.dispose(); // ctx.canvas will also be cleaned up
}
Promise.all(promises).then((responses) => {
// The result from the first promise, that is, the JSON string
// fetched by fetchAndText
jsonStr = responses[0];
benchmarkAndReport(`${animStr}_animation_render_flush`, setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
});
});