<!-- This benchmark aims to accurately measure the time it takes for Skottie to load the JSON and
turn it into an animation, as well as the times for the first hundred frames (and, as a subcomponent
of that, the seek times of the first hundred frames). This is set to mimic how a real-world user
would display the animation (e.g. using clock time to determine where to seek, not frame numbers).
-->
<!DOCTYPE html>
<html>
<head>
  <title>Skottie-WASM 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>
  <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=1000 height=1000 style="height: 1000px; width: 1000px;"></canvas>
  </main>
  <script type="text/javascript" charset="utf-8">
    const WIDTH  = 1000;
    const HEIGHT = 1000;
    const WARM_UP_FRAMES = 0; // No warmup, so that the jank of initial frames gets measured.
    // We sample MAX_FRAMES or until MAX_SAMPLE_SECONDS has elapsed.
    const MAX_FRAMES = 600; // ~10s at 60fps
    const MAX_SAMPLE_MS = 50 * 1000; // in case something takes a while, stop after 50 seconds.
    const LOTTIE_JSON_PATH = '/static/lottie.json';
    const ASSETS_PATH = '/static/assets/';
    (function() {

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

      const loadLottie = fetch(LOTTIE_JSON_PATH).then((resp) => {
        return resp.text();
      });

      const loadFontsAndAssets = loadLottie.then((jsonStr) => {
        const lottie = JSON.parse(jsonStr);
        const promises = [];
        promises.push(...loadFonts(lottie.fonts));
        promises.push(...loadAssets(lottie.assets));
        return Promise.all(promises);
      });

      Promise.all([loadKit, loadLottie, loadFontsAndAssets]).then((values) => {
        const [CanvasKit, json, externalAssets] = values;
        console.log(externalAssets);
        const assets = {};
        for (const asset of externalAssets) {
          if (asset) {
            assets[asset.name] = asset.bytes;
          }
        }
        const loadStart = performance.now();
        const animation = CanvasKit.MakeManagedAnimation(json, assets);
        const loadTime = performance.now() - loadStart;

        window._perfData = {
          json_load_ms: loadTime,
        };

        const duration = animation.duration() * 1000;
        const bounds = CanvasKit.LTRBRect(0, 0, WIDTH, HEIGHT);

        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;
        }
        const canvas = surface.getCanvas();

        document.getElementById('start_bench').addEventListener('click', async () => {
          const startTime = Date.now();
          const damageRect = Float32Array.of(0, 0, 0, 0);

          function draw() {
            const seek = ((Date.now() - startTime) / duration) % 1.0;
            const damage = animation.seek(seek, damageRect);

            if (damage[2] > damage[0] && damage[3] > damage[1]) {
              animation.render(canvas, bounds);
            }
          }

          startTimingFrames(draw, surface, WARM_UP_FRAMES, MAX_FRAMES, MAX_SAMPLE_MS).then((results) => {
            Object.assign(window._perfData, results);
            window._perfDone = true;
          }).catch((error) => {
            window._error = error;
          });

        });
        console.log('Perf is ready');
        window._perfReady = true;
      });
    })();

  function loadFonts(fonts) {
    const promises = [];
    if (!fonts || !fonts.list) {
      return promises;
    }
    for (const font of fonts.list) {
      if (font.fName) {
        promises.push(fetch(`${ASSETS_PATH}/${font.fName}.ttf`).then((resp) => {
            // fetch does not reject on 404
            if (!resp.ok) {
              console.error(`Could not load ${font.fName}.ttf: status ${resp.status}`);
              return null;
            }
            return resp.arrayBuffer().then((buffer) => {
              return {
                'name': font.fName,
                'bytes': buffer
              };
            });
          })
        );
      }
    }
    return promises;
  }

  function loadAssets(assets) {
    const promises = [];
    if (!assets) {
      return [];
    }
    for (const asset of assets) {
      // asset.p is the filename, if it's an image.
      // Don't try to load inline/dataURI images.
      const should_load = asset.p && asset.p.startsWith && !asset.p.startsWith('data:');
      if (should_load) {
        promises.push(fetch(`${ASSETS_PATH}/${asset.p}`)
          .then((resp) => {
            // fetch does not reject on 404
            if (!resp.ok) {
              console.error(`Could not load ${asset.p}: status ${resp.status}`);
              return null;
            }
            return resp.arrayBuffer().then((buffer) => {
              return {
                'name': asset.p,
                'bytes': buffer
              };
            });
          })
        );
      }
    }
    return promises;
  }
  </script>
</body>
</html>
