diff options
Diffstat (limited to 'dom/canvas/test/test_bitmaprenderer.html')
-rw-r--r-- | dom/canvas/test/test_bitmaprenderer.html | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/dom/canvas/test/test_bitmaprenderer.html b/dom/canvas/test/test_bitmaprenderer.html new file mode 100644 index 0000000000..ee42d9d7f5 --- /dev/null +++ b/dom/canvas/test/test_bitmaprenderer.html @@ -0,0 +1,178 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>WebGL in OffscreenCanvas</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="/tests/SimpleTest/WindowSnapshot.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"> +</head> +<body> +<script type="text/js-worker"> +function ok(expect, msg) { + postMessage({"type": "status", status: !!expect, msg: msg}); +} + +onmessage = function(event) { + var bitmap = event.data.bitmap; + ok(!!bitmap, "Get the ImageBitmap from the main script."); + + var offscreenCanvas = new OffscreenCanvas(64, 64); + var ctx = offscreenCanvas.getContext('bitmaprenderer'); + ok(!!ctx, "Get bitmaprenderer context on worker."); + + ctx.transferFromImageBitmap(bitmap); + var resultBitmap = offscreenCanvas.transferToImageBitmap(); + postMessage({"type": "bitmap", bitmap: resultBitmap}, [resultBitmap]); +} +</script> +<script> + +SimpleTest.waitForExplicitFinish(); + +function createCanvas(width, height) { + var htmlCanvas = document.createElement('canvas'); + htmlCanvas.width = width; + htmlCanvas.height = height; + document.body.appendChild(htmlCanvas); + return htmlCanvas; +} + +function runTest(canvasWidth, canvasHeight, nextTest) { + var canvas1 = createCanvas(canvasWidth, canvasHeight); + var ctx = canvas1.getContext("2d"); + ctx.fillStyle = "#00FF00"; + ctx.fillRect(0, 0, canvasWidth, canvasHeight); + + var canvasRef = createCanvas(canvasWidth, canvasHeight); + var ctx = canvasRef.getContext("2d"); + // Clear with black transparent first + ctx.fillStyle = "rgba(0, 0, 0, 0)"; + ctx.fillRect(0, 0, canvasWidth, canvasHeight); + + ctx.fillStyle = "#00FF00"; + ctx.fillRect(0, 0, canvasWidth, canvasHeight); + + createImageBitmap(canvas1).then(async function(bmp) { + document.body.removeChild(canvas1); + + var canvas2 = createCanvas(90, 90); + var ctx2 = canvas2.getContext("bitmaprenderer"); + ctx2.transferFromImageBitmap(bmp); + + ok(canvasRef.toDataURL() == canvas2.toDataURL(), "toDataURL should return same result."); + + // Exam render result + canvasRef.style.display = "none"; + canvas2.style.display = "block"; + var snapshot = await snapshotWindow(window); + + canvasRef.style.display = "block"; + canvas2.style.display = "none"; + var snapshotRef = await snapshotWindow(window); + + // bitmaprenderers use an ImageLayer whereas a normal 2d canvas uses a canvas layer. This + // can result in some anti-aliasing differences on the edge. We consider slight AA differences + // to be reasonable when using different codepaths so fuzz a little bit. + var fuzz = { numDifferentPixels: 0, + maxDifference: 0 }; + if (SpecialPowers.Services.appinfo.widgetToolkit == "android") { + fuzz.maxDifference = 2; + fuzz.numDifferentPixels = 131; + } + var results = compareSnapshots(snapshot, snapshotRef, true, fuzz); + ok(results[0], "Screenshots should be the same"); + + document.body.removeChild(canvasRef); + document.body.removeChild(canvas2); + + nextTest(); + }); +} + +function createSolidGreenBitmap(width, height) { + const canvas = createCanvas(width, height); + const ctx = canvas.getContext("2d"); + ctx.fillStyle = "#00FF00"; + ctx.fillRect(0, 0, width, height); + const bitmap = createImageBitmap(canvas); + document.body.removeChild(canvas); + return bitmap; +} + +async function scaleTestCase(name, refWidth, refHeight, testWidth, testHeight, canvasWidth, canvasHeight) { + const refBitmap = await createSolidGreenBitmap(refWidth, refHeight); + const refCanvas = createCanvas(refWidth, refHeight); + const refCtx = refCanvas.getContext("bitmaprenderer"); + refCtx.transferFromImageBitmap(refBitmap); + is(refCanvas.width, refWidth, name + ": refCanvas width " + refCanvas.width + " is ref " + refWidth); + is(refCanvas.height, refHeight, name + ": refCanvas height " + refCanvas.height + " is ref " + refHeight); + const refSnapshot = await snapshotWindow(window); + document.body.removeChild(refCanvas); + + const bitmap = await createSolidGreenBitmap(testWidth, testHeight); + const canvas = createCanvas(canvasWidth, canvasHeight); + const ctx = canvas.getContext("bitmaprenderer"); + ctx.transferFromImageBitmap(bitmap); + is(canvas.width, testWidth, name + ": canvas width " + canvas.width + " is bitmap " + testWidth); + is(canvas.height, testHeight, name + ": canvas height " + canvas.height + " is bitmap " + testHeight); + if (refWidth !== testWidth) { + canvas.width = refWidth; + is(canvas.width, refWidth, name + ": canvas width " + canvas.width + " is ref " + refWidth); + } + if (refHeight !== testHeight) { + canvas.height = refHeight; + is(canvas.height, refHeight, name + ": canvas height " + canvas.height + " is ref " + refHeight); + } + const snapshot = await snapshotWindow(window); + document.body.removeChild(canvas); + + const results = compareSnapshots(snapshot, refSnapshot, true); + ok(results[0], name + ": screenshots should be the same"); + return Promise.resolve(); +} + +async function scaleTest() { + await scaleTestCase("grow_unscaled", 64, 64, 64, 64, 32, 32); // Canvas grows, no scaling. + await scaleTestCase("grow_downscaled", 64, 64, 128, 128, 32, 32); // Canvas grows, scales down. + await scaleTestCase("grow_upscaled", 64, 64, 32, 32, 16, 16); // Canvas grows, scales up. + await scaleTestCase("same_downscaled", 64, 64, 128, 128, 128, 128); // Canvas unchanged, scales down. + await scaleTestCase("same_upscaled", 64, 64, 32, 32, 32, 32); // Canvas unchanged, scales up. + await scaleTestCase("shrink_unscaled", 64, 64, 64, 64, 128, 128); // Canvas shrinks, no scaling. + await scaleTestCase("shrink_downscaled", 64, 64, 128, 128, 256, 256); // Canvas shrinks, scales down. + await scaleTestCase("shrink_upscaled", 64, 64, 32, 32, 256, 256); // Canvas shrinks, scales up. + runTestOnWorker(); +} + +function runTestOnWorker() { + var canvas1 = createCanvas(64, 64); + var ctx = canvas1.getContext("2d"); + ctx.fillStyle = "#00FF00"; + ctx.fillRect(0, 0, 64, 64); + + var blob = new Blob(Array.prototype.map.call(document.querySelectorAll("script[type=\"text\/js-worker\"]"), function (oScript) { return oScript.textContent; }),{type: "text/javascript"}); + + var worker = new Worker(window.URL.createObjectURL(blob)); + + createImageBitmap(canvas1).then(function(bmp) { + worker.postMessage({bitmap: bmp}, [bmp]); + worker.onmessage = function(event) { + if (event.data.type == "status") { + ok(event.data.status, event.data.msg); + } else if (event.data.type == "bitmap") { + var canvas2 = createCanvas(64, 64); + var ctx2 = canvas2.getContext('bitmaprenderer'); + ctx2.transferFromImageBitmap(event.data.bitmap); + ok(canvas1.toDataURL() == canvas2.toDataURL(), 'toDataURL should be the same'); + SimpleTest.finish(); + } + } + }); +} + +SpecialPowers.pushPrefEnv({'set': [ + ['gfx.offscreencanvas.enabled', true], +]}, runTest.bind(this, 64, 64, runTest.bind(this, 128, 128, scaleTest))); + +</script> +</body> +</html> |