<!-- This benchmark run a lot of small benchmarks that are defined with a karma-like sytax in canvas_perf.js --> <!DOCTYPE html> <html> <head> <title>CanvasKit SKP Perf</title> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="/static/canvaskit.js" type="text/javascript" charset="utf-8"></script> <script src="/static/benchmark.js" type="text/javascript" charset="utf-8"></script> <script src="/static/canvas_perf.js" type="text/javascript" charset="utf-8"></script> <style type="text/css" media="screen"> body { margin: 0; padding: 0; } </style> </head> <body> <main> <button id="start_bench">Start Benchmark</button> <br> <canvas id=anim width=600 height=600 style="height: 600px; width: 600px;"></canvas> </main> <script type="text/javascript" charset="utf-8"> const WIDTH = 600; const HEIGHT = 600; const WARM_UP_FRAMES = 5; // Keeping this a little lower because this test runs many smaller tests, // each for this many frames, which could add up to a long time. const MAX_FRAMES = 51; // Any external files needed by tests in canvas_perf.js must be listed here. // And checked in under canvas_perf_assets/ // tests may then fetch them from ctx.files['filename'] const testDataFiles = [ 'test_64x64.png', 'test_512x512.png', 'test_1500x959.jpg', 'Roboto-Regular.ttf', ]; (function() { const filePromises = []; for (const filename of testDataFiles) { filePromises.push(fetch('/static/assets/'+filename).then((resp) => { return resp.arrayBuffer(); // this is also a promise. })); } const externals = Promise.all(filePromises).then((results) => { const files = {}; let i=0; for (const bytes of results) { // store them by name files[testDataFiles[i]] = bytes; i++; } return files; }); const loadCanvasKit = CanvasKitInit({ locateFile: (file) => '/static/' + file, }); Promise.all([loadCanvasKit, externals]).then(([CanvasKit, externalFiles]) => { const urlSearchParams = new URLSearchParams(window.location.search); let glversion = 2; if (urlSearchParams.has('webgl1')) { glversion = 1; } let surface = getSurface(CanvasKit, glversion); if (!surface) { console.error('Could not make surface', window._error); return; } document.getElementById('start_bench').addEventListener('click', async () => { window._perfData = {}; // canvas_perf.js should have defined an array called tests whose objects have: // setup: A function called once before testing begins, it is expected to make its // own canvas and put it in ctx. // test: A function called to draw one frame // teardown: A function called after testing finishes // description: A human readable description // perfkey: A key used to save the results in perf.skia.org. // // For quick local bench testing, there is also an array called onlytests. This way // a developer can replace tests.push with onlytests.push to just run one or two // performance benchmarks they care about. let testsToRun = tests; if (onlytests.length) { testsToRun = onlytests; } for (const t of testsToRun) { let ctx = { 'surface': surface, 'files': externalFiles, }; console.log('Benchmarking "' + t.description + '"'); t.setup(CanvasKit, ctx); function draw() { t.test(CanvasKit, ctx); } // TODO(nifong): is it ok to keep re-using the surface? results = await startTimingFrames(draw, surface, WARM_UP_FRAMES, MAX_FRAMES); t.teardown(CanvasKit, ctx); window._perfData[t.perfKey] = results; // Delete and re-create surface between tests, to prevent the possibility of // interference between them through the state of surface, the gl context, or things // that are keyed by the surface's gen id. surface.delete(); surface = getSurface(CanvasKit, glversion); // TODO(nifong): provide a function similar to startTimingFrames for timing // non-visual tests. } surface.delete(); window._perfDone = true; }); console.log('Perf is ready'); window._perfReady = true; }); } )(); </script> </body> </html>