Bug 1935611 - Fix libyuv/libpng link failed for loongarch64. r=glandium,tnikkel,ng
[gecko.git] / dom / canvas / test / offscreencanvas.js
bloba1be9ce85c2efc28d44065705b530844f91bf785
1 /* WebWorker for test_offscreencanvas_*.html */
2 (function () {
3   var port = null;
5   function isInWorker() {
6     try {
7       return !(self instanceof Window);
8     } catch (e) {
9       return true;
10     }
11   }
13   function postMessageGeneral(data) {
14     if (isInWorker()) {
15       if (port) {
16         port.postMessage(data);
17       } else {
18         postMessage(data);
19       }
20     } else {
21       postMessage(data, "*");
22     }
23   }
25   function ok(expect, msg) {
26     postMessageGeneral({ type: "test", result: !!expect, name: msg });
27   }
29   function finish() {
30     postMessageGeneral({ type: "finish" });
31   }
33   function drawCount(count) {
34     postMessageGeneral({ type: "draw", count });
35   }
37   function sendBlob(blob) {
38     postMessageGeneral({ type: "blob", blob });
39   }
41   function sendImageBitmap(img) {
42     if (port) {
43       port.postMessage({ type: "imagebitmap", bitmap: img });
44     } else {
45       postMessage({ type: "imagebitmap", bitmap: img });
46     }
47   }
49   //--------------------------------------------------------------------
50   // WebGL Drawing Functions
51   //--------------------------------------------------------------------
52   function createDrawFunc(canvas) {
53     var gl;
55     try {
56       gl = canvas.getContext("webgl");
57     } catch (e) {}
59     if (!gl) {
60       ok(false, "WebGL is unavailable");
61       return null;
62     }
64     var vertSrc =
65       "attribute vec2 position; \
66                  void main(void) { \
67                    gl_Position = vec4(position, 0.0, 1.0); \
68                  }";
70     var fragSrc =
71       "precision mediump float; \
72                  void main(void) { \
73                    gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); \
74                  }";
76     // Returns a valid shader, or null on errors.
77     var createShader = function (src, t) {
78       var shader = gl.createShader(t);
80       gl.shaderSource(shader, src);
81       gl.compileShader(shader);
83       return shader;
84     };
86     var createProgram = function (vsSrc, fsSrc) {
87       var vs = createShader(vsSrc, gl.VERTEX_SHADER);
88       var fs = createShader(fsSrc, gl.FRAGMENT_SHADER);
90       var prog = gl.createProgram();
91       gl.attachShader(prog, vs);
92       gl.attachShader(prog, fs);
93       gl.linkProgram(prog);
95       if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
96         var str = "Shader program linking failed:";
97         str += "\nShader program info log:\n" + gl.getProgramInfoLog(prog);
98         str += "\n\nVert shader log:\n" + gl.getShaderInfoLog(vs);
99         str += "\n\nFrag shader log:\n" + gl.getShaderInfoLog(fs);
100         console.log(str);
101         ok(false, "Shader program linking failed");
102         return null;
103       }
105       return prog;
106     };
108     gl.disable(gl.DEPTH_TEST);
110     var program = createProgram(vertSrc, fragSrc);
111     ok(program, "Creating shader program");
113     program.positionAttr = gl.getAttribLocation(program, "position");
114     ok(program.positionAttr >= 0, "position attribute should be valid");
116     var vertCoordArr = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
117     var vertCoordBuff = gl.createBuffer();
118     gl.bindBuffer(gl.ARRAY_BUFFER, vertCoordBuff);
119     gl.bufferData(gl.ARRAY_BUFFER, vertCoordArr, gl.STATIC_DRAW);
121     var checkGLError = function (prefix, refValue) {
122       if (!refValue) {
123         refValue = 0;
124       }
126       var error = gl.getError();
127       ok(
128         error == refValue,
129         prefix +
130           "gl.getError should be 0x" +
131           refValue.toString(16) +
132           ", was 0x" +
133           error.toString(16) +
134           "."
135       );
136     };
138     var testPixel = function (x, y, refData, infoString) {
139       var pixel = new Uint8Array(4);
140       gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
142       var pixelMatches =
143         pixel[0] == refData[0] &&
144         pixel[1] == refData[1] &&
145         pixel[2] == refData[2] &&
146         pixel[3] == refData[3];
147       ok(pixelMatches, infoString);
148     };
150     var preDraw = function (prefix) {
151       gl.clearColor(1.0, 0.0, 0.0, 1.0);
152       gl.clear(gl.COLOR_BUFFER_BIT);
154       testPixel(
155         0,
156         0,
157         [255, 0, 0, 255],
158         prefix + "Should be red before drawing."
159       );
160     };
162     var postDraw = function (prefix) {
163       testPixel(
164         0,
165         0,
166         [0, 255, 0, 255],
167         prefix + "Should be green after drawing."
168       );
169     };
171     gl.useProgram(program);
172     gl.enableVertexAttribArray(program.position);
173     gl.vertexAttribPointer(program.position, 2, gl.FLOAT, false, 0, 0);
175     // Start drawing
176     checkGLError("after setup");
178     return function (prefix, needCommitFrame) {
179       if (prefix) {
180         prefix = "[" + prefix + "] ";
181       } else {
182         prefix = "";
183       }
185       gl.viewport(0, 0, canvas.width, canvas.height);
186       checkGLError(prefix + "[viewport]");
188       preDraw(prefix);
189       checkGLError(prefix + "[predraw]");
190       gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
191       checkGLError(prefix + "[drawarrays]");
192       postDraw(prefix);
193       checkGLError(prefix + "[postdraw]");
194       if (needCommitFrame) {
195         gl.commit();
196         checkGLError(prefix + "[commit]");
197       }
198       checkGLError(prefix);
199     };
200   }
202   /* entry point */
203   function entryFunction(testStr, subtests, offscreenCanvas) {
204     var test = testStr;
205     var canvas = offscreenCanvas;
206     if (test == "webgl_imagebitmap") {
207       canvas = new OffscreenCanvas(64, 64);
208     }
210     if (test != "subworker") {
211       ok(canvas, "Canvas successfully transfered to worker");
212       ok(canvas.getContext, "Canvas has getContext");
214       ok(canvas.width == 64, "OffscreenCanvas width should be 64");
215       ok(canvas.height == 64, "OffscreenCanvas height should be 64");
216     }
218     var draw;
220     //------------------------------------------------------------------------
221     // Basic WebGL test
222     //------------------------------------------------------------------------
223     if (test == "webgl") {
224       draw = createDrawFunc(canvas);
225       if (!draw) {
226         finish();
227         return;
228       }
230       var count = 0;
231       var iid = setInterval(function () {
232         if (count++ > 20) {
233           clearInterval(iid);
234           ok(true, "Worker is done");
235           finish();
236           return;
237         }
238         draw("loop " + count, true);
239       }, 0);
240     }
241     //------------------------------------------------------------------------
242     // Test dynamic fallback
243     //------------------------------------------------------------------------
244     else if (test == "webgl_fallback") {
245       draw = createDrawFunc(canvas);
246       if (!draw) {
247         return;
248       }
250       var count = 0;
251       var iid = setInterval(function () {
252         ++count;
253         draw("loop " + count, true);
254         drawCount(count);
255       }, 0);
256     }
257     //------------------------------------------------------------------------
258     // Test toBlob
259     //------------------------------------------------------------------------
260     else if (test == "webgl_toblob") {
261       draw = createDrawFunc(canvas);
262       if (!draw) {
263         return;
264       }
266       draw("", false);
267       canvas.toBlob().then(function (blob) {
268         sendBlob(blob);
269       });
270     }
271     //------------------------------------------------------------------------
272     // Test toImageBitmap
273     //------------------------------------------------------------------------
274     else if (test == "webgl_imagebitmap") {
275       draw = createDrawFunc(canvas);
276       if (!draw) {
277         return;
278       }
280       draw("", false);
281       var imgBitmap = canvas.transferToImageBitmap();
282       sendImageBitmap(imgBitmap);
283     }
284     //------------------------------------------------------------------------
285     // Canvas Size Change from Worker
286     //------------------------------------------------------------------------
287     else if (test == "webgl_changesize") {
288       draw = createDrawFunc(canvas);
289       if (!draw) {
290         finish();
291         return;
292       }
294       draw("64x64", true);
296       setTimeout(function () {
297         canvas.width = 128;
298         canvas.height = 128;
299         draw("Increased to 128x128", true);
301         setTimeout(function () {
302           canvas.width = 32;
303           canvas.width = 32;
304           draw("Decreased to 32x32", true);
306           setTimeout(function () {
307             canvas.width = 64;
308             canvas.height = 64;
309             draw("Increased to 64x64", true);
311             ok(true, "Worker is done");
312             finish();
313           }, 0);
314         }, 0);
315       }, 0);
316     }
317     //------------------------------------------------------------------------
318     // Using OffscreenCanvas from sub workers
319     //------------------------------------------------------------------------
320     else if (test == "subworker") {
321       /* subworker tests take a list of tests to run on children */
322       var stillRunning = 0;
323       subtests.forEach(function (subtest) {
324         ++stillRunning;
325         var subworker = new Worker("offscreencanvas.js");
326         subworker.onmessage = function (evt) {
327           /* report finish to parent when all children are finished */
328           if (evt.data.type == "finish") {
329             subworker.terminate();
330             if (--stillRunning == 0) {
331               ok(true, "Worker is done");
332               finish();
333             }
334             return;
335           }
336           /* relay all other messages to parent */
337           postMessage(evt.data);
338         };
340         var findTransferables = function (t) {
341           if (t.test == "subworker") {
342             var result = [];
343             t.subtests.forEach(function (subWorkerTest) {
344               result = result.concat(findTransferables(subWorkerTest));
345             });
347             return result;
348           } else {
349             return [t.canvas];
350           }
351         };
353         subworker.postMessage(subtest, findTransferables(subtest));
354       });
355     }
356   }
358   onmessage = function (evt) {
359     port = evt.ports[0];
360     entryFunction(evt.data.test, evt.data.subtests, evt.data.canvas);
361   };
363   onconnect = function (evt) {
364     port = evt.ports[0];
366     port.addEventListener("message", function (event) {
367       entryFunction(event.data.test, event.data.subtests, event.data.canvas);
368     });
370     port.start();
371   };
373   if (!isInWorker()) {
374     window.entryFunction = entryFunction;
375   }
376 })();