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