blob: 21fa05248307ddf26b26051efac26196e743eeec [file] [log] [blame]
<!DOCTYPE html>
<title>GMs and unit tests against WASM/WebGL</title>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
html, body {
margin: 0;
padding: 0;
}
#debug_canvas {
/* Same checkboard pattern as is on debugger.skia.org, just a little darker. */
background-position: 0 0, 10px 10px;
background-size: 20px 20px;
background-image: linear-gradient(45deg, #CCC 25%, transparent 25%, transparent 75%, #CCC 75%, #CCC 100%),
linear-gradient(45deg, #CCC 25%, white 25%, white 75%, #CCC 75%, #CCC 100%);
}
</style>
<canvas id=debug_canvas height=1000 width=1000></canvas>
<canvas id=gm_canvas></canvas>
<script type="text/javascript" src="/out/wasm_gm_tests.js"></script>
<script type="text/javascript" charset="utf-8">
const loadTests = InitWasmGMTests({
locateFile: (file) => '/out/'+file,
});
Promise.all([loadTests]).then(([GM]) => {
RunGMs(GM);
});
function RunGMs(GM) {
const canvas = document.getElementById('gm_canvas');
const ctx = GM.GetWebGLContext(canvas, 2);
const grcontext = GM.MakeGrContext(ctx);
requestAnimationFrame(drawQueuedPNGs);
const names = GM.ListGMs();
names.sort();
for (const name of names) {
const pngAndHash = GM.RunGM(grcontext, name);
if (!pngAndHash) {
continue;
}
drawDebugPNG(pngAndHash.png);
// We need to know the digest of the image as well as which gm produced it.
// As such, we include both parts in the name.
outputPNG(pngAndHash.png, pngAndHash.hash + '_' + name + '.png');
}
grcontext.delete();
}
const msPerGM = 500;
let timeSinceLastPNGSwapped = 0;
const queuedDebugPNGs = [];
// This decodes the given PNG and queues it up to be drawn. Because decoding the image
// (createImageBitmap) is asynchronous, we queue this in a list and have a drawing loop that
// occasionally pulls the next image off the queue to be displayed to the human. That way we
// have a minimum amount of time an image is seen so the human can casually inspect the outputs
// as they are generated.
function drawDebugPNG(pngBytes) {
const blob = new Blob([pngBytes], {type: 'image/png'});
createImageBitmap(blob).then((bitmap) => {
queuedDebugPNGs.push(bitmap);
});
}
function drawQueuedPNGs() {
requestAnimationFrame(drawQueuedPNGs);
if (!queuedDebugPNGs.length) {
return; // no new image to show
}
if ((Date.now() - timeSinceLastPNGSwapped) < msPerGM) {
return; // not been displayed long enough.
}
// Draw the first image in the queue.
const bitmap = queuedDebugPNGs.shift();
const debugCanvas = document.getElementById('debug_canvas');
debugCanvas.width = bitmap.width;
debugCanvas.height = bitmap.height;
const ctx = debugCanvas.getContext('2d');
ctx.clearRect(0, 0, 1000, 1000);
ctx.drawImage(bitmap, 0, 0);
timeSinceLastPNGSwapped = Date.now();
}
// This triggers a download of the created PNG using the provided filename. For a production
// testing environment, it will probably be good to swap this out with a webserver because it
// might not be easy to determine where the download folder for a given browser is.
function outputPNG(pngBytes, fileName) {
// https://stackoverflow.com/a/32094834
const blob = new Blob([pngBytes], {type: 'image/png'});
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
document.body.appendChild(a);
a.href = url;
a.download = fileName;
a.click();
// clean up after because FF might not download it synchronously
setTimeout(function() {
URL.revokeObjectURL(url);
a.remove();
}, 50);
}
</script>