<!DOCTYPE html> <html> <body> <canvas id="canvas" width="3" height="2"></canvas> <script src="../../resources/js-test.js"></script> <script> jsTestIsAsync = true; var worker = new Worker('./resources/canvas-ImageBitmap-transferable.js'); description("Tests that ImageBitmap is transferable and that the pixel data survives the trip, as well as createImageBitmap(ImageBitmap) works on worker thread"); var imageWidth = 3; var imageHeight = 2; var bitmapWidth; var bitmapHeight; var newImage; var newImageBitmap; var image = new ImageData(new Uint8ClampedArray( [255, 0, 0, 255, 0, 255, 0, 255, 255, 255, 255, 127, 0, 0, 0, 64, 12, 34, 56, 64, 12, 34, 56, 127]), imageWidth, imageHeight); var context = document.getElementById("canvas").getContext("2d"); createImageBitmap(image).then(imageBitmap => { bitmapWidth = imageBitmap.width; bitmapHeight = imageBitmap.height; shouldBe("bitmapWidth", "imageWidth"); shouldBe("bitmapHeight", "imageHeight"); worker.postMessage({data: imageBitmap}, [imageBitmap]); // ImageBitmap has been transfered to worker, main thread loses ownership // of it, so the width and height should be 0 now. bitmapWidth = imageBitmap.width; bitmapHeight = imageBitmap.height; shouldBe("bitmapWidth", "0"); shouldBe("bitmapHeight", "0"); newImageBitmap = imageBitmap; // Test createImageBitmap from neutered ImageBitmap createImageBitmap(imageBitmap).then(function() { testFailed("Promise accepted, expected to be rejected"); finishJSTest(); }, () => { testPassed("createImageBitmap from a neutered ImageBitmap was rejected"); }); try { worker.postMessage({data:imageBitmap}); testFailed("Apply structured cloning succeed, expected to fail"); } catch(e) { testPassed("Apply structured cloning to a neutered ImageBitmap should throw an exception: " + e); } }); worker.onmessage = function(e) { newImageBitmap = e.data.data; bitmapWidth = newImageBitmap.width; bitmapHeight = newImageBitmap.height; // Getting the ImageBitmap back from the worker thread shouldBe("bitmapWidth", "imageWidth"); shouldBe("bitmapHeight", "imageHeight"); context.drawImage(newImageBitmap, 0, 0); newImage = context.getImageData(0, 0, imageWidth, imageHeight); // newImage is not necessary the same as imageData because of // multiplying and dividing by alpha during the round trip, but // they should be close. // The alpha channel should be exactly the same. shouldBeCloseTo("newImage.data[0]", "image.data[0]", 5); shouldBeCloseTo("newImage.data[1]", "image.data[1]", 5); shouldBeCloseTo("newImage.data[2]", "image.data[2]", 5); shouldBe("newImage.data[3]", "image.data[3]"); shouldBeCloseTo("newImage.data[4]", "image.data[4]", 5); shouldBeCloseTo("newImage.data[5]", "image.data[5]", 5); shouldBeCloseTo("newImage.data[6]", "image.data[6]", 5); shouldBe("newImage.data[7]", "image.data[7]"); shouldBeCloseTo("newImage.data[8]", "image.data[8]", 5); shouldBeCloseTo("newImage.data[9]", "image.data[9]", 5); shouldBeCloseTo("newImage.data[10]", "image.data[10]", 5); shouldBe("newImage.data[11]", "image.data[11]"); shouldBeCloseTo("newImage.data[12]", "image.data[12]", 5); shouldBeCloseTo("newImage.data[13]", "image.data[13]", 5); shouldBeCloseTo("newImage.data[14]", "image.data[14]", 5); shouldBe("newImage.data[15]", "image.data[15]"); shouldBeCloseTo("newImage.data[16]", "image.data[16]", 5); shouldBeCloseTo("newImage.data[17]", "image.data[17]", 5); shouldBeCloseTo("newImage.data[18]", "image.data[18]", 5); shouldBe("newImage.data[19]", "image.data[19]"); shouldBeCloseTo("newImage.data[20]", "image.data[20]", 5); shouldBeCloseTo("newImage.data[21]", "image.data[21]", 5); shouldBeCloseTo("newImage.data[22]", "image.data[22]", 5); shouldBe("newImage.data[23]", "image.data[23]"); finishJSTest(); } </script> </body> </html>