1*c8dee2aaSAndroid Build Coastguard Worker<!-- This benchmark aims to accurately measure the time it takes for CanvasKit to render 2*c8dee2aaSAndroid Build Coastguard Worker an SKP from our test corpus. It is very careful to measure the time between frames. This form 3*c8dee2aaSAndroid Build Coastguard Worker of measurement makes sure we are capturing the GPU draw time. CanvasKit.flush() returns after 4*c8dee2aaSAndroid Build Coastguard Worker it has sent all the instructions to the GPU, but we don't know the GPU is done until the next 5*c8dee2aaSAndroid Build Coastguard Worker frame is requested. Thus, we need to keep track of the time between frames in order to 6*c8dee2aaSAndroid Build Coastguard Worker accurately calculate draw time. Keeping track of the drawPicture and drawPicture+flush is still 7*c8dee2aaSAndroid Build Coastguard Worker useful for telling us how much time we are spending in WASM land and if our drawing is CPU 8*c8dee2aaSAndroid Build Coastguard Worker bound or GPU bound. If total_frame_ms is close to with_flush_ms, we are CPU bound; if 9*c8dee2aaSAndroid Build Coastguard Worker total_frame_ms >> with_flush_ms, we are GPU bound. 10*c8dee2aaSAndroid Build Coastguard Worker--> 11*c8dee2aaSAndroid Build Coastguard Worker<!DOCTYPE html> 12*c8dee2aaSAndroid Build Coastguard Worker<html> 13*c8dee2aaSAndroid Build Coastguard Worker<head> 14*c8dee2aaSAndroid Build Coastguard Worker <title>CanvasKit SKP Perf</title> 15*c8dee2aaSAndroid Build Coastguard Worker <meta charset="utf-8" /> 16*c8dee2aaSAndroid Build Coastguard Worker <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 17*c8dee2aaSAndroid Build Coastguard Worker <meta name="viewport" content="width=device-width, initial-scale=1.0"> 18*c8dee2aaSAndroid Build Coastguard Worker <script src="/static/canvaskit.js" type="text/javascript" charset="utf-8"></script> 19*c8dee2aaSAndroid Build Coastguard Worker <script src="/static/benchmark.js" type="text/javascript" charset="utf-8"></script> 20*c8dee2aaSAndroid Build Coastguard Worker <style type="text/css" media="screen"> 21*c8dee2aaSAndroid Build Coastguard Worker body { 22*c8dee2aaSAndroid Build Coastguard Worker margin: 0; 23*c8dee2aaSAndroid Build Coastguard Worker padding: 0; 24*c8dee2aaSAndroid Build Coastguard Worker } 25*c8dee2aaSAndroid Build Coastguard Worker </style> 26*c8dee2aaSAndroid Build Coastguard Worker</head> 27*c8dee2aaSAndroid Build Coastguard Worker<body> 28*c8dee2aaSAndroid Build Coastguard Worker <main> 29*c8dee2aaSAndroid Build Coastguard Worker <button id="start_bench">Start Benchmark</button> 30*c8dee2aaSAndroid Build Coastguard Worker <br> 31*c8dee2aaSAndroid Build Coastguard Worker <canvas id=anim width=1000 height=1000 style="height: 1000px; width: 1000px;"></canvas> 32*c8dee2aaSAndroid Build Coastguard Worker </main> 33*c8dee2aaSAndroid Build Coastguard Worker <script type="text/javascript" charset="utf-8"> 34*c8dee2aaSAndroid Build Coastguard Worker const WIDTH = 1000; 35*c8dee2aaSAndroid Build Coastguard Worker const HEIGHT = 1000; 36*c8dee2aaSAndroid Build Coastguard Worker const WARM_UP_FRAMES = 10; 37*c8dee2aaSAndroid Build Coastguard Worker const MAX_FRAMES = 201; // This should be sufficient to have low noise. 38*c8dee2aaSAndroid Build Coastguard Worker const SKP_PATH = '/static/test.skp'; 39*c8dee2aaSAndroid Build Coastguard Worker 40*c8dee2aaSAndroid Build Coastguard Worker (function() { 41*c8dee2aaSAndroid Build Coastguard Worker 42*c8dee2aaSAndroid Build Coastguard Worker const loadKit = CanvasKitInit({ 43*c8dee2aaSAndroid Build Coastguard Worker locateFile: (file) => '/static/' + file, 44*c8dee2aaSAndroid Build Coastguard Worker }); 45*c8dee2aaSAndroid Build Coastguard Worker 46*c8dee2aaSAndroid Build Coastguard Worker const loadSKP = fetch(SKP_PATH).then((resp) => { 47*c8dee2aaSAndroid Build Coastguard Worker return resp.arrayBuffer(); 48*c8dee2aaSAndroid Build Coastguard Worker }); 49*c8dee2aaSAndroid Build Coastguard Worker 50*c8dee2aaSAndroid Build Coastguard Worker Promise.all([loadKit, loadSKP]).then((values) => { 51*c8dee2aaSAndroid Build Coastguard Worker const [CanvasKit, skpBytes] = values; 52*c8dee2aaSAndroid Build Coastguard Worker const loadStart = performance.now(); 53*c8dee2aaSAndroid Build Coastguard Worker const skp = CanvasKit.MakePicture(skpBytes); 54*c8dee2aaSAndroid Build Coastguard Worker const loadTime = performance.now() - loadStart; 55*c8dee2aaSAndroid Build Coastguard Worker window._perfData = { 56*c8dee2aaSAndroid Build Coastguard Worker skp_load_ms: loadTime, 57*c8dee2aaSAndroid Build Coastguard Worker }; 58*c8dee2aaSAndroid Build Coastguard Worker console.log('loaded skp', skp, loadTime); 59*c8dee2aaSAndroid Build Coastguard Worker if (!skp) { 60*c8dee2aaSAndroid Build Coastguard Worker window._error = 'could not read skp'; 61*c8dee2aaSAndroid Build Coastguard Worker return; 62*c8dee2aaSAndroid Build Coastguard Worker } 63*c8dee2aaSAndroid Build Coastguard Worker 64*c8dee2aaSAndroid Build Coastguard Worker const urlSearchParams = new URLSearchParams(window.location.search); 65*c8dee2aaSAndroid Build Coastguard Worker let glversion = 2; 66*c8dee2aaSAndroid Build Coastguard Worker if (urlSearchParams.has('webgl1')) { 67*c8dee2aaSAndroid Build Coastguard Worker glversion = 1; 68*c8dee2aaSAndroid Build Coastguard Worker } 69*c8dee2aaSAndroid Build Coastguard Worker 70*c8dee2aaSAndroid Build Coastguard Worker const surface = getSurface(CanvasKit, glversion); 71*c8dee2aaSAndroid Build Coastguard Worker if (!surface) { 72*c8dee2aaSAndroid Build Coastguard Worker console.error('Could not make surface', window._error); 73*c8dee2aaSAndroid Build Coastguard Worker return; 74*c8dee2aaSAndroid Build Coastguard Worker } 75*c8dee2aaSAndroid Build Coastguard Worker const canvas = surface.getCanvas(); 76*c8dee2aaSAndroid Build Coastguard Worker 77*c8dee2aaSAndroid Build Coastguard Worker document.getElementById('start_bench').addEventListener('click', async () => { 78*c8dee2aaSAndroid Build Coastguard Worker const clearColor = CanvasKit.WHITE; 79*c8dee2aaSAndroid Build Coastguard Worker 80*c8dee2aaSAndroid Build Coastguard Worker function draw() { 81*c8dee2aaSAndroid Build Coastguard Worker canvas.clear(clearColor); 82*c8dee2aaSAndroid Build Coastguard Worker canvas.drawPicture(skp); 83*c8dee2aaSAndroid Build Coastguard Worker } 84*c8dee2aaSAndroid Build Coastguard Worker 85*c8dee2aaSAndroid Build Coastguard Worker const results = await startTimingFrames(draw, surface, WARM_UP_FRAMES, MAX_FRAMES); 86*c8dee2aaSAndroid Build Coastguard Worker Object.assign(window._perfData, results); 87*c8dee2aaSAndroid Build Coastguard Worker window._perfDone = true; 88*c8dee2aaSAndroid Build Coastguard Worker }); 89*c8dee2aaSAndroid Build Coastguard Worker console.log('Perf is ready'); 90*c8dee2aaSAndroid Build Coastguard Worker window._perfReady = true; 91*c8dee2aaSAndroid Build Coastguard Worker }); 92*c8dee2aaSAndroid Build Coastguard Worker } 93*c8dee2aaSAndroid Build Coastguard Worker )(); 94*c8dee2aaSAndroid Build Coastguard Worker 95*c8dee2aaSAndroid Build Coastguard Worker </script> 96*c8dee2aaSAndroid Build Coastguard Worker</body> 97*c8dee2aaSAndroid Build Coastguard Worker</html> 98