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