forked from mirrors/gecko-dev
		
	 351d147e2f
			
		
	
	
		351d147e2f
		
	
	
	
	
		
			
			Differential Revision: https://phabricator.services.mozilla.com/D44149 --HG-- extra : moz-landing-system : lando
		
			
				
	
	
		
			376 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			376 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* 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("experimental-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;
 | |
|   }
 | |
| })();
 |