1cb93a386Sopenharmony_ci<!-- This benchmark run a lot of small benchmarks that are defined with a karma-like sytax 2cb93a386Sopenharmony_ci in canvas_perf.js 3cb93a386Sopenharmony_ci--> 4cb93a386Sopenharmony_ci<!DOCTYPE html> 5cb93a386Sopenharmony_ci<html> 6cb93a386Sopenharmony_ci<head> 7cb93a386Sopenharmony_ci <title>CanvasKit SKP Perf</title> 8cb93a386Sopenharmony_ci <meta charset="utf-8" /> 9cb93a386Sopenharmony_ci <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 10cb93a386Sopenharmony_ci <meta name="viewport" content="width=device-width, initial-scale=1.0"> 11cb93a386Sopenharmony_ci <script src="/static/canvaskit.js" type="text/javascript" charset="utf-8"></script> 12cb93a386Sopenharmony_ci <script src="/static/benchmark.js" type="text/javascript" charset="utf-8"></script> 13cb93a386Sopenharmony_ci <script src="/static/canvas_perf.js" type="text/javascript" charset="utf-8"></script> 14cb93a386Sopenharmony_ci <style type="text/css" media="screen"> 15cb93a386Sopenharmony_ci body { 16cb93a386Sopenharmony_ci margin: 0; 17cb93a386Sopenharmony_ci padding: 0; 18cb93a386Sopenharmony_ci } 19cb93a386Sopenharmony_ci </style> 20cb93a386Sopenharmony_ci</head> 21cb93a386Sopenharmony_ci<body> 22cb93a386Sopenharmony_ci <main> 23cb93a386Sopenharmony_ci <button id="start_bench">Start Benchmark</button> 24cb93a386Sopenharmony_ci <br> 25cb93a386Sopenharmony_ci <canvas id=anim width=600 height=600 style="height: 600px; width: 600px;"></canvas> 26cb93a386Sopenharmony_ci </main> 27cb93a386Sopenharmony_ci <script type="text/javascript" charset="utf-8"> 28cb93a386Sopenharmony_ci const WIDTH = 600; 29cb93a386Sopenharmony_ci const HEIGHT = 600; 30cb93a386Sopenharmony_ci const WARM_UP_FRAMES = 5; 31cb93a386Sopenharmony_ci // Keeping this a little lower because this test runs many smaller tests, 32cb93a386Sopenharmony_ci // each for this many frames, which could add up to a long time. 33cb93a386Sopenharmony_ci const MAX_FRAMES = 51; 34cb93a386Sopenharmony_ci 35cb93a386Sopenharmony_ci // Any external files needed by tests in canvas_perf.js must be listed here. 36cb93a386Sopenharmony_ci // And checked in under canvas_perf_assets/ 37cb93a386Sopenharmony_ci // tests may then fetch them from ctx.files['filename'] 38cb93a386Sopenharmony_ci const testDataFiles = [ 39cb93a386Sopenharmony_ci 'test_64x64.png', 40cb93a386Sopenharmony_ci 'test_512x512.png', 41cb93a386Sopenharmony_ci 'test_1500x959.jpg', 42cb93a386Sopenharmony_ci 'Roboto-Regular.ttf', 43cb93a386Sopenharmony_ci 'Roboto-Regular.woff', 44cb93a386Sopenharmony_ci 'Roboto-Regular.woff2', 45cb93a386Sopenharmony_ci ]; 46cb93a386Sopenharmony_ci 47cb93a386Sopenharmony_ci (function() { 48cb93a386Sopenharmony_ci const filePromises = []; 49cb93a386Sopenharmony_ci for (const filename of testDataFiles) { 50cb93a386Sopenharmony_ci filePromises.push(fetch('/static/assets/'+filename).then((resp) => { 51cb93a386Sopenharmony_ci return resp.arrayBuffer(); // this is also a promise. 52cb93a386Sopenharmony_ci })); 53cb93a386Sopenharmony_ci } 54cb93a386Sopenharmony_ci const externals = Promise.all(filePromises).then((results) => { 55cb93a386Sopenharmony_ci const files = {}; 56cb93a386Sopenharmony_ci let i=0; 57cb93a386Sopenharmony_ci for (const bytes of results) { 58cb93a386Sopenharmony_ci // store them by name 59cb93a386Sopenharmony_ci files[testDataFiles[i]] = bytes; 60cb93a386Sopenharmony_ci i++; 61cb93a386Sopenharmony_ci } 62cb93a386Sopenharmony_ci return files; 63cb93a386Sopenharmony_ci }); 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci const loadCanvasKit = CanvasKitInit({ 66cb93a386Sopenharmony_ci locateFile: (file) => '/static/' + file, 67cb93a386Sopenharmony_ci }); 68cb93a386Sopenharmony_ci 69cb93a386Sopenharmony_ci Promise.all([loadCanvasKit, externals]).then(([CanvasKit, externalFiles]) => { 70cb93a386Sopenharmony_ci const urlSearchParams = new URLSearchParams(window.location.search); 71cb93a386Sopenharmony_ci let glversion = 2; 72cb93a386Sopenharmony_ci if (urlSearchParams.has('webgl1')) { 73cb93a386Sopenharmony_ci glversion = 1; 74cb93a386Sopenharmony_ci } 75cb93a386Sopenharmony_ci let surface = getSurface(CanvasKit, glversion); 76cb93a386Sopenharmony_ci if (!surface) { 77cb93a386Sopenharmony_ci console.error('Could not make surface', window._error); 78cb93a386Sopenharmony_ci return; 79cb93a386Sopenharmony_ci } 80cb93a386Sopenharmony_ci 81cb93a386Sopenharmony_ci document.getElementById('start_bench').addEventListener('click', async () => { 82cb93a386Sopenharmony_ci window._perfData = {}; 83cb93a386Sopenharmony_ci 84cb93a386Sopenharmony_ci // canvas_perf.js should have defined an array called tests whose objects have: 85cb93a386Sopenharmony_ci // setup: A function called once before testing begins, it is expected to make its 86cb93a386Sopenharmony_ci // own canvas and put it in ctx. 87cb93a386Sopenharmony_ci // test: A function called to draw one frame 88cb93a386Sopenharmony_ci // teardown: A function called after testing finishes 89cb93a386Sopenharmony_ci // description: A human readable description 90cb93a386Sopenharmony_ci // perfkey: A key used to save the results in perf.skia.org. 91cb93a386Sopenharmony_ci // 92cb93a386Sopenharmony_ci // For quick local bench testing, there is also an array called onlytests. This way 93cb93a386Sopenharmony_ci // a developer can replace tests.push with onlytests.push to just run one or two 94cb93a386Sopenharmony_ci // performance benchmarks they care about. 95cb93a386Sopenharmony_ci let testsToRun = tests; 96cb93a386Sopenharmony_ci if (onlytests.length) { 97cb93a386Sopenharmony_ci testsToRun = onlytests; 98cb93a386Sopenharmony_ci } 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci for (const t of testsToRun) { 101cb93a386Sopenharmony_ci let ctx = { 102cb93a386Sopenharmony_ci 'surface': surface, 103cb93a386Sopenharmony_ci 'files': externalFiles, 104cb93a386Sopenharmony_ci }; 105cb93a386Sopenharmony_ci console.log('Benchmarking "' + t.description + '"'); 106cb93a386Sopenharmony_ci t.setup(CanvasKit, ctx); 107cb93a386Sopenharmony_ci function draw() { 108cb93a386Sopenharmony_ci t.test(CanvasKit, ctx); 109cb93a386Sopenharmony_ci } 110cb93a386Sopenharmony_ci // TODO(nifong): is it ok to keep re-using the surface? 111cb93a386Sopenharmony_ci results = await startTimingFrames(draw, surface, WARM_UP_FRAMES, MAX_FRAMES); 112cb93a386Sopenharmony_ci t.teardown(CanvasKit, ctx); 113cb93a386Sopenharmony_ci window._perfData[t.perfKey] = results; 114cb93a386Sopenharmony_ci 115cb93a386Sopenharmony_ci // Delete and re-create surface between tests, to prevent the possibility of 116cb93a386Sopenharmony_ci // interference between them through the state of surface, the gl context, or things 117cb93a386Sopenharmony_ci // that are keyed by the surface's gen id. 118cb93a386Sopenharmony_ci surface.delete(); 119cb93a386Sopenharmony_ci surface = getSurface(CanvasKit, glversion); 120cb93a386Sopenharmony_ci 121cb93a386Sopenharmony_ci // TODO(nifong): provide a function similar to startTimingFrames for timing 122cb93a386Sopenharmony_ci // non-visual tests. 123cb93a386Sopenharmony_ci } 124cb93a386Sopenharmony_ci surface.delete(); 125cb93a386Sopenharmony_ci window._perfDone = true; 126cb93a386Sopenharmony_ci }); 127cb93a386Sopenharmony_ci console.log('Perf is ready'); 128cb93a386Sopenharmony_ci window._perfReady = true; 129cb93a386Sopenharmony_ci }); 130cb93a386Sopenharmony_ci } 131cb93a386Sopenharmony_ci )(); 132cb93a386Sopenharmony_ci 133cb93a386Sopenharmony_ci </script> 134cb93a386Sopenharmony_ci</body> 135cb93a386Sopenharmony_ci</html> 136