test_bitmaprenderer.html (6842B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <title>WebGL in OffscreenCanvas</title> 5 <script src="/tests/SimpleTest/SimpleTest.js"></script> 6 <script src="/tests/SimpleTest/WindowSnapshot.js"></script> 7 <link rel="stylesheet" href="/tests/SimpleTest/test.css"> 8 </head> 9 <body> 10 <script type="text/js-worker"> 11 function ok(expect, msg) { 12 postMessage({"type": "status", status: !!expect, msg: msg}); 13 } 14 15 onmessage = function(event) { 16 var bitmap = event.data.bitmap; 17 ok(!!bitmap, "Get the ImageBitmap from the main script."); 18 19 var offscreenCanvas = new OffscreenCanvas(64, 64); 20 var ctx = offscreenCanvas.getContext('bitmaprenderer'); 21 ok(!!ctx, "Get bitmaprenderer context on worker."); 22 23 ctx.transferFromImageBitmap(bitmap); 24 var resultBitmap = offscreenCanvas.transferToImageBitmap(); 25 postMessage({"type": "bitmap", bitmap: resultBitmap}, [resultBitmap]); 26 } 27 </script> 28 <script> 29 30 SimpleTest.waitForExplicitFinish(); 31 32 function createCanvas(width, height) { 33 var htmlCanvas = document.createElement('canvas'); 34 htmlCanvas.width = width; 35 htmlCanvas.height = height; 36 document.body.appendChild(htmlCanvas); 37 return htmlCanvas; 38 } 39 40 function runTest(canvasWidth, canvasHeight, nextTest) { 41 var canvas1 = createCanvas(canvasWidth, canvasHeight); 42 var ctx = canvas1.getContext("2d"); 43 ctx.fillStyle = "#00FF00"; 44 ctx.fillRect(0, 0, canvasWidth, canvasHeight); 45 46 var canvasRef = createCanvas(canvasWidth, canvasHeight); 47 var ctx = canvasRef.getContext("2d"); 48 // Clear with black transparent first 49 ctx.fillStyle = "rgba(0, 0, 0, 0)"; 50 ctx.fillRect(0, 0, canvasWidth, canvasHeight); 51 52 ctx.fillStyle = "#00FF00"; 53 ctx.fillRect(0, 0, canvasWidth, canvasHeight); 54 55 createImageBitmap(canvas1).then(async function(bmp) { 56 document.body.removeChild(canvas1); 57 58 var canvas2 = createCanvas(90, 90); 59 var ctx2 = canvas2.getContext("bitmaprenderer"); 60 ctx2.transferFromImageBitmap(bmp); 61 62 ok(canvasRef.toDataURL() == canvas2.toDataURL(), "toDataURL should return same result."); 63 64 // Exam render result 65 canvasRef.style.display = "none"; 66 canvas2.style.display = "block"; 67 var snapshot = await snapshotWindow(window); 68 69 canvasRef.style.display = "block"; 70 canvas2.style.display = "none"; 71 var snapshotRef = await snapshotWindow(window); 72 73 // bitmaprenderers use an ImageLayer whereas a normal 2d canvas uses a canvas layer. This 74 // can result in some anti-aliasing differences on the edge. We consider slight AA differences 75 // to be reasonable when using different codepaths so fuzz a little bit. 76 var fuzz = { numDifferentPixels: 0, 77 maxDifference: 0 }; 78 if (SpecialPowers.Services.appinfo.widgetToolkit == "android") { 79 fuzz.maxDifference = 2; 80 fuzz.numDifferentPixels = 131; 81 } 82 var results = compareSnapshots(snapshot, snapshotRef, true, fuzz); 83 ok(results[0], "Screenshots should be the same"); 84 85 document.body.removeChild(canvasRef); 86 document.body.removeChild(canvas2); 87 88 nextTest(); 89 }); 90 } 91 92 function createSolidGreenBitmap(width, height) { 93 const canvas = createCanvas(width, height); 94 const ctx = canvas.getContext("2d"); 95 ctx.fillStyle = "#00FF00"; 96 ctx.fillRect(0, 0, width, height); 97 const bitmap = createImageBitmap(canvas); 98 document.body.removeChild(canvas); 99 return bitmap; 100 } 101 102 async function scaleTestCase(name, refWidth, refHeight, testWidth, testHeight, canvasWidth, canvasHeight) { 103 const refBitmap = await createSolidGreenBitmap(refWidth, refHeight); 104 const refCanvas = createCanvas(refWidth, refHeight); 105 const refCtx = refCanvas.getContext("bitmaprenderer"); 106 refCtx.transferFromImageBitmap(refBitmap); 107 is(refCanvas.width, refWidth, name + ": refCanvas width " + refCanvas.width + " is ref " + refWidth); 108 is(refCanvas.height, refHeight, name + ": refCanvas height " + refCanvas.height + " is ref " + refHeight); 109 const refSnapshot = await snapshotWindow(window); 110 document.body.removeChild(refCanvas); 111 112 const bitmap = await createSolidGreenBitmap(testWidth, testHeight); 113 const canvas = createCanvas(canvasWidth, canvasHeight); 114 const ctx = canvas.getContext("bitmaprenderer"); 115 ctx.transferFromImageBitmap(bitmap); 116 is(canvas.width, testWidth, name + ": canvas width " + canvas.width + " is bitmap " + testWidth); 117 is(canvas.height, testHeight, name + ": canvas height " + canvas.height + " is bitmap " + testHeight); 118 if (refWidth !== testWidth) { 119 canvas.width = refWidth; 120 is(canvas.width, refWidth, name + ": canvas width " + canvas.width + " is ref " + refWidth); 121 } 122 if (refHeight !== testHeight) { 123 canvas.height = refHeight; 124 is(canvas.height, refHeight, name + ": canvas height " + canvas.height + " is ref " + refHeight); 125 } 126 const snapshot = await snapshotWindow(window); 127 document.body.removeChild(canvas); 128 129 const results = compareSnapshots(snapshot, refSnapshot, true); 130 ok(results[0], name + ": screenshots should be the same"); 131 return Promise.resolve(); 132 } 133 134 async function scaleTest() { 135 await scaleTestCase("grow_unscaled", 64, 64, 64, 64, 32, 32); // Canvas grows, no scaling. 136 await scaleTestCase("grow_downscaled", 64, 64, 128, 128, 32, 32); // Canvas grows, scales down. 137 await scaleTestCase("grow_upscaled", 64, 64, 32, 32, 16, 16); // Canvas grows, scales up. 138 await scaleTestCase("same_downscaled", 64, 64, 128, 128, 128, 128); // Canvas unchanged, scales down. 139 await scaleTestCase("same_upscaled", 64, 64, 32, 32, 32, 32); // Canvas unchanged, scales up. 140 await scaleTestCase("shrink_unscaled", 64, 64, 64, 64, 128, 128); // Canvas shrinks, no scaling. 141 await scaleTestCase("shrink_downscaled", 64, 64, 128, 128, 256, 256); // Canvas shrinks, scales down. 142 await scaleTestCase("shrink_upscaled", 64, 64, 32, 32, 256, 256); // Canvas shrinks, scales up. 143 runTestOnWorker(); 144 } 145 146 function runTestOnWorker() { 147 var canvas1 = createCanvas(64, 64); 148 var ctx = canvas1.getContext("2d"); 149 ctx.fillStyle = "#00FF00"; 150 ctx.fillRect(0, 0, 64, 64); 151 152 var blob = new Blob(Array.prototype.map.call(document.querySelectorAll("script[type=\"text\/js-worker\"]"), function (oScript) { return oScript.textContent; }),{type: "text/javascript"}); 153 154 var worker = new Worker(window.URL.createObjectURL(blob)); 155 156 createImageBitmap(canvas1).then(function(bmp) { 157 worker.postMessage({bitmap: bmp}, [bmp]); 158 worker.onmessage = function(event) { 159 if (event.data.type == "status") { 160 ok(event.data.status, event.data.msg); 161 } else if (event.data.type == "bitmap") { 162 var canvas2 = createCanvas(64, 64); 163 var ctx2 = canvas2.getContext('bitmaprenderer'); 164 ctx2.transferFromImageBitmap(event.data.bitmap); 165 ok(canvas1.toDataURL() == canvas2.toDataURL(), 'toDataURL should be the same'); 166 SimpleTest.finish(); 167 } 168 } 169 }); 170 } 171 172 173 runTest(64, 64, runTest.bind(this, 128, 128, scaleTest)); 174 175 </script> 176 </body> 177 </html>