1 /* WebWorker for test_offscreencanvas_*.html */
5 function isInWorker() {
7 return !(self instanceof Window);
13 function postMessageGeneral(data) {
16 port.postMessage(data);
21 postMessage(data, "*");
25 function ok(expect, msg) {
26 postMessageGeneral({ type: "test", result: !!expect, name: msg });
30 postMessageGeneral({ type: "finish" });
33 function drawCount(count) {
34 postMessageGeneral({ type: "draw", count });
37 function sendBlob(blob) {
38 postMessageGeneral({ type: "blob", blob });
41 function sendImageBitmap(img) {
43 port.postMessage({ type: "imagebitmap", bitmap: img });
45 postMessage({ type: "imagebitmap", bitmap: img });
49 //--------------------------------------------------------------------
50 // WebGL Drawing Functions
51 //--------------------------------------------------------------------
52 function createDrawFunc(canvas) {
56 gl = canvas.getContext("webgl");
60 ok(false, "WebGL is unavailable");
65 "attribute vec2 position; \
67 gl_Position = vec4(position, 0.0, 1.0); \
71 "precision mediump float; \
73 gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); \
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);
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);
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);
101 ok(false, "Shader program linking failed");
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) {
126 var error = gl.getError();
130 "gl.getError should be 0x" +
131 refValue.toString(16) +
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);
143 pixel[0] == refData[0] &&
144 pixel[1] == refData[1] &&
145 pixel[2] == refData[2] &&
146 pixel[3] == refData[3];
147 ok(pixelMatches, infoString);
150 var preDraw = function (prefix) {
151 gl.clearColor(1.0, 0.0, 0.0, 1.0);
152 gl.clear(gl.COLOR_BUFFER_BIT);
158 prefix + "Should be red before drawing."
162 var postDraw = function (prefix) {
167 prefix + "Should be green after drawing."
171 gl.useProgram(program);
172 gl.enableVertexAttribArray(program.position);
173 gl.vertexAttribPointer(program.position, 2, gl.FLOAT, false, 0, 0);
176 checkGLError("after setup");
178 return function (prefix, needCommitFrame) {
180 prefix = "[" + prefix + "] ";
185 gl.viewport(0, 0, canvas.width, canvas.height);
186 checkGLError(prefix + "[viewport]");
189 checkGLError(prefix + "[predraw]");
190 gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
191 checkGLError(prefix + "[drawarrays]");
193 checkGLError(prefix + "[postdraw]");
194 if (needCommitFrame) {
196 checkGLError(prefix + "[commit]");
198 checkGLError(prefix);
203 function entryFunction(testStr, subtests, offscreenCanvas) {
205 var canvas = offscreenCanvas;
206 if (test == "webgl_imagebitmap") {
207 canvas = new OffscreenCanvas(64, 64);
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");
220 //------------------------------------------------------------------------
222 //------------------------------------------------------------------------
223 if (test == "webgl") {
224 draw = createDrawFunc(canvas);
231 var iid = setInterval(function () {
234 ok(true, "Worker is done");
238 draw("loop " + count, true);
241 //------------------------------------------------------------------------
242 // Test dynamic fallback
243 //------------------------------------------------------------------------
244 else if (test == "webgl_fallback") {
245 draw = createDrawFunc(canvas);
251 var iid = setInterval(function () {
253 draw("loop " + count, true);
257 //------------------------------------------------------------------------
259 //------------------------------------------------------------------------
260 else if (test == "webgl_toblob") {
261 draw = createDrawFunc(canvas);
267 canvas.toBlob().then(function (blob) {
271 //------------------------------------------------------------------------
272 // Test toImageBitmap
273 //------------------------------------------------------------------------
274 else if (test == "webgl_imagebitmap") {
275 draw = createDrawFunc(canvas);
281 var imgBitmap = canvas.transferToImageBitmap();
282 sendImageBitmap(imgBitmap);
284 //------------------------------------------------------------------------
285 // Canvas Size Change from Worker
286 //------------------------------------------------------------------------
287 else if (test == "webgl_changesize") {
288 draw = createDrawFunc(canvas);
296 setTimeout(function () {
299 draw("Increased to 128x128", true);
301 setTimeout(function () {
304 draw("Decreased to 32x32", true);
306 setTimeout(function () {
309 draw("Increased to 64x64", true);
311 ok(true, "Worker is done");
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) {
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");
336 /* relay all other messages to parent */
337 postMessage(evt.data);
340 var findTransferables = function (t) {
341 if (t.test == "subworker") {
343 t.subtests.forEach(function (subWorkerTest) {
344 result = result.concat(findTransferables(subWorkerTest));
353 subworker.postMessage(subtest, findTransferables(subtest));
358 onmessage = function (evt) {
360 entryFunction(evt.data.test, evt.data.subtests, evt.data.canvas);
363 onconnect = function (evt) {
366 port.addEventListener("message", function (event) {
367 entryFunction(event.data.test, event.data.subtests, event.data.canvas);
374 window.entryFunction = entryFunction;