<!-- 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;

    (function() {

      const loadCanvasKit = CanvasKitInit({
        locateFile: (file) => '/static/' + file,
      });

      loadCanvasKit.then((CanvasKit) => {
        const urlSearchParams = new URLSearchParams(window.location.search);
        let glversion = 2;
        if (urlSearchParams.has('webgl1')) {
          glversion = 1;
        }
        const 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 a single object called tests that is an array of
          // objects having:
          //  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 (const t of tests) {
            let ctx = {
              'surface': surface,
            };
            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;

            // 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>
