diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /dom/canvas/test/offscreencanvas.js | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/canvas/test/offscreencanvas.js')
-rw-r--r-- | dom/canvas/test/offscreencanvas.js | 376 |
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; + } +})(); |