summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/offscreencanvas.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/test/offscreencanvas.js')
-rw-r--r--dom/canvas/test/offscreencanvas.js376
1 files changed, 376 insertions, 0 deletions
diff --git a/dom/canvas/test/offscreencanvas.js b/dom/canvas/test/offscreencanvas.js
new file mode 100644
index 0000000000..a1be9ce85c
--- /dev/null
+++ b/dom/canvas/test/offscreencanvas.js
@@ -0,0 +1,376 @@
+/* WebWorker for test_offscreencanvas_*.html */
+(function () {
+ var port = null;
+
+ function isInWorker() {
+ try {
+ return !(self instanceof Window);
+ } catch (e) {
+ return true;
+ }
+ }
+
+ function postMessageGeneral(data) {
+ if (isInWorker()) {
+ if (port) {
+ port.postMessage(data);
+ } else {
+ postMessage(data);
+ }
+ } else {
+ postMessage(data, "*");
+ }
+ }
+
+ function ok(expect, msg) {
+ postMessageGeneral({ type: "test", result: !!expect, name: msg });
+ }
+
+ function finish() {
+ postMessageGeneral({ type: "finish" });
+ }
+
+ function drawCount(count) {
+ postMessageGeneral({ type: "draw", count });
+ }
+
+ function sendBlob(blob) {
+ postMessageGeneral({ type: "blob", blob });
+ }
+
+ function sendImageBitmap(img) {
+ if (port) {
+ port.postMessage({ type: "imagebitmap", bitmap: img });
+ } else {
+ postMessage({ type: "imagebitmap", bitmap: img });
+ }
+ }
+
+ //--------------------------------------------------------------------
+ // WebGL Drawing Functions
+ //--------------------------------------------------------------------
+ function createDrawFunc(canvas) {
+ var gl;
+
+ try {
+ gl = canvas.getContext("webgl");
+ } catch (e) {}
+
+ if (!gl) {
+ ok(false, "WebGL is unavailable");
+ return null;
+ }
+
+ var vertSrc =
+ "attribute vec2 position; \
+ void main(void) { \
+ gl_Position = vec4(position, 0.0, 1.0); \
+ }";
+
+ var fragSrc =
+ "precision mediump float; \
+ void main(void) { \
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); \
+ }";
+
+ // Returns a valid shader, or null on errors.
+ var createShader = function (src, t) {
+ var shader = gl.createShader(t);
+
+ gl.shaderSource(shader, src);
+ gl.compileShader(shader);
+
+ return shader;
+ };
+
+ var createProgram = function (vsSrc, fsSrc) {
+ var vs = createShader(vsSrc, gl.VERTEX_SHADER);
+ var fs = createShader(fsSrc, gl.FRAGMENT_SHADER);
+
+ var prog = gl.createProgram();
+ gl.attachShader(prog, vs);
+ gl.attachShader(prog, fs);
+ gl.linkProgram(prog);
+
+ if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
+ var str = "Shader program linking failed:";
+ str += "\nShader program info log:\n" + gl.getProgramInfoLog(prog);
+ str += "\n\nVert shader log:\n" + gl.getShaderInfoLog(vs);
+ str += "\n\nFrag shader log:\n" + gl.getShaderInfoLog(fs);
+ console.log(str);
+ ok(false, "Shader program linking failed");
+ return null;
+ }
+
+ return prog;
+ };
+
+ gl.disable(gl.DEPTH_TEST);
+
+ var program = createProgram(vertSrc, fragSrc);
+ ok(program, "Creating shader program");
+
+ program.positionAttr = gl.getAttribLocation(program, "position");
+ ok(program.positionAttr >= 0, "position attribute should be valid");
+
+ var vertCoordArr = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
+ var vertCoordBuff = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertCoordBuff);
+ gl.bufferData(gl.ARRAY_BUFFER, vertCoordArr, gl.STATIC_DRAW);
+
+ var checkGLError = function (prefix, refValue) {
+ if (!refValue) {
+ refValue = 0;
+ }
+
+ var error = gl.getError();
+ ok(
+ error == refValue,
+ prefix +
+ "gl.getError should be 0x" +
+ refValue.toString(16) +
+ ", was 0x" +
+ error.toString(16) +
+ "."
+ );
+ };
+
+ var testPixel = function (x, y, refData, infoString) {
+ var pixel = new Uint8Array(4);
+ gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
+
+ var pixelMatches =
+ pixel[0] == refData[0] &&
+ pixel[1] == refData[1] &&
+ pixel[2] == refData[2] &&
+ pixel[3] == refData[3];
+ ok(pixelMatches, infoString);
+ };
+
+ var preDraw = function (prefix) {
+ gl.clearColor(1.0, 0.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ testPixel(
+ 0,
+ 0,
+ [255, 0, 0, 255],
+ prefix + "Should be red before drawing."
+ );
+ };
+
+ var postDraw = function (prefix) {
+ testPixel(
+ 0,
+ 0,
+ [0, 255, 0, 255],
+ prefix + "Should be green after drawing."
+ );
+ };
+
+ gl.useProgram(program);
+ gl.enableVertexAttribArray(program.position);
+ gl.vertexAttribPointer(program.position, 2, gl.FLOAT, false, 0, 0);
+
+ // Start drawing
+ checkGLError("after setup");
+
+ return function (prefix, needCommitFrame) {
+ if (prefix) {
+ prefix = "[" + prefix + "] ";
+ } else {
+ prefix = "";
+ }
+
+ gl.viewport(0, 0, canvas.width, canvas.height);
+ checkGLError(prefix + "[viewport]");
+
+ preDraw(prefix);
+ checkGLError(prefix + "[predraw]");
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+ checkGLError(prefix + "[drawarrays]");
+ postDraw(prefix);
+ checkGLError(prefix + "[postdraw]");
+ if (needCommitFrame) {
+ gl.commit();
+ checkGLError(prefix + "[commit]");
+ }
+ checkGLError(prefix);
+ };
+ }
+
+ /* entry point */
+ function entryFunction(testStr, subtests, offscreenCanvas) {
+ var test = testStr;
+ var canvas = offscreenCanvas;
+ if (test == "webgl_imagebitmap") {
+ canvas = new OffscreenCanvas(64, 64);
+ }
+
+ if (test != "subworker") {
+ ok(canvas, "Canvas successfully transfered to worker");
+ ok(canvas.getContext, "Canvas has getContext");
+
+ ok(canvas.width == 64, "OffscreenCanvas width should be 64");
+ ok(canvas.height == 64, "OffscreenCanvas height should be 64");
+ }
+
+ var draw;
+
+ //------------------------------------------------------------------------
+ // Basic WebGL test
+ //------------------------------------------------------------------------
+ if (test == "webgl") {
+ draw = createDrawFunc(canvas);
+ if (!draw) {
+ finish();
+ return;
+ }
+
+ var count = 0;
+ var iid = setInterval(function () {
+ if (count++ > 20) {
+ clearInterval(iid);
+ ok(true, "Worker is done");
+ finish();
+ return;
+ }
+ draw("loop " + count, true);
+ }, 0);
+ }
+ //------------------------------------------------------------------------
+ // Test dynamic fallback
+ //------------------------------------------------------------------------
+ else if (test == "webgl_fallback") {
+ draw = createDrawFunc(canvas);
+ if (!draw) {
+ return;
+ }
+
+ var count = 0;
+ var iid = setInterval(function () {
+ ++count;
+ draw("loop " + count, true);
+ drawCount(count);
+ }, 0);
+ }
+ //------------------------------------------------------------------------
+ // Test toBlob
+ //------------------------------------------------------------------------
+ else if (test == "webgl_toblob") {
+ draw = createDrawFunc(canvas);
+ if (!draw) {
+ return;
+ }
+
+ draw("", false);
+ canvas.toBlob().then(function (blob) {
+ sendBlob(blob);
+ });
+ }
+ //------------------------------------------------------------------------
+ // Test toImageBitmap
+ //------------------------------------------------------------------------
+ else if (test == "webgl_imagebitmap") {
+ draw = createDrawFunc(canvas);
+ if (!draw) {
+ return;
+ }
+
+ draw("", false);
+ var imgBitmap = canvas.transferToImageBitmap();
+ sendImageBitmap(imgBitmap);
+ }
+ //------------------------------------------------------------------------
+ // Canvas Size Change from Worker
+ //------------------------------------------------------------------------
+ else if (test == "webgl_changesize") {
+ draw = createDrawFunc(canvas);
+ if (!draw) {
+ finish();
+ return;
+ }
+
+ draw("64x64", true);
+
+ setTimeout(function () {
+ canvas.width = 128;
+ canvas.height = 128;
+ draw("Increased to 128x128", true);
+
+ setTimeout(function () {
+ canvas.width = 32;
+ canvas.width = 32;
+ draw("Decreased to 32x32", true);
+
+ setTimeout(function () {
+ canvas.width = 64;
+ canvas.height = 64;
+ draw("Increased to 64x64", true);
+
+ ok(true, "Worker is done");
+ finish();
+ }, 0);
+ }, 0);
+ }, 0);
+ }
+ //------------------------------------------------------------------------
+ // Using OffscreenCanvas from sub workers
+ //------------------------------------------------------------------------
+ else if (test == "subworker") {
+ /* subworker tests take a list of tests to run on children */
+ var stillRunning = 0;
+ subtests.forEach(function (subtest) {
+ ++stillRunning;
+ var subworker = new Worker("offscreencanvas.js");
+ subworker.onmessage = function (evt) {
+ /* report finish to parent when all children are finished */
+ if (evt.data.type == "finish") {
+ subworker.terminate();
+ if (--stillRunning == 0) {
+ ok(true, "Worker is done");
+ finish();
+ }
+ return;
+ }
+ /* relay all other messages to parent */
+ postMessage(evt.data);
+ };
+
+ var findTransferables = function (t) {
+ if (t.test == "subworker") {
+ var result = [];
+ t.subtests.forEach(function (subWorkerTest) {
+ result = result.concat(findTransferables(subWorkerTest));
+ });
+
+ return result;
+ } else {
+ return [t.canvas];
+ }
+ };
+
+ subworker.postMessage(subtest, findTransferables(subtest));
+ });
+ }
+ }
+
+ onmessage = function (evt) {
+ port = evt.ports[0];
+ entryFunction(evt.data.test, evt.data.subtests, evt.data.canvas);
+ };
+
+ onconnect = function (evt) {
+ port = evt.ports[0];
+
+ port.addEventListener("message", function (event) {
+ entryFunction(event.data.test, event.data.subtests, event.data.canvas);
+ });
+
+ port.start();
+ };
+
+ if (!isInWorker()) {
+ window.entryFunction = entryFunction;
+ }
+})();