diff --git a/site/source/docs/api_reference/module.rst b/site/source/docs/api_reference/module.rst index c6f2bf0868f50..2c0124694f232 100644 --- a/site/source/docs/api_reference/module.rst +++ b/site/source/docs/api_reference/module.rst @@ -174,10 +174,6 @@ Other methods .. note:: Sanitizers or source map is currently not supported if overriding WebAssembly instantiation with Module.instantiateWasm. Providing Module.instantiateWasm when source map or sanitizer is enabled can prevent WebAssembly instantiation from finishing. -.. js:function:: Module.onCustomMessage - - When compiled with ``PROXY_TO_WORKER = 1`` (see `settings.js `_), this callback (which should be implemented on both the client and worker's ``Module`` object) allows sending custom messages and data between the web worker and the main thread (using the ``postCustomMessage`` function defined in `proxyClient.js `_ and `proxyWorker.js `_). - .. js:function:: Module.fetchSettings Override the default settings object used when fetching the Wasm module from diff --git a/site/source/docs/api_reference/wasm_workers.rst b/site/source/docs/api_reference/wasm_workers.rst index bea9afbeba3a0..ee94bdd56ed88 100644 --- a/site/source/docs/api_reference/wasm_workers.rst +++ b/site/source/docs/api_reference/wasm_workers.rst @@ -396,7 +396,6 @@ The following build options are not supported at the moment with Wasm Workers: - -sSINGLE_FILE - Dynamic linking (-sLINKABLE, -sMAIN_MODULE, -sSIDE_MODULE) -- -sPROXY_TO_WORKER - -sPROXY_TO_PTHREAD Example Code diff --git a/site/source/docs/tools_reference/settings_reference.rst b/site/source/docs/tools_reference/settings_reference.rst index c55d47022860a..79429e62b6b69 100644 --- a/site/source/docs/tools_reference/settings_reference.rst +++ b/site/source/docs/tools_reference/settings_reference.rst @@ -1679,27 +1679,6 @@ in a worker. See emscripten.h Default value: false -.. _proxy_to_worker: - -PROXY_TO_WORKER -=============== - -If set to 1, we build the project into a js file that will run in a worker, -and generate an html file that proxies input and output to/from it. - -Default value: false - -.. _proxy_to_worker_filename: - -PROXY_TO_WORKER_FILENAME -======================== - -If set, the script file name the main thread loads. Useful if your project -doesn't run the main emscripten- generated script immediately but does some -setup before - -Default value: '' - .. _proxy_to_pthread: PROXY_TO_PTHREAD @@ -3384,8 +3363,6 @@ the these settings please open a bug (or reply to one of the existing bugs). - ``ASYNCIFY_EXPORTS``: please use JSPI_EXPORTS instead - ``LINKABLE``: under consideration for removal (https://github.com/emscripten-core/emscripten/issues/25262) - ``RELOCATABLE``: under consideration for removal (https://github.com/emscripten-core/emscripten/issues/25262) - - ``PROXY_TO_WORKER``: under consideration for removal (See https://github.com/emscripten-core/emscripten/issues/25440) - - ``PROXY_TO_WORKER_FILENAME``: under consideration for removal (See https://github.com/emscripten-core/emscripten/issues/25440) .. _legacy-settings: @@ -3471,3 +3448,4 @@ for backwards compatbility with older versions: - ``USE_OFFSET_COVERTER``: No longer supported, not needed with modern v8 versions (Valid values: [0]) - ``ASYNCIFY_LAZY_LOAD_CODE``: No longer supported (Valid values: [0]) - ``USE_WEBGPU``: No longer supported; replaced by --use-port=emdawnwebgpu, which implements a newer (but incompatible) version of webgpu.h - see tools/ports/emdawnwebgpu.py (Valid values: [0]) + - ``PROXY_TO_WORKER``: No longer supported (Valid values: [0]) diff --git a/src/lib/libegl.js b/src/lib/libegl.js index 491f5e4d0b4ed..1724f91293bef 100644 --- a/src/lib/libegl.js +++ b/src/lib/libegl.js @@ -637,10 +637,6 @@ var LibraryEGL = { eglSwapBuffers__deps: ['$GLctx'], eglSwapBuffers__proxy: 'sync', eglSwapBuffers: (dpy, surface) => { -#if PROXY_TO_WORKER - if (Browser.doSwapBuffers) Browser.doSwapBuffers(); -#endif - if (!EGL.defaultDisplayInitialized) { EGL.setErrorCode(0x3001 /* EGL_NOT_INITIALIZED */); } else if (!GLctx) { diff --git a/src/lib/libwasm_worker.js b/src/lib/libwasm_worker.js index 8e9162ecd3aca..2c93a51d884a1 100644 --- a/src/lib/libwasm_worker.js +++ b/src/lib/libwasm_worker.js @@ -18,9 +18,6 @@ #if RELOCATABLE #error "dynamic linking is not supported with -sWASM_WORKERS" #endif -#if PROXY_TO_WORKER -#error "-sPROXY_TO_WORKER is not supported with -sWASM_WORKERS" -#endif #if WASM2JS && MODULARIZE #error "-sWASM=0 + -sMODULARIZE + -sWASM_WORKERS is not supported" #endif diff --git a/src/postamble.js b/src/postamble.js index 9879161660884..561305ec04c9d 100644 --- a/src/postamble.js +++ b/src/postamble.js @@ -6,13 +6,6 @@ // === Auto-generated postamble setup entry stuff === -#if PROXY_TO_WORKER -if (ENVIRONMENT_IS_WORKER) { -#include "webGLWorker.js" -#include "proxyWorker.js" -} -#endif - #if LOAD_SOURCE_MAP #include "source_map_support.js" #endif diff --git a/src/proxyClient.js b/src/proxyClient.js deleted file mode 100644 index 3d14a4ba06960..0000000000000 --- a/src/proxyClient.js +++ /dev/null @@ -1,353 +0,0 @@ -/** - * @license - * Copyright 2013 The Emscripten Authors - * SPDX-License-Identifier: MIT - */ - -/* - * Proxy events/work to/from an emscripen worker built - * with PROXY_TO_WORKER. This code runs on the main - * thread and is not part of the main emscripten output - * file. - */ - -#if !PROXY_TO_WORKER -#error "proxyClient.js should only be included in PROXY_TO_WORKER mode" -#endif - -#if ENVIRONMENT_MAY_BE_NODE -var ENVIRONMENT_IS_NODE = {{{ nodeDetectionCode() }}}; -if (ENVIRONMENT_IS_NODE) { - var NodeWorker = require('worker_threads').Worker; - global.Worker = function(url, options) { - // Special handling for `data:` URL argument, to match the behaviour - // of the Web API. - if (typeof url == 'string' && url.startsWith('data:')) { -#if EXPORT_ES6 - // worker_threads always assume data URLs are ES6 modules - url = new URL(url); -#else - // For class modules we decode the data URL and use `eval: true`. - url = Buffer.from(url.split(",")[1], 'base64').toString(); - if (!options) options = {}; - options.eval = true; -#endif - } - return new NodeWorker(url, options); - } - var Module = Module || {} -} else -#endif -if (typeof Module == 'undefined') { - console.warn('no Module object defined - cannot proxy canvas rendering and input events, etc.'); - Module = { - canvas: { - addEventListener: () => {}, - getBoundingClientRect: () => ({ bottom: 0, height: 0, left: 0, right: 0, top: 0, width: 0 }), - }, - }; -} - -if (!Module.hasOwnProperty('print')) { - Module['print'] = (x) => console.log(x); -} - -if (!Module.hasOwnProperty('printErr')) { - Module['printErr'] = (x) => console.error(x); -} - -// utils - -function FPSTracker(text) { - var last = 0; - var mean = 0; - var counter = 0; - this.tick = () => { - var now = Date.now(); - if (last > 0) { - var diff = now - last; - mean = 0.99*mean + 0.01*diff; - if (counter++ === 60) { - counter = 0; - dump(text + ' fps: ' + (1000/mean).toFixed(2) + '\n'); - } - } - last = now; - }; -} - -/* -function GenericTracker(text) { - var mean = 0; - var counter = 0; - this.tick = (value) => { - mean = 0.99*mean + 0.01*value; - if (counter++ === 60) { - counter = 0; - dump(text + ': ' + (mean).toFixed(2) + '\n'); - } - }; -} -*/ - -// render - -var renderFrameData = null; - -function renderFrame() { - var dst = Module.canvasData.data; - if (dst.set) { - dst.set(renderFrameData); - } else { - for (var i = 0; i < renderFrameData.length; i++) { - dst[i] = renderFrameData[i]; - } - } - Module['ctx'].putImageData(Module.canvasData, 0, 0); - renderFrameData = null; -} - -/* -(() => { - var trueRAF = window.requestAnimationFrame; - var tracker = new FPSTracker('client'); - window.requestAnimationFrame = (func) => { - trueRAF(() => { - tracker.tick(); - func(); - }); - } -})(); -*/ - -// end render - -// IDBStore - -#include "IDBStore.js" - -// Frame throttling - -var frameId = 0; - -// Worker - -var filename = "<<< filename >>>"; - -#if SINGLE_FILE && SINGLE_FILE_BINARY_ENCODE -#include "binaryDecode.js" - -#if ENVIRONMENT_MAY_BE_NODE -if (ENVIRONMENT_IS_NODE) filename = "data:text/javascript;base64," + Buffer.from(binaryDecode(filename)).toString('base64'); -else -#endif - filename = URL.createObjectURL(new Blob([binaryDecode(filename)], {type: 'application/javascript'})); - -#endif - -var worker = new Worker(filename); - -#if ENVIRONMENT_MAY_BE_NODE -if (ENVIRONMENT_IS_NODE) { - worker.postMessage({target: 'worker-init'}); -} else { -#endif -WebGLClient.prefetch(); - -setTimeout(() => { - worker.postMessage({ - target: 'worker-init', - width: Module['canvas'].width, - height: Module['canvas'].height, - boundingClientRect: cloneObject(Module['canvas'].getBoundingClientRect()), - URL: document.URL, - currentScriptUrl: filename, - preMain: true }); -}, 0); // delay til next frame, to make sure html is ready -#if ENVIRONMENT_MAY_BE_NODE -} -#endif - -var workerResponded = false; - -worker.onmessage = (event) => { - //dump('\nclient got ' + JSON.stringify(event.data).slice(0, 150) + '\n'); - if (!workerResponded) { - workerResponded = true; - Module.setStatus?.(''); - } - - var data = event.data; - switch (data.target) { - case 'stdout': { - Module['print'](data.content); - break; - } - case 'stderr': { - Module['printErr'](data.content); - break; - } - case 'window': { - window[data.method](); - break; - } - case 'canvas': { - switch (data.op) { - case 'getContext': { - Module['ctx'] = Module['canvas'].getContext(data.type, data.attributes); - if (data.type !== '2d') { - // possible GL_DEBUG entry point: Module['ctx'] = wrapDebugGL(Module['ctx']); - Module.glClient = new WebGLClient(); - } - break; - } - case 'resize': { - Module['canvas'].width = data.width; - Module['canvas'].height = data.height; - if (Module['ctx']?.getImageData) Module.canvasData = Module['ctx'].getImageData(0, 0, data.width, data.height); - worker.postMessage({ target: 'canvas', boundingClientRect: cloneObject(Module['canvas'].getBoundingClientRect()) }); - break; - } - case 'render': { - if (renderFrameData) { - // previous image was not rendered yet, just update image - renderFrameData = data.image.data; - } else { - // previous image was rendered so update image and request another frame - renderFrameData = data.image.data; - window.requestAnimationFrame(renderFrame); - } - break; - } - case 'setObjectProperty': { - Module['canvas'][data.object][data.property] = data.value; - break; - } - default: abort('eh?'); - } - break; - } - case 'gl': { - Module.glClient.onmessage(data); - break; - } - case 'tick': { - frameId = data.id; - worker.postMessage({ target: 'tock', id: frameId }); - break; - } - case 'Image': { - assert(data.method === 'src'); - var img = new Image(); - img.onload = () => { - assert(img.complete); - var canvas = document.createElement('canvas'); - canvas.width = img.width; - canvas.height = img.height; - var ctx = canvas.getContext('2d'); - ctx.drawImage(img, 0, 0); - var imageData = ctx.getImageData(0, 0, img.width, img.height); - worker.postMessage({ target: 'Image', method: 'onload', id: data.id, width: img.width, height: img.height, data: imageData.data, preMain: true }); - }; - img.onerror = () => { - worker.postMessage({ target: 'Image', method: 'onerror', id: data.id, preMain: true }); - }; - img.src = data.src; - break; - } - case 'IDBStore': { - switch (data.method) { - case 'loadBlob': { - IDBStore.getFile(data.db, data.id, (error, blob) => { - worker.postMessage({ - target: 'IDBStore', - method: 'response', - blob: error ? null : blob - }); - }); - break; - } - case 'storeBlob': { - IDBStore.setFile(data.db, data.id, data.blob, (error) => { - worker.postMessage({ - target: 'IDBStore', - method: 'response', - error: !!error - }); - }); - break; - } - } - break; - } - case 'custom': { - if (Module['onCustomMessage']) { - Module['onCustomMessage'](event); - } else { - abort('Custom message received but client Module.onCustomMessage not implemented.'); - } - break; - } - case 'setimmediate': { - worker.postMessage({target: 'setimmediate'}); - break; - } - default: abort('what? ' + data.target); - } -}; - -function postCustomMessage(data, options = {}) { - worker.postMessage({ target: 'custom', userData: data, preMain: options.preMain }); -} - -function cloneObject(event) { - var ret = {}; - for (var x in event) { - if (x == x.toUpperCase()) continue; - var prop = event[x]; - if (typeof prop == 'number' || typeof prop == 'string') ret[x] = prop; - } - return ret; -}; - -#if ENVIRONMENT_MAY_BE_NODE -if (!ENVIRONMENT_IS_NODE) { -#endif - -// Only prevent default on backspace/tab because we don't want unexpected navigation. -// Do not prevent default on the rest as we need the keypress event. -function shouldPreventDefault(event) { - if (event.type === 'keydown' && event.key != 'Backspace' && event.key != 'Tab') { - return false; // keypress, back navigation - } else { - return true; // NO keypress, NO back navigation - } -}; - - -['keydown', 'keyup', 'keypress', 'blur', 'visibilitychange'].forEach((event) => { - document.addEventListener(event, (event) => { - worker.postMessage({ target: 'document', event: cloneObject(event) }); - - if (shouldPreventDefault(event)) { - event.preventDefault(); - } - }); -}); - -['unload'].forEach((event) => { - window.addEventListener(event, (event) => { - worker.postMessage({ target: 'window', event: cloneObject(event) }); - }); -}); - -['mousedown', 'mouseup', 'mousemove', 'DOMMouseScroll', 'mousewheel', 'mouseout'].forEach((event) => { - Module['canvas'].addEventListener(event, (event) => { - worker.postMessage({ target: 'canvas', event: cloneObject(event) }); - event.preventDefault(); - }, true); -}); - -#if ENVIRONMENT_MAY_BE_NODE -} -#endif diff --git a/src/proxyWorker.js b/src/proxyWorker.js deleted file mode 100644 index 87eaa22494824..0000000000000 --- a/src/proxyWorker.js +++ /dev/null @@ -1,502 +0,0 @@ -/** - * @license - * Copyright 2013 The Emscripten Authors - * SPDX-License-Identifier: MIT - */ - -/* - * Implements the server/worker side of proxyClient.js. - * This code gets included in the main emscripten output - * when PROXY_TO_WORKER is used. The resulting code then - * needs to be run in a worker and receive events from - * proxyClient.js running on the main thread. - */ - -#if !PROXY_TO_WORKER -#error "proxyClient.js should only be included in PROXY_TO_WORKER mode" -#endif - -#if ENVIRONMENT_MAY_BE_NODE -if (!ENVIRONMENT_IS_NODE) { -#endif - -function FPSTracker(text) { - var last = 0; - var mean = 0; - var counter = 0; - this.tick = () => { - var now = Date.now(); - if (last > 0) { - var diff = now - last; - mean = 0.99*mean + 0.01*diff; - if (counter++ === 60) { - counter = 0; - dump(text + ' fps: ' + (1000/mean).toFixed(2) + '\n'); - } - } - last = now; - } -} - -function Element() { abort('TODO: Element'); } -function HTMLCanvasElement() { abort('TODO: HTMLCanvasElement'); } -function HTMLVideoElement() { abort('TODO: HTMLVideoElement'); } - -var KeyboardEvent = { - 'DOM_KEY_LOCATION_RIGHT': 2, -}; - -function PropertyBag() { - this.addProperty = () => {}; - this.removeProperty = () => {}; - this.setProperty = () => {}; -}; - -var IndexedObjects = { - nextId: 1, - cache: {}, - add(object) { - object.id = this.nextId++; - this.cache[object.id] = object; - } -}; - -function EventListener() { - this.listeners = {}; - - this.addEventListener = function addEventListener(event, func) { - this.listeners[event] ||= []; - this.listeners[event].push(func); - }; - - this.removeEventListener = function(event, func) { - var list = this.listeners[event]; - if (!list) return; - var me = list.indexOf(func); - if (me < 0) return; - list.splice(me, 1); - }; - - this.fireEvent = function(event) { - event.preventDefault = () => {}; - - if (event.type in this.listeners) { - this.listeners[event.type].forEach((listener) => listener(event)); - } - } -} - -function Image() { - IndexedObjects.add(this); - EventListener.call(this); - var src = ''; - Object.defineProperty(this, 'src', { - set: (value) => { - src = value; - assert(this.id); - postMessage({ target: 'Image', method: 'src', src, id: this.id }); - }, - get: () => src - }); -} -Image.prototype.onload = () => {}; -Image.prototype.onerror = () => {}; - -var HTMLImageElement = Image; - -var window = this; -var windowExtra = new EventListener(); -for (var x in windowExtra) window[x] = windowExtra[x]; - -window.close = () => { - postMessage({ target: 'window', method: 'close' }); -}; - -window.alert = (text) => { - err(`alert forever: ${text}`); - while (1) {}; -}; - -window.scrollX = window.scrollY = 0; // TODO: proxy these - -window.WebGLRenderingContext = WebGLWorker; - -window.requestAnimationFrame = (() => { - // similar to Browser.requestAnimationFrame - var nextRAF = 0; - return (func) => { - // try to keep 60fps between calls to here - var now = Date.now(); - if (nextRAF === 0) { - nextRAF = now + 1000/60; - } else { - while (now + 2 >= nextRAF) { // fudge a little, to avoid timer jitter causing us to do lots of delay:0 - nextRAF += 1000/60; - } - } - var delay = Math.max(nextRAF - now, 0); - setTimeout(func, delay); - }; -})(); - -var webGLWorker = new WebGLWorker(); - -var document = new EventListener(); - -document.createElement = (what) => { - switch (what) { - case 'canvas': { - var canvas = new EventListener(); - canvas.ensureData = () => { - if (!canvas.data || canvas.data.width !== canvas.width || canvas.data.height !== canvas.height) { - canvas.data = { - width: canvas.width, - height: canvas.height, - data: new Uint8Array(canvas.width*canvas.height*4) - }; - if (canvas === Module['canvas']) { - postMessage({ target: 'canvas', op: 'resize', width: canvas.width, height: canvas.height }); - } - } - }; - canvas.getContext = (type, attributes) => { - if (canvas === Module['canvas']) { - postMessage({ target: 'canvas', op: 'getContext', type, attributes }); - } - if (type === '2d') { - return { - getImageData: (x, y, w, h) => { - assert(x == 0 && y == 0 && w == canvas.width && h == canvas.height); - canvas.ensureData(); - return { - width: canvas.data.width, - height: canvas.data.height, - data: new Uint8Array(canvas.data.data) // TODO: can we avoid this copy? - }; - }, - putImageData: (image, x, y) => { - canvas.ensureData(); - assert(x == 0 && y == 0 && image.width == canvas.width && image.height == canvas.height); - canvas.data.data.set(image.data); // TODO: can we avoid this copy? - if (canvas === Module['canvas']) { - postMessage({ target: 'canvas', op: 'render', image: canvas.data }); - } - }, - drawImage: (image, x, y, w, h, ox, oy, ow, oh) => { - assert (!x && !y && !ox && !oy); - assert(w === ow && h === oh); - assert(canvas.width === w || w === undefined); - assert(canvas.height === h || h === undefined); - assert(image.width === canvas.width && image.height === canvas.height); - canvas.ensureData(); - canvas.data.data.set(image.data.data); // TODO: can we avoid this copy? - if (canvas === Module['canvas']) { - postMessage({ target: 'canvas', op: 'render', image: canvas.data }); - } - } - }; - } else { - return webGLWorker; - } - }; - canvas.boundingClientRect = {}; - canvas.getBoundingClientRect = () => ({ - width: canvas.boundingClientRect.width, - height: canvas.boundingClientRect.height, - top: canvas.boundingClientRect.top, - left: canvas.boundingClientRect.left, - bottom: canvas.boundingClientRect.bottom, - right: canvas.boundingClientRect.right - }); - canvas.style = new PropertyBag(); - - canvas.width_ ||= 0; - canvas.height_ ||= 0; - Object.defineProperty(canvas, 'width', { - set: (value) => { - canvas.width_ = value; - if (canvas === Module['canvas']) { - postMessage({ target: 'canvas', op: 'resize', width: canvas.width_, height: canvas.height_ }); - } - }, - get: () => canvas.width_ - }); - Object.defineProperty(canvas, 'height', { - set: (value) => { - canvas.height_ = value; - if (canvas === Module['canvas']) { - postMessage({ target: 'canvas', op: 'resize', width: canvas.width_, height: canvas.height_ }); - } - }, - get: () => canvas.height_ - }); - - var style = { - parentCanvas: canvas, - removeProperty: () => {}, - setProperty: () => {}, - }; - - Object.defineProperty(style, 'cursor', { - set: (value) => { - if (!style.cursor_ || style.cursor_ !== value) { - style.cursor_ = value; - if (style.parentCanvas === Module['canvas']) { - postMessage({ target: 'canvas', op: 'setObjectProperty', object: 'style', property: 'cursor', value: style.cursor_ }); - } - } - }, - get: () => style.cursor, - }); - - canvas.style = style; - return canvas; - } - default: { - abort('document.createElement ' + what); - } - } -}; - -document.getElementById = (id) => { - if (id === 'canvas' || id === 'application-canvas') { - return Module['canvas']; - } - abort('document.getElementById failed on ' + id); -}; - -document.querySelector = (id) => { - if (id === '#canvas' || id === '#application-canvas' || id === 'canvas' || id === 'application-canvas') { - return Module['canvas']; - } - abort('document.querySelector failed on ' + id); -}; - -document.documentElement = {}; - -document.styleSheets = [{ - cssRules: [], // TODO: forward to client - insertRule(rule, i) { - this.cssRules.splice(i, 0, rule); - } -}]; - -document.URL = 'http://worker.not.yet.ready.wait.for.window.onload?fake'; - -document.exitPointerLock = () => {}; - -function Audio() { - warnOnce('faking Audio elements, no actual sound will play'); -} -Audio.prototype = new EventListener(); -Object.defineProperty(Audio.prototype, 'src', { - set(value) { - if (value[0] === 'd') return; // ignore data urls - this.onerror(); - }, -}); - -Audio.prototype.play = () => {}; -Audio.prototype.pause = () => {}; - -Audio.prototype.cloneNode = () => new Audio; - -function AudioContext() { - warnOnce('faking WebAudio elements, no actual sound will play'); - var makeNode = () => { - return { - connect: () => {}, - disconnect: () => {}, - } - }; - this.listener = { - setPosition: () => {}, - setOrientation: () => {}, - }; - this.decodeAudioData = () => {}; // ignore callbacks - this.createBuffer = makeNode; - this.createBufferSource = makeNode; - this.createGain = makeNode; - this.createPanner = makeNode; -} - -var screen = { - width: 0, - height: 0 -}; - -Module['canvas'] = document.createElement('canvas'); - -Module.setStatus = () => {}; - -out = (x) => { - //dump('OUT: ' + x + '\n'); - postMessage({ target: 'stdout', content: x }); -}; -err = (x) => { - //dump('ERR: ' + x + '\n'); - postMessage({ target: 'stderr', content: x }); -}; - -// Frame throttling - -var frameId = 0; -var clientFrameId = 0; - -var postMainLoop = Module['postMainLoop']; -Module['postMainLoop'] = () => { - postMainLoop?.(); - // frame complete, send a frame id - postMessage({ target: 'tick', id: frameId++ }); - commandBuffer = []; -}; - -// Wait to start running until we receive some info from the client - -#if PTHREADS -if (!ENVIRONMENT_IS_PTHREAD) { -#endif - addRunDependency('gl-prefetch'); - addRunDependency('worker-init'); -#if PTHREADS -} -#endif - -#if ENVIRONMENT_MAY_BE_NODE -} -#endif - -// buffer messages until the program starts to run - -var messageBuffer = null; -var messageResenderTimeout = null; -var calledMain = false; - -// Set calledMain to true during postRun which happens once main returns -Module['postRun'] ||= []; -if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']]; -Module['postRun'].push(() => { calledMain = true; }); - -function messageResender() { - if (calledMain) { - assert(messageBuffer && messageBuffer.length > 0); - messageResenderTimeout = null; - messageBuffer.forEach(onmessage); - messageBuffer = null; - } else { - messageResenderTimeout = setTimeout(messageResender, 100); - } -} - -function onMessageFromMainEmscriptenThread(message) { - if (!calledMain && !message.data.preMain) { - if (!messageBuffer) { - messageBuffer = []; - messageResenderTimeout = setTimeout(messageResender, 100); - } - messageBuffer.push(message); - return; - } - if (calledMain && messageResenderTimeout) { - clearTimeout(messageResenderTimeout); - messageResender(); - } - //dump('worker got ' + JSON.stringify(message.data).slice(0, 150) + '\n'); - switch (message.data.target) { - case 'document': { - document.fireEvent(message.data.event); - break; - } - case 'window': { - window.fireEvent(message.data.event); - break; - } - case 'canvas': { - if (message.data.event) { - Module['canvas'].fireEvent(message.data.event); - } else if (message.data.boundingClientRect) { - Module['canvas'].boundingClientRect = message.data.boundingClientRect; - } else abort('ey?'); - break; - } - case 'gl': { - webGLWorker.onmessage(message.data); - break; - } - case 'tock': { - clientFrameId = message.data.id; - break; - } - case 'Image': { - var img = IndexedObjects.cache[message.data.id]; - switch (message.data.method) { - case 'onload': { - img.width = message.data.width; - img.height = message.data.height; - img.data = { width: img.width, height: img.height, data: message.data.data }; - img.complete = true; - img.onload(); - break; - } - case 'onerror': { - img.onerror({ srcElement: img }); - break; - } - } - break; - } - case 'IDBStore': { - assert(message.data.method === 'response'); - assert(IDBStore.pending); - IDBStore.pending(message.data); - break; - } - case 'worker-init': { - Module['canvas'] = document.createElement('canvas'); - screen.width = Module['canvas'].width_ = message.data.width; - screen.height = Module['canvas'].height_ = message.data.height; - Module['canvas'].boundingClientRect = message.data.boundingClientRect; -#if ENVIRONMENT_MAY_BE_NODE - if (ENVIRONMENT_IS_NODE) -#endif - document.URL = message.data.URL; -#if PTHREADS - currentScriptUrl = message.data.currentScriptUrl; -#endif - window.fireEvent({ type: 'load' }); - removeRunDependency('worker-init'); - break; - } - case 'custom': { - if (Module['onCustomMessage']) { - Module['onCustomMessage'](message); - } else { - abort('Custom message received but worker Module.onCustomMessage not implemented.'); - } - break; - } - case 'setimmediate': { - Module['setImmediates']?.shift()(); - break; - } - default: abort('wha? ' + message.data.target); - } -}; - -#if PTHREADS -if (!ENVIRONMENT_IS_PTHREAD) { -#endif - onmessage = onMessageFromMainEmscriptenThread; -#if PTHREADS -} -#endif - -// proxyWorker.js has defined 'document' and 'window' objects above, so need to -// initialize them for library_html5.js explicitly here. -if (typeof specialHTMLTargets != 'undefined') { - specialHTMLTargets = [0, document, window]; -} - -function postCustomMessage(data) { - postMessage({ target: 'custom', userData: data }); -} diff --git a/src/settings.js b/src/settings.js index a6019134fe63d..1383bf1fb4583 100644 --- a/src/settings.js +++ b/src/settings.js @@ -995,7 +995,7 @@ var INCOMING_MODULE_JS_API = [ 'instantiateWasm', 'keyboardListeningElement', 'freePreloadedMediaOnUse', 'loadSplitModule', 'locateFile', 'logReadFiles', 'mainScriptUrlOrBlob', 'mem', 'monitorRunDependencies', 'noExitRuntime', 'noInitialRun', 'onAbort', - 'onCustomMessage', 'onExit', 'onFree', 'onFullScreen', 'onMalloc', + 'onExit', 'onFree', 'onFullScreen', 'onMalloc', 'onRealloc', 'onRuntimeInitialized', 'postMainLoop', 'postRun', 'preInit', 'preMainLoop', 'preRun', 'preinitializedWebGLContext', 'preloadPlugins', @@ -1145,17 +1145,6 @@ var RUNTIME_LINKED_LIBS = []; // [link] var BUILD_AS_WORKER = false; -// If set to 1, we build the project into a js file that will run in a worker, -// and generate an html file that proxies input and output to/from it. -// [link] -var PROXY_TO_WORKER = false; - -// If set, the script file name the main thread loads. Useful if your project -// doesn't run the main emscripten- generated script immediately but does some -// setup before -// [link] -var PROXY_TO_WORKER_FILENAME = ''; - // If set to 1, compiles in a small stub main() in between the real main() which // calls pthread_create() to run the application main() in a pthread. This is // something that applications can do manually as well if they wish, this option diff --git a/src/shell.js b/src/shell.js index f7965f65f6718..51d82c1f91c38 100644 --- a/src/shell.js +++ b/src/shell.js @@ -89,7 +89,7 @@ var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIR #if PTHREADS // Three configurations we can be running in: // 1) We could be the application main() thread running in the main JS UI thread. (ENVIRONMENT_IS_WORKER == false and ENVIRONMENT_IS_PTHREAD == false) -// 2) We could be the application main() thread proxied to worker. (with Emscripten -sPROXY_TO_WORKER) (ENVIRONMENT_IS_WORKER == true, ENVIRONMENT_IS_PTHREAD == false) +// 2) We could be the application main() running directly in a worker. (ENVIRONMENT_IS_WORKER == true, ENVIRONMENT_IS_PTHREAD == false) // 3) We could be an application pthread running in a worker. (ENVIRONMENT_IS_WORKER == true and ENVIRONMENT_IS_PTHREAD == true) // The way we signal to a worker that it is hosting a pthread is to construct diff --git a/src/webGLClient.js b/src/webGLClient.js deleted file mode 100644 index e65041a611334..0000000000000 --- a/src/webGLClient.js +++ /dev/null @@ -1,367 +0,0 @@ -/** - * @license - * Copyright 2014 The Emscripten Authors - * SPDX-License-Identifier: MIT - */ - -// WebGLWorker client code - -function assert(x) { - if (!x) throw new Error('failed assert'); -} - -function WebGLClient() { - var objects = {}; - - var ctx = null; - var buffer = null; - var i = 0; - var skippable = false; - var currFrameBuffer = null; - - function func0(name) { - ctx[name](); - } - function func1(name) { - ctx[name](buffer[i]); - i++; - } - function func2(name) { - ctx[name](buffer[i], buffer[i+1]); - i += 2; - } - function func3(name) { - ctx[name](buffer[i], buffer[i+1], buffer[i+2]); - i += 3; - } - function func4(name) { - ctx[name](buffer[i], buffer[i+1], buffer[i+2], buffer[i+3]); - i += 4; - } - function func5(name) { - ctx[name](buffer[i], buffer[i+1], buffer[i+2], buffer[i+3], buffer[i+4]); - i += 5; - } - function func6(name) { - ctx[name](buffer[i], buffer[i+1], buffer[i+2], buffer[i+3], buffer[i+4], buffer[i+5]); - i += 6; - } - function func7(name) { - ctx[name](buffer[i], buffer[i+1], buffer[i+2], buffer[i+3], buffer[i+4], buffer[i+5], buffer[i+6]); - i += 7; - } - function func9(name) { - ctx[name](buffer[i], buffer[i+1], buffer[i+2], buffer[i+3], buffer[i+4], buffer[i+5], buffer[i+6], buffer[i+7], buffer[i+8]); - i += 9; - } - - // lookuppers, convert integer ids to cached objects for some args - function func1L0(name) { - ctx[name](objects[buffer[i]]); - i++; - } - function func2L0(name) { - ctx[name](objects[buffer[i]], buffer[i+1]); - i += 2; - } - function func2L0L1(name) { - ctx[name](objects[buffer[i]], objects[buffer[i+1]]); - i += 2; - } - function func2L1_(name) { - ctx[name](buffer[i], buffer[i+1] ? objects[buffer[i+1]] : null); - i += 2; - } - function func3L0(name) { - ctx[name](objects[buffer[i]], buffer[i+1], buffer[i+2]); - i += 3; - } - function func4L3_(name) { - ctx[name](buffer[i], buffer[i+1], buffer[i+2], buffer[i+3] ? objects[buffer[i+3]] : null); - i += 4; - } - function func5L3_(name) { - ctx[name](buffer[i], buffer[i+1], buffer[i+2], buffer[i+3] ? objects[buffer[i+3]] : null, buffer[i+4]); - i += 5; - } - - // constructors, last argument is the id to save as - function funcC0(name) { - var object = ctx[name](); - var id = buffer[i++]; - objects[id] = object; - } - function funcC1(name) { - var object = ctx[name](buffer[i++]); - var id = buffer[i++]; - objects[id] = object; - } - function funcC2(name) { - var object = ctx[name](buffer[i++], buffer[i++]); - var id = buffer[i++]; - objects[id] = object; - } - function funcC2L0(name) { - var object = ctx[name](objects[buffer[i++]], buffer[i++]); - var id = buffer[i++]; - objects[id] = object; - } - - // destructors, stop holding on to the object in the cache - function funcD0(name) { - var id = buffer[i++]; - var object = objects[id]; - objects[id] = null; - ctx[name](object); - } - - // special cases/optimizations - function bindFramebuffer() { - currFrameBuffer = buffer[i+1] ? objects[buffer[i+1]] : null; - ctx.bindFramebuffer(buffer[i], currFrameBuffer); - i += 2; - } - function drawArrays(name) { - if (!skippable || currFrameBuffer !== null) { - ctx.drawArrays(buffer[i], buffer[i+1], buffer[i+2]); - } - i += 3; - } - function drawElements(name) { - if (!skippable || currFrameBuffer !== null) { - ctx.drawElements(buffer[i], buffer[i+1], buffer[i+2], buffer[i+3]); - } - i += 4; - } - function enable() { - ctx.enable(buffer[i++]); - } - function disable() { - ctx.disable(buffer[i++]); - } - function enableVertexAttribArray() { - ctx.enableVertexAttribArray(buffer[i++]); - } - function disableVertexAttribArray() { - ctx.disableVertexAttribArray(buffer[i++]); - } - function activeTexture() { - ctx.activeTexture(buffer[i++]); - } - function uniform1i() { - ctx.uniform1i(objects[buffer[i]], buffer[i+1]); - i += 2; - } - function uniform1f() { - ctx.uniform1f(objects[buffer[i]], buffer[i+1]); - i += 2; - } - function uniform1fv() { - ctx.uniform1fv(objects[buffer[i]], buffer[i+1]); - i += 2; - } - function uniform2fv() { - ctx.uniform2fv(objects[buffer[i]], buffer[i+1]); - i += 2; - } - function uniform1iv() { - ctx.uniform1iv(objects[buffer[i]], buffer[i+1]); - i += 2; - } - function uniform3f() { - ctx.uniform3f(objects[buffer[i]], buffer[i+1], buffer[i+2], buffer[i+3]); - i += 4; - } - function uniform3fv() { - ctx.uniform3fv(objects[buffer[i]], buffer[i+1]); - i += 2; - } - function uniform4fv() { - ctx.uniform4fv(objects[buffer[i]], buffer[i+1]); - i += 2; - } - function vertexAttribPointer() { - ctx.vertexAttribPointer(buffer[i], buffer[i+1], buffer[i+2], buffer[i+3], buffer[i+4], buffer[i+5]); - i += 6; - } - - var calls = { - 0: { name: 'NULL', func: func0 }, - 1: { name: 'getExtension', func: func1 }, - 2: { name: 'enable', func: enable }, - 3: { name: 'disable', func: disable }, - 4: { name: 'clear', func: func1 }, - 5: { name: 'clearColor', func: func4 }, - 6: { name: 'createShader', func: funcC1 }, - 7: { name: 'deleteShader', func: funcD0 }, - 8: { name: 'shaderSource', func: func2L0 }, - 9: { name: 'compileShader', func: func1L0 }, - 10: { name: 'createProgram', func: funcC0 }, - 11: { name: 'deleteProgram', func: funcD0 }, - 12: { name: 'attachShader', func: func2L0L1 }, - 13: { name: 'bindAttribLocation', func: func3L0 }, - 14: { name: 'linkProgram', func: func1L0 }, - 15: { name: 'getProgramParameter', func: () => assert(ctx.getProgramParameter(objects[buffer[i++]], buffer[i++]), 'we cannot handle errors, we are async proxied WebGL') }, - 16: { name: 'getUniformLocation', func: funcC2L0 }, - 17: { name: 'useProgram', func: func1L0 }, - 18: { name: 'uniform1i', func: uniform1i }, - 19: { name: 'uniform1f', func: uniform1f }, - 20: { name: 'uniform3fv', func: uniform3fv }, - 21: { name: 'uniform4fv', func: uniform4fv }, - 22: { name: 'uniformMatrix4fv', func: func3L0 }, - 23: { name: 'vertexAttrib4fv', func: func2 }, - 24: { name: 'createBuffer', func: funcC0 }, - 25: { name: 'deleteBuffer', func: funcD0 }, - 26: { name: 'bindBuffer', func: func2L1_ }, - 27: { name: 'bufferData', func: func3 }, - 28: { name: 'bufferSubData', func: func3 }, - 29: { name: 'viewport', func: func4 }, - 30: { name: 'vertexAttribPointer', func: vertexAttribPointer }, - 31: { name: 'enableVertexAttribArray', func: enableVertexAttribArray }, - 32: { name: 'disableVertexAttribArray', func: disableVertexAttribArray }, - 33: { name: 'drawArrays', func: drawArrays }, - 34: { name: 'drawElements', func: drawElements }, - 35: { name: 'getError', func: () => assert(ctx.getError() === ctx.NO_ERROR, 'we cannot handle errors, we are async proxied WebGL') }, - 36: { name: 'createTexture', func: funcC0 }, - 37: { name: 'deleteTexture', func: funcD0 }, - 38: { name: 'bindTexture', func: func2L1_ }, - 39: { name: 'texParameteri', func: func3 }, - 40: { name: 'texImage2D', func: func9 }, - 41: { name: 'compressedTexImage2D', func: func7 }, - 42: { name: 'activeTexture', func: activeTexture }, - 43: { name: 'getShaderParameter', func: () => { - // Log shader compilation errors as warnings in the console log, since we cannot get the compilation logs back to the proxied Worker in any other way. - var object = objects[buffer[i++]]; - var param = buffer[i++]; - if (!ctx.getShaderParameter(object, param) && param == ctx.COMPILE_STATUS) console.warn(`Shader compilation failed: ${ctx.getShaderInfoLog(object)}`); - } }, - 44: { name: 'clearDepth', func: func1 }, - 45: { name: 'depthFunc', func: func1 }, - 46: { name: 'frontFace', func: func1 }, - 47: { name: 'cullFace', func: func1 }, - 48: { name: 'pixelStorei', func: func2 }, - 49: { name: 'depthMask', func: func1 }, - 50: { name: 'depthRange', func: func2 }, - 51: { name: 'blendFunc', func: func2 }, - 52: { name: 'scissor', func: func4 }, - 53: { name: 'colorMask', func: func4 }, - 54: { name: 'lineWidth', func: func1 }, - 55: { name: 'createFramebuffer', func: funcC0 }, - 56: { name: 'deleteFramebuffer', func: funcD0 }, - 57: { name: 'bindFramebuffer', func: bindFramebuffer }, - 58: { name: 'framebufferTexture2D', func: func5L3_ }, - 59: { name: 'createRenderbuffer', func: funcC0 }, - 60: { name: 'deleteRenderbuffer', func: funcD0 }, - 61: { name: 'bindRenderbuffer', func: func2L1_ }, - 62: { name: 'renderbufferStorage', func: func4 }, - 63: { name: 'framebufferRenderbuffer', func: func4L3_ }, - 64: { name: 'debugPrint', func: func1 }, - 65: { name: 'hint', func: func2 }, - 66: { name: 'blendEquation', func: func1 }, - 67: { name: 'generateMipmap', func: func1 }, - 68: { name: 'uniformMatrix3fv', func: func3L0 }, - 69: { name: 'stencilMask', func: func1 }, - 70: { name: 'clearStencil', func: func1 }, - 71: { name: 'texSubImage2D', func: func9 }, - 72: { name: 'uniform3f', func: uniform3f }, - 73: { name: 'blendFuncSeparate', func: func4 }, - 74: { name: 'uniform2fv', func: uniform2fv }, - 75: { name: 'texParameterf', func: func3 }, - 76: { name: 'isContextLost', func: () => assert(!ctx.isContextLost(), 'context lost which we cannot handle, we are async proxied WebGL') }, - 77: { name: 'blendEquationSeparate', func: func2 }, - 78: { name: 'stencilFuncSeparate', func: func4 }, - 79: { name: 'stencilOpSeparate', func: func4 }, - 80: { name: 'drawBuffersWEBGL', func: func1 }, - 81: { name: 'uniform1iv', func: uniform1iv }, - 82: { name: 'uniform1fv', func: uniform1fv }, - }; - - function renderCommands(buf) { - ctx = Module['ctx']; - i = 0; - buffer = buf; - var len = buffer.length; - //dump('issuing commands, buffer len: ' + len + '\n'); - while (i < len) { - var info = calls[buffer[i++]]; - var name = info.name; - info.func(name); - //var err; - //while ((err = ctx.getError()) !== ctx.NO_ERROR) { - // dump('warning: GL error ' + err + ', after ' + [command, numArgs] + '\n'); - //} - assert(i <= len); - } - } - - var commandBuffers = []; - - function renderAllCommands() { - // we can skip parts of the frames before the last, as we just need their side effects - skippable = true; - for (var i = 0; i < commandBuffers.length-1; i++) { - renderCommands(commandBuffers[i]); - } - skippable = false; - renderCommands(commandBuffers[commandBuffers.length-1]); - commandBuffers.length = 0; - } - - this.onmessage = (msg) => { - //dump('client GL got ' + JSON.stringify(msg) + '\n'); - switch (msg.op) { - case 'render': { - if (commandBuffers.length === 0) { - // requestion a new frame, we will clear the buffers after rendering them - window.requestAnimationFrame(renderAllCommands); - } - commandBuffers.push(msg.commandBuffer); - break; - } - default: abort('weird gl onmessage ' + JSON.stringify(msg)); - } - }; -} - -WebGLClient.prefetch = () => { - // Create a fake temporary GL context - var canvas = document.createElement('canvas'); - var ctx = canvas.getContext('webgl-experimental') || canvas.getContext('webgl'); - if (!ctx) { - // If we have no webGL support, we still notify that prefetching is done, as the app blocks on that - worker.postMessage({ target: 'gl', op: 'setPrefetched', preMain: true }); - return; - } - - // Fetch the parameters and proxy them - var parameters = {}; - ['MAX_VERTEX_ATTRIBS', 'MAX_TEXTURE_IMAGE_UNITS', 'MAX_TEXTURE_SIZE', 'MAX_CUBE_MAP_TEXTURE_SIZE', 'MAX_VERTEX_UNIFORM_VECTORS', 'MAX_FRAGMENT_UNIFORM_VECTORS', - 'MAX_VARYING_VECTORS', 'MAX_COMBINED_TEXTURE_IMAGE_UNITS', 'MAX_VERTEX_TEXTURE_IMAGE_UNITS', 'VENDOR', 'RENDERER', 'VERSION', 'SHADING_LANGUAGE_VERSION', - 'COMPRESSED_TEXTURE_FORMATS', 'RED_BITS', 'GREEN_BITS', 'BLUE_BITS', 'ALPHA_BITS', 'DEPTH_BITS', 'STENCIL_BITS', 'MAX_RENDERBUFFER_SIZE'].forEach(function(name) { - var id = ctx[name]; - parameters[id] = ctx.getParameter(id); - }); - // Try to enable some extensions, so we can access their parameters - [{ extName: 'EXT_texture_filter_anisotropic', paramName: 'MAX_TEXTURE_MAX_ANISOTROPY_EXT' }, - { extName: 'WEBGL_draw_buffers', paramName: 'MAX_COLOR_ATTACHMENTS_WEBGL' }].forEach(function(pair) { - var ext = ctx.getExtension(pair.extName); - if (ext) { - var id = ext[pair.paramName]; - parameters[id] = ctx.getParameter(id); - } - }); - // Fetch shader precisions - var precisions = {}; - ['FRAGMENT_SHADER', 'VERTEX_SHADER'].forEach(function(shaderType) { - shaderType = ctx[shaderType]; - precisions[shaderType] = {}; - ['LOW_FLOAT', 'MEDIUM_FLOAT', 'HIGH_FLOAT', 'LOW_INT', 'MEDIUM_INT', 'HIGH_INT'].forEach(function(precisionType) { - precisionType = ctx[precisionType]; - var info = ctx.getShaderPrecisionFormat(shaderType, precisionType); - precisions[shaderType][precisionType] = info ? { rangeMin: info.rangeMin, rangeMax: info.rangeMax, precision: info.precision } : info; - }); - }); - - worker.postMessage({ target: 'gl', op: 'setPrefetched', parameters, extensions: ctx.getSupportedExtensions(), precisions, preMain: true }); -}; - diff --git a/src/webGLWorker.js b/src/webGLWorker.js deleted file mode 100644 index 06426362fbe3a..0000000000000 --- a/src/webGLWorker.js +++ /dev/null @@ -1,1177 +0,0 @@ -/** - * @license - * Copyright 2014 The Emscripten Authors - * SPDX-License-Identifier: MIT - */ - -// WebGLWorker worker code - -function WebGLBuffer(id) { - this.what = 'buffer'; - this.id = id; -} -function WebGLProgram(id) { - this.what = 'program'; - this.id = id; - this.shaders = []; - this.attributes = {}; - this.attributeVec = []; - this.nextAttributes = {}; - this.nextAttributeVec = []; -} -function WebGLFramebuffer(id) { - this.what = 'frameBuffer'; - this.id = id; -} -function WebGLRenderbuffer(id) { - this.what = 'renderBuffer'; - this.id = id; -} -function WebGLTexture(id) { - this.what = 'texture'; - this.id = id; - this.binding = 0; -} - -function WebGLWorker() { - //=========== - // Constants - //=========== - - /* ClearBufferMask */ - this.DEPTH_BUFFER_BIT = 0x00000100; - this.STENCIL_BUFFER_BIT = 0x00000400; - this.COLOR_BUFFER_BIT = 0x00004000; - - /* BeginMode */ - this.POINTS = 0x0000; - this.LINES = 0x0001; - this.LINE_LOOP = 0x0002; - this.LINE_STRIP = 0x0003; - this.TRIANGLES = 0x0004; - this.TRIANGLE_STRIP = 0x0005; - this.TRIANGLE_FAN = 0x0006; - - /* AlphaFunction (not supported in ES20) */ - /* NEVER */ - /* LESS */ - /* EQUAL */ - /* LEQUAL */ - /* GREATER */ - /* NOTEQUAL */ - /* GEQUAL */ - /* ALWAYS */ - - /* BlendingFactorDest */ - this.ZERO = 0; - this.ONE = 1; - this.SRC_COLOR = 0x0300; - this.ONE_MINUS_SRC_COLOR = 0x0301; - this.SRC_ALPHA = 0x0302; - this.ONE_MINUS_SRC_ALPHA = 0x0303; - this.DST_ALPHA = 0x0304; - this.ONE_MINUS_DST_ALPHA = 0x0305; - - /* BlendingFactorSrc */ - /* ZERO */ - /* ONE */ - this.DST_COLOR = 0x0306; - this.ONE_MINUS_DST_COLOR = 0x0307; - this.SRC_ALPHA_SATURATE = 0x0308; - /* SRC_ALPHA */ - /* ONE_MINUS_SRC_ALPHA */ - /* DST_ALPHA */ - /* ONE_MINUS_DST_ALPHA */ - - /* BlendEquationSeparate */ - this.FUNC_ADD = 0x8006; - this.BLEND_EQUATION = 0x8009; - this.BLEND_EQUATION_RGB = 0x8009; /* same as BLEND_EQUATION */ - this.BLEND_EQUATION_ALPHA = 0x883D; - - /* BlendSubtract */ - this.FUNC_SUBTRACT = 0x800A; - this.FUNC_REVERSE_SUBTRACT = 0x800B; - - /* Separate Blend Functions */ - this.BLEND_DST_RGB = 0x80C8; - this.BLEND_SRC_RGB = 0x80C9; - this.BLEND_DST_ALPHA = 0x80CA; - this.BLEND_SRC_ALPHA = 0x80CB; - this.CONSTANT_COLOR = 0x8001; - this.ONE_MINUS_CONSTANT_COLOR = 0x8002; - this.CONSTANT_ALPHA = 0x8003; - this.ONE_MINUS_CONSTANT_ALPHA = 0x8004; - this.BLEND_COLOR = 0x8005; - - /* Buffer Objects */ - this.ARRAY_BUFFER = 0x8892; - this.ELEMENT_ARRAY_BUFFER = 0x8893; - this.ARRAY_BUFFER_BINDING = 0x8894; - this.ELEMENT_ARRAY_BUFFER_BINDING = 0x8895; - - this.STREAM_DRAW = 0x88E0; - this.STATIC_DRAW = 0x88E4; - this.DYNAMIC_DRAW = 0x88E8; - - this.BUFFER_SIZE = 0x8764; - this.BUFFER_USAGE = 0x8765; - - this.CURRENT_VERTEX_ATTRIB = 0x8626; - - /* CullFaceMode */ - this.FRONT = 0x0404; - this.BACK = 0x0405; - this.FRONT_AND_BACK = 0x0408; - - /* DepthFunction */ - /* NEVER */ - /* LESS */ - /* EQUAL */ - /* LEQUAL */ - /* GREATER */ - /* NOTEQUAL */ - /* GEQUAL */ - /* ALWAYS */ - - /* EnableCap */ - /* TEXTURE_2D */ - this.CULL_FACE = 0x0B44; - this.BLEND = 0x0BE2; - this.DITHER = 0x0BD0; - this.STENCIL_TEST = 0x0B90; - this.DEPTH_TEST = 0x0B71; - this.SCISSOR_TEST = 0x0C11; - this.POLYGON_OFFSET_FILL = 0x8037; - this.SAMPLE_ALPHA_TO_COVERAGE = 0x809E; - this.SAMPLE_COVERAGE = 0x80A0; - - /* ErrorCode */ - this.NO_ERROR = 0; - this.INVALID_ENUM = 0x0500; - this.INVALID_VALUE = 0x0501; - this.INVALID_OPERATION = 0x0502; - this.OUT_OF_MEMORY = 0x0505; - - /* FrontFaceDirection */ - this.CW = 0x0900; - this.CCW = 0x0901; - - /* GetPName */ - this.LINE_WIDTH = 0x0B21; - this.ALIASED_POINT_SIZE_RANGE = 0x846D; - this.ALIASED_LINE_WIDTH_RANGE = 0x846E; - this.CULL_FACE_MODE = 0x0B45; - this.FRONT_FACE = 0x0B46; - this.DEPTH_RANGE = 0x0B70; - this.DEPTH_WRITEMASK = 0x0B72; - this.DEPTH_CLEAR_VALUE = 0x0B73; - this.DEPTH_FUNC = 0x0B74; - this.STENCIL_CLEAR_VALUE = 0x0B91; - this.STENCIL_FUNC = 0x0B92; - this.STENCIL_FAIL = 0x0B94; - this.STENCIL_PASS_DEPTH_FAIL = 0x0B95; - this.STENCIL_PASS_DEPTH_PASS = 0x0B96; - this.STENCIL_REF = 0x0B97; - this.STENCIL_VALUE_MASK = 0x0B93; - this.STENCIL_WRITEMASK = 0x0B98; - this.STENCIL_BACK_FUNC = 0x8800; - this.STENCIL_BACK_FAIL = 0x8801; - this.STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802; - this.STENCIL_BACK_PASS_DEPTH_PASS = 0x8803; - this.STENCIL_BACK_REF = 0x8CA3; - this.STENCIL_BACK_VALUE_MASK = 0x8CA4; - this.STENCIL_BACK_WRITEMASK = 0x8CA5; - this.VIEWPORT = 0x0BA2; - this.SCISSOR_BOX = 0x0C10; - /* SCISSOR_TEST */ - this.COLOR_CLEAR_VALUE = 0x0C22; - this.COLOR_WRITEMASK = 0x0C23; - this.UNPACK_ALIGNMENT = 0x0CF5; - this.PACK_ALIGNMENT = 0x0D05; - this.MAX_TEXTURE_SIZE = 0x0D33; - this.MAX_VIEWPORT_DIMS = 0x0D3A; - this.SUBPIXEL_BITS = 0x0D50; - this.RED_BITS = 0x0D52; - this.GREEN_BITS = 0x0D53; - this.BLUE_BITS = 0x0D54; - this.ALPHA_BITS = 0x0D55; - this.DEPTH_BITS = 0x0D56; - this.STENCIL_BITS = 0x0D57; - this.POLYGON_OFFSET_UNITS = 0x2A00; - /* POLYGON_OFFSET_FILL */ - this.POLYGON_OFFSET_FACTOR = 0x8038; - this.TEXTURE_BINDING_2D = 0x8069; - this.SAMPLE_BUFFERS = 0x80A8; - this.SAMPLES = 0x80A9; - this.SAMPLE_COVERAGE_VALUE = 0x80AA; - this.SAMPLE_COVERAGE_INVERT = 0x80AB; - - /* GetTextureParameter */ - /* TEXTURE_MAG_FILTER */ - /* TEXTURE_MIN_FILTER */ - /* TEXTURE_WRAP_S */ - /* TEXTURE_WRAP_T */ - - this.COMPRESSED_TEXTURE_FORMATS = 0x86A3; - - /* HintMode */ - this.DONT_CARE = 0x1100; - this.FASTEST = 0x1101; - this.NICEST = 0x1102; - - /* HintTarget */ - this.GENERATE_MIPMAP_HINT = 0x8192; - - /* DataType */ - this.BYTE = 0x1400; - this.UNSIGNED_BYTE = 0x1401; - this.SHORT = 0x1402; - this.UNSIGNED_SHORT = 0x1403; - this.INT = 0x1404; - this.UNSIGNED_INT = 0x1405; - this.FLOAT = 0x1406; - - /* PixelFormat */ - this.DEPTH_COMPONENT = 0x1902; - this.ALPHA = 0x1906; - this.RGB = 0x1907; - this.RGBA = 0x1908; - this.LUMINANCE = 0x1909; - this.LUMINANCE_ALPHA = 0x190A; - - /* PixelType */ - /* UNSIGNED_BYTE */ - this.UNSIGNED_SHORT_4_4_4_4 = 0x8033; - this.UNSIGNED_SHORT_5_5_5_1 = 0x8034; - this.UNSIGNED_SHORT_5_6_5 = 0x8363; - - /* Shaders */ - this.FRAGMENT_SHADER = 0x8B30; - this.VERTEX_SHADER = 0x8B31; - this.MAX_VERTEX_ATTRIBS = 0x8869; - this.MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB; - this.MAX_VARYING_VECTORS = 0x8DFC; - this.MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D; - this.MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C; - this.MAX_TEXTURE_IMAGE_UNITS = 0x8872; - this.MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD; - this.SHADER_TYPE = 0x8B4F; - this.DELETE_STATUS = 0x8B80; - this.LINK_STATUS = 0x8B82; - this.VALIDATE_STATUS = 0x8B83; - this.ATTACHED_SHADERS = 0x8B85; - this.ACTIVE_UNIFORMS = 0x8B86; - this.ACTIVE_ATTRIBUTES = 0x8B89; - this.SHADING_LANGUAGE_VERSION = 0x8B8C; - this.CURRENT_PROGRAM = 0x8B8D; - - /* StencilFunction */ - this.NEVER = 0x0200; - this.LESS = 0x0201; - this.EQUAL = 0x0202; - this.LEQUAL = 0x0203; - this.GREATER = 0x0204; - this.NOTEQUAL = 0x0205; - this.GEQUAL = 0x0206; - this.ALWAYS = 0x0207; - - /* StencilOp */ - /* ZERO */ - this.KEEP = 0x1E00; - this.REPLACE = 0x1E01; - this.INCR = 0x1E02; - this.DECR = 0x1E03; - this.INVERT = 0x150A; - this.INCR_WRAP = 0x8507; - this.DECR_WRAP = 0x8508; - - /* StringName */ - this.VENDOR = 0x1F00; - this.RENDERER = 0x1F01; - this.VERSION = 0x1F02; - - /* TextureMagFilter */ - this.NEAREST = 0x2600; - this.LINEAR = 0x2601; - - /* TextureMinFilter */ - /* NEAREST */ - /* LINEAR */ - this.NEAREST_MIPMAP_NEAREST = 0x2700; - this.LINEAR_MIPMAP_NEAREST = 0x2701; - this.NEAREST_MIPMAP_LINEAR = 0x2702; - this.LINEAR_MIPMAP_LINEAR = 0x2703; - - /* TextureParameterName */ - this.TEXTURE_MAG_FILTER = 0x2800; - this.TEXTURE_MIN_FILTER = 0x2801; - this.TEXTURE_WRAP_S = 0x2802; - this.TEXTURE_WRAP_T = 0x2803; - - /* TextureTarget */ - this.TEXTURE_2D = 0x0DE1; - this.TEXTURE = 0x1702; - - this.TEXTURE_CUBE_MAP = 0x8513; - this.TEXTURE_BINDING_CUBE_MAP = 0x8514; - this.TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515; - this.TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516; - this.TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517; - this.TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518; - this.TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519; - this.TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A; - this.MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C; - - /* TextureUnit */ - this.TEXTURE0 = 0x84C0; - this.TEXTURE1 = 0x84C1; - this.TEXTURE2 = 0x84C2; - this.TEXTURE3 = 0x84C3; - this.TEXTURE4 = 0x84C4; - this.TEXTURE5 = 0x84C5; - this.TEXTURE6 = 0x84C6; - this.TEXTURE7 = 0x84C7; - this.TEXTURE8 = 0x84C8; - this.TEXTURE9 = 0x84C9; - this.TEXTURE10 = 0x84CA; - this.TEXTURE11 = 0x84CB; - this.TEXTURE12 = 0x84CC; - this.TEXTURE13 = 0x84CD; - this.TEXTURE14 = 0x84CE; - this.TEXTURE15 = 0x84CF; - this.TEXTURE16 = 0x84D0; - this.TEXTURE17 = 0x84D1; - this.TEXTURE18 = 0x84D2; - this.TEXTURE19 = 0x84D3; - this.TEXTURE20 = 0x84D4; - this.TEXTURE21 = 0x84D5; - this.TEXTURE22 = 0x84D6; - this.TEXTURE23 = 0x84D7; - this.TEXTURE24 = 0x84D8; - this.TEXTURE25 = 0x84D9; - this.TEXTURE26 = 0x84DA; - this.TEXTURE27 = 0x84DB; - this.TEXTURE28 = 0x84DC; - this.TEXTURE29 = 0x84DD; - this.TEXTURE30 = 0x84DE; - this.TEXTURE31 = 0x84DF; - this.ACTIVE_TEXTURE = 0x84E0; - - /* TextureWrapMode */ - this.REPEAT = 0x2901; - this.CLAMP_TO_EDGE = 0x812F; - this.MIRRORED_REPEAT = 0x8370; - - /* Uniform Types */ - this.FLOAT_VEC2 = 0x8B50; - this.FLOAT_VEC3 = 0x8B51; - this.FLOAT_VEC4 = 0x8B52; - this.INT_VEC2 = 0x8B53; - this.INT_VEC3 = 0x8B54; - this.INT_VEC4 = 0x8B55; - this.BOOL = 0x8B56; - this.BOOL_VEC2 = 0x8B57; - this.BOOL_VEC3 = 0x8B58; - this.BOOL_VEC4 = 0x8B59; - this.FLOAT_MAT2 = 0x8B5A; - this.FLOAT_MAT3 = 0x8B5B; - this.FLOAT_MAT4 = 0x8B5C; - this.SAMPLER_2D = 0x8B5E; - this.SAMPLER_3D = 0x8B5F; - this.SAMPLER_CUBE = 0x8B60; - - /* Vertex Arrays */ - this.VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622; - this.VERTEX_ATTRIB_ARRAY_SIZE = 0x8623; - this.VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624; - this.VERTEX_ATTRIB_ARRAY_TYPE = 0x8625; - this.VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A; - this.VERTEX_ATTRIB_ARRAY_POINTER = 0x8645; - this.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F; - - /* Read Format */ - this.IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A; - this.IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B; - - /* Shader Source */ - this.COMPILE_STATUS = 0x8B81; - - /* Shader Precision-Specified Types */ - this.LOW_FLOAT = 0x8DF0; - this.MEDIUM_FLOAT = 0x8DF1; - this.HIGH_FLOAT = 0x8DF2; - this.LOW_INT = 0x8DF3; - this.MEDIUM_INT = 0x8DF4; - this.HIGH_INT = 0x8DF5; - - /* Framebuffer Object. */ - this.FRAMEBUFFER = 0x8D40; - this.RENDERBUFFER = 0x8D41; - - this.RGBA4 = 0x8056; - this.RGB5_A1 = 0x8057; - this.RGB565 = 0x8D62; - this.DEPTH_COMPONENT16 = 0x81A5; - this.STENCIL_INDEX = 0x1901; - this.STENCIL_INDEX8 = 0x8D48; - this.DEPTH_STENCIL = 0x84F9; - - this.RENDERBUFFER_WIDTH = 0x8D42; - this.RENDERBUFFER_HEIGHT = 0x8D43; - this.RENDERBUFFER_INTERNAL_FORMAT = 0x8D44; - this.RENDERBUFFER_RED_SIZE = 0x8D50; - this.RENDERBUFFER_GREEN_SIZE = 0x8D51; - this.RENDERBUFFER_BLUE_SIZE = 0x8D52; - this.RENDERBUFFER_ALPHA_SIZE = 0x8D53; - this.RENDERBUFFER_DEPTH_SIZE = 0x8D54; - this.RENDERBUFFER_STENCIL_SIZE = 0x8D55; - - this.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0; - this.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1; - this.FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2; - this.FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3; - - this.COLOR_ATTACHMENT0 = 0x8CE0; - this.DEPTH_ATTACHMENT = 0x8D00; - this.STENCIL_ATTACHMENT = 0x8D20; - this.DEPTH_STENCIL_ATTACHMENT = 0x821A; - - this.NONE = 0; - - this.FRAMEBUFFER_COMPLETE = 0x8CD5; - this.FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6; - this.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7; - this.FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9; - this.FRAMEBUFFER_UNSUPPORTED = 0x8CDD; - - this.ACTIVE_TEXTURE = 0x84E0; - this.FRAMEBUFFER_BINDING = 0x8CA6; - this.RENDERBUFFER_BINDING = 0x8CA7; - this.MAX_RENDERBUFFER_SIZE = 0x84E8; - - this.INVALID_FRAMEBUFFER_OPERATION = 0x0506; - - /* WebGL-specific enums */ - this.UNPACK_FLIP_Y_WEBGL = 0x9240; - this.UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241; - this.CONTEXT_LOST_WEBGL = 0x9242; - this.UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243; - this.BROWSER_DEFAULT_WEBGL = 0x9244; - - //======= - // State - //======= - - var commandBuffer = []; - - var nextId = 1; // valid ids are > 0 - - var bindings = { - texture2D: null, - arrayBuffer: null, - elementArrayBuffer: null, - program: null, - framebuffer: null, - activeTexture: this.TEXTURE0, - generateMipmapHint: this.DONT_CARE, - blendSrcRGB: this.ONE, - blendSrcAlpha: this.ONE, - blendDstRGB: this.ZERO, - blendDstAlpha: this.ZERO, - blendEquationRGB: this.FUNC_ADD, - blendEquationAlpha: this.FUNC_ADD, - enabledState: {} // Stores whether various GL state via glEnable/glDisable/glIsEnabled/getParameter are enabled. - }; - var stateDisabledByDefault = [this.BLEND, this.CULL_FACE, this.DEPTH_TEST, this.DITHER, this.POLYGON_OFFSET_FILL, this.SAMPLE_ALPHA_TO_COVERAGE, this.SAMPLE_COVERAGE, this.SCISSOR_TEST, this.STENCIL_TEST]; - for (var i in stateDisabledByDefault) { - bindings.enabledState[stateDisabledByDefault[i]] = false; // It will be important to distinguish between false and undefined (undefined meaning the state cap enum is unknown/unsupported). - } - - //========== - // Functions - //========== - - var that = this; - - // Helpers - - this.onmessage = function(msg) { - //dump('worker GL got ' + JSON.stringify(msg) + '\n'); - switch (msg.op) { - case 'setPrefetched': { - WebGLWorker.prototype.prefetchedParameters = msg.parameters; - WebGLWorker.prototype.prefetchedExtensions = msg.extensions; - WebGLWorker.prototype.prefetchedPrecisions = msg.precisions; - removeRunDependency('gl-prefetch'); - break; - } - default: abort('weird gl onmessage ' + JSON.stringify(msg)); - } - }; - - function revname(name) { - for (var x in that) if (that[x] === name) return x; - return null; - } - - // GL - - this.getParameter = function(name) { - assert(name); - if (name in this.prefetchedParameters) return this.prefetchedParameters[name]; - switch (name) { - case this.TEXTURE_BINDING_2D: { - return bindings.texture2D; - } - case this.ARRAY_BUFFER_BINDING: { - return bindings.arrayBuffer; - } - case this.ELEMENT_ARRAY_BUFFER_BINDING: { - return bindings.elementArrayBuffer; - } - case this.CURRENT_PROGRAM: { - return bindings.program; - } - case this.FRAMEBUFFER_BINDING: { - return bindings.framebuffer; - } - case this.ACTIVE_TEXTURE: { - return bindings.activeTexture; - } - case this.GENERATE_MIPMAP_HINT: { - return bindings.generateMipmapHint; - } - case this.BLEND_SRC_RGB: { - return bindings.blendSrcRGB; - } - case this.BLEND_SRC_ALPHA: { - return bindings.blendSrcAlpha; - } - case this.BLEND_DST_RGB: { - return bindings.blendDstRGB; - } - case this.BLEND_DST_ALPHA: { - return bindings.blendDstAlpha; - } - case this.BLEND_EQUATION_RGB: { - return bindings.blendEquationRGB; - } - case this.BLEND_EQUATION_ALPHA: { - return bindings.blendEquationAlpha; - } - default: { - if (bindings.enabledState[name] !== undefined) return bindings.enabledState[name]; - abort('TODO: get parameter ' + name + ' : ' + revname(name)); - } - } - }; - this.getExtension = function(name) { - var i = this.prefetchedExtensions.indexOf(name); - if (i < 0) return null; - commandBuffer.push(1, name); - switch (name) { - case 'EXT_texture_filter_anisotropic': { - return { - TEXTURE_MAX_ANISOTROPY_EXT: 0x84FE, - MAX_TEXTURE_MAX_ANISOTROPY_EXT: 0x84FF - }; - } - case 'WEBGL_draw_buffers': { - return { - COLOR_ATTACHMENT0_WEBGL : 0x8CE0, - COLOR_ATTACHMENT1_WEBGL : 0x8CE1, - COLOR_ATTACHMENT2_WEBGL : 0x8CE2, - COLOR_ATTACHMENT3_WEBGL : 0x8CE3, - COLOR_ATTACHMENT4_WEBGL : 0x8CE4, - COLOR_ATTACHMENT5_WEBGL : 0x8CE5, - COLOR_ATTACHMENT6_WEBGL : 0x8CE6, - COLOR_ATTACHMENT7_WEBGL : 0x8CE7, - COLOR_ATTACHMENT8_WEBGL : 0x8CE8, - COLOR_ATTACHMENT9_WEBGL : 0x8CE9, - COLOR_ATTACHMENT10_WEBGL : 0x8CEA, - COLOR_ATTACHMENT11_WEBGL : 0x8CEB, - COLOR_ATTACHMENT12_WEBGL : 0x8CEC, - COLOR_ATTACHMENT13_WEBGL : 0x8CED, - COLOR_ATTACHMENT14_WEBGL : 0x8CEE, - COLOR_ATTACHMENT15_WEBGL : 0x8CEF, - - DRAW_BUFFER0_WEBGL : 0x8825, - DRAW_BUFFER1_WEBGL : 0x8826, - DRAW_BUFFER2_WEBGL : 0x8827, - DRAW_BUFFER3_WEBGL : 0x8828, - DRAW_BUFFER4_WEBGL : 0x8829, - DRAW_BUFFER5_WEBGL : 0x882A, - DRAW_BUFFER6_WEBGL : 0x882B, - DRAW_BUFFER7_WEBGL : 0x882C, - DRAW_BUFFER8_WEBGL : 0x882D, - DRAW_BUFFER9_WEBGL : 0x882E, - DRAW_BUFFER10_WEBGL : 0x882F, - DRAW_BUFFER11_WEBGL : 0x8830, - DRAW_BUFFER12_WEBGL : 0x8831, - DRAW_BUFFER13_WEBGL : 0x8832, - DRAW_BUFFER14_WEBGL : 0x8833, - DRAW_BUFFER15_WEBGL : 0x8834, - - MAX_COLOR_ATTACHMENTS_WEBGL : 0x8CDF, - MAX_DRAW_BUFFERS_WEBGL : 0x8824, - - drawBuffersWEBGL: function(buffers) { - that.drawBuffersWEBGL(buffers); - } - }; - } - case 'OES_standard_derivatives': { - return { FRAGMENT_SHADER_DERIVATIVE_HINT_OES: 0x8B8B }; - } - }; - return true; // TODO: return an object here - }; - this.getSupportedExtensions = function() { - return this.prefetchedExtensions; - }; - this.getShaderPrecisionFormat = function(shaderType, precisionType) { - return this.prefetchedPrecisions[shaderType][precisionType]; - }; - this.enable = function(cap) { - commandBuffer.push(2, cap); - bindings.enabledState[cap] = true; - }; - this.isEnabled = function(cap) { - return bindings.enabledState[cap]; - }; - this.disable = function(cap) { - commandBuffer.push(3, cap); - bindings.enabledState[cap] = false; - }; - this.clear = function(mask) { - commandBuffer.push(4, mask); - }; - this.clearColor = function(r, g, b, a) { - commandBuffer.push(5, r, g, b, a); - }; - this.createShader = function(type) { - var id = nextId++; - commandBuffer.push(6, type, id); - return { id, what: 'shader', type }; - }; - this.deleteShader = function(shader) { - if (!shader) return; - commandBuffer.push(7, shader.id); - }; - this.shaderSource = function(shader, source) { - shader.source = source; - commandBuffer.push(8, shader.id, source); - }; - this.compileShader = function(shader) { - commandBuffer.push(9, shader.id); - }; - this.getShaderInfoLog = function(shader) { - return ''; // optimistic assumption of success; no proxying - }; - this.createProgram = function() { - var id = nextId++; - commandBuffer.push(10, id); - return new WebGLProgram(id); - }; - this.deleteProgram = function(program) { - if (!program) return; - commandBuffer.push(11, program.id); - }; - this.attachShader = function(program, shader) { - program.shaders.push(shader); - commandBuffer.push(12, program.id, shader.id); - }; - this.bindAttribLocation = function(program, index, name) { - program.nextAttributes[name] = { what: 'attribute', name, size: -1, location: index, type: '?' }; // fill in size, type later - program.nextAttributeVec[index] = name; - commandBuffer.push(13, program.id, index, name); - }; - this.getAttribLocation = function(program, name) { - // all existing attribs are cached locally - if (name in program.attributes) return program.attributes[name].location; - return -1; - }; - this.linkProgram = function(program) { - // parse shader sources - function getTypeId(text) { - switch (text) { - case 'bool': return that.BOOL; - case 'int': return that.INT; - case 'uint': return that.UNSIGNED_INT; - case 'float': return that.FLOAT; - case 'vec2': return that.FLOAT_VEC2; - case 'vec3': return that.FLOAT_VEC3; - case 'vec4': return that.FLOAT_VEC4; - case 'ivec2': return that.INT_VEC2; - case 'ivec3': return that.INT_VEC3; - case 'ivec4': return that.INT_VEC4; - case 'bvec2': return that.BOOL_VEC2; - case 'bvec3': return that.BOOL_VEC3; - case 'bvec4': return that.BOOL_VEC4; - case 'mat2': return that.FLOAT_MAT2; - case 'mat3': return that.FLOAT_MAT3; - case 'mat4': return that.FLOAT_MAT4; - case 'sampler2D': return that.SAMPLER_2D; - case 'sampler3D': return that.SAMPLER_3D; - case 'samplerCube': return that.SAMPLER_CUBE; - default: abort('not yet recognized type text: ' + text); - } - } - function parseElementType(shader, type, obj, vec) { - var source = shader.source; - source = source.replace(/\n/g, '|\n'); // barrier between lines, to make regexing easier - var newItems = source.match(new RegExp(type + '\\s+\\w+\\s+[\\w,\\s\[\\]]+;', 'g')); - if (!newItems) return; - newItems.forEach((item) => { - var m = new RegExp(type + '\\s+(\\w+)\\s+([\\w,\\s\[\\]]+);').exec(item); - assert(m); - m[2].split(',').map((name) => { name = name.trim(); return name.search(/\s/) >= 0 ? '' : name }).filter((name) => !!name).forEach((name) => { - var size = 1; - var open = name.indexOf('['); - var fullname = name; - if (open >= 0) { - var close = name.indexOf(']'); - size = parseInt(name.slice(open+1, close)); - name = name.slice(0, open); - fullname = name + '[0]'; - } - if (!obj[name]) { - obj[name] = { what: type, name: fullname, size, location: -1, type: getTypeId(m[1]) }; - vec?.push(name); - } - }); - }); - } - - program.uniforms = {}; - program.uniformVec = []; - - program.attributes = program.nextAttributes; - program.attributeVec = program.nextAttributeVec; - program.nextAttributes = {}; - program.nextAttributeVec = []; - - var existingAttributes = {}; - - program.shaders.forEach((shader) => { - parseElementType(shader, 'uniform', program.uniforms, program.uniformVec); - parseElementType(shader, 'attribute', existingAttributes, null); - }); - - // bind not-yet bound attributes - for (var attr in existingAttributes) { - if (!(attr in program.attributes)) { - var index = program.attributeVec.length; - program.attributes[attr] = { what: 'attribute', name: attr, size: -1, location: index, type: '?' }; // fill in size, type later - program.attributeVec[index] = attr; - commandBuffer.push(13, program.id, index, attr); // do a bindAttribLocation as well, so this takes effect in the link we are about to do - } - program.attributes[attr].size = existingAttributes[attr].size; - program.attributes[attr].type = existingAttributes[attr].type; - } - - commandBuffer.push(14, program.id); - }; - this.getProgramParameter = function(program, name) { - switch (name) { - case this.ACTIVE_UNIFORMS: return program.uniformVec.length; - case this.ACTIVE_ATTRIBUTES: return program.attributeVec.length; - case this.LINK_STATUS: { - // optimisticaly return success; client will abort on an actual error. we assume an error-free async workflow - commandBuffer.push(15, program.id, name); - return true; - } - default: abort('bad getProgramParameter ' + revname(name)); - } - }; - this.getActiveAttrib = function(program, index) { - var name = program.attributeVec[index]; - if (!name) return null; - return program.attributes[name]; - }; - this.getActiveUniform = function(program, index) { - var name = program.uniformVec[index]; - if (!name) return null; - return program.uniforms[name]; - }; - this.getUniformLocation = function(program, name) { - var fullname = name; - var index = -1; - var open = name.indexOf('['); - if (open >= 0) { - var close = name.indexOf(']'); - index = parseInt(name.slice(open+1, close)); - name = name.slice(0, open); - } - if (!(name in program.uniforms)) return null; - var id = nextId++; - commandBuffer.push(16, program.id, fullname, id); - return { what: 'location', uniform: program.uniforms[name], id, index }; - }; - this.getProgramInfoLog = function(shader) { - return ''; // optimistic assumption of success; no proxying - }; - this.useProgram = function(program) { - commandBuffer.push(17, program ? program.id : 0); - bindings.program = program; - }; - this.uniform1i = function(location, data) { - if (!location) return; - commandBuffer.push(18, location.id, data); - }; - this.uniform1f = function(location, data) { - if (!location) return; - commandBuffer.push(19, location.id, data); - }; - this.uniform3fv = function(location, data) { - if (!location) return; - commandBuffer.push(20, location.id, new Float32Array(data)); - }; - this.uniform4f = function(location, x, y, z, w) { - if (!location) return; - commandBuffer.push(21, location.id, new Float32Array([x, y, z, w])); - }; - this.uniform4fv = function(location, data) { - if (!location) return; - commandBuffer.push(21, location.id, new Float32Array(data)); - }; - this.uniformMatrix4fv = function(location, transpose, data) { - if (!location) return; - commandBuffer.push(22, location.id, transpose, new Float32Array(data)); - }; - this.vertexAttrib4fv = function(index, values) { - commandBuffer.push(23, index, new Float32Array(values)); - }; - this.createBuffer = function() { - var id = nextId++; - commandBuffer.push(24, id); - return new WebGLBuffer(id); - }; - this.deleteBuffer = function(buffer) { - if (!buffer) return; - commandBuffer.push(25, buffer.id); - }; - this.bindBuffer = function(target, buffer) { - commandBuffer.push(26, target, buffer ? buffer.id : 0); - switch (target) { - case this.ARRAY_BUFFER_BINDING: { - bindings.arrayBuffer = buffer; - break; - } - case this.ELEMENT_ARRAY_BUFFER_BINDING: { - bindings.elementArrayBuffer = buffer; - break; - } - } - }; - function duplicate(something) { - // clone data properly: handles numbers, null, typed arrays, js arrays and array buffers - if (!something || typeof something == 'number') return something; - if (something.slice) return something.slice(0); // ArrayBuffer or js array - return new something.constructor(something); // typed array - } - this.bufferData = function(target, something, usage) { - commandBuffer.push(27, target, duplicate(something), usage); - }; - this.bufferSubData = function(target, offset, something) { - commandBuffer.push(28, target, offset, duplicate(something)); - }; - this.viewport = function(x, y, w, h) { - commandBuffer.push(29, x, y, w, h); - }; - this.vertexAttribPointer = function(index, size, type, normalized, stride, offset) { - commandBuffer.push(30, index, size, type, normalized, stride, offset); - }; - this.enableVertexAttribArray = function(index) { - commandBuffer.push(31, index); - }; - this.disableVertexAttribArray = function(index) { - commandBuffer.push(32, index); - }; - this.drawArrays = function(mode, first, count) { - commandBuffer.push(33, mode, first, count); - }; - this.drawElements = function(mode, count, type, offset) { - commandBuffer.push(34, mode, count, type, offset); - }; - this.getError = function() { - // optimisticaly return success; client will abort on an actual error. we assume an error-free async workflow - commandBuffer.push(35); - return this.NO_ERROR; - }; - this.createTexture = function() { - var id = nextId++; - commandBuffer.push(36, id); - return new WebGLTexture(id); - }; - this.deleteTexture = function(texture) { - if (!texture) return; - commandBuffer.push(37, texture.id); - texture.id = 0; - }; - this.isTexture = function(texture) { - return texture && texture.what === 'texture' && texture.id > 0 && texture.binding; - }; - this.bindTexture = function(target, texture) { - switch (target) { - case that.TEXTURE_2D: { - bindings.texture2D = texture; - break; - } - } - if (texture) texture.binding = target; - commandBuffer.push(38, target, texture ? texture.id : 0); - }; - this.texParameteri = function(target, pname, param) { - commandBuffer.push(39, target, pname, param); - }; - this.texImage2D = function(target, level, internalformat, width, height, border, format, type, pixels) { - if (pixels === undefined) { - format = width; // width, height, border do not exist in the shorter overload - type = height; - pixels = border; - assert(pixels instanceof Image); - assert(internalformat === format && format === this.RGBA); // HTML Images are RGBA, 8-bit - assert(type === this.UNSIGNED_BYTE); - var data = pixels.data; - width = data.width; - height = data.height; - border = 0; - pixels = new Uint8Array(data.data); // XXX transform from clamped to normal, could have been done in duplicate - } - commandBuffer.push(40, target, level, internalformat, width, height, border, format, type, duplicate(pixels)); - }; - this.compressedTexImage2D = function(target, level, internalformat, width, height, border, pixels) { - commandBuffer.push(41, target, level, internalformat, width, height, border, duplicate(pixels)); - }; - this.activeTexture = function(texture) { - commandBuffer.push(42, texture); - bindings.activeTexture = texture; - }; - this.getShaderParameter = function(shader, pname) { - switch (pname) { - case this.SHADER_TYPE: return shader.type; - case this.COMPILE_STATUS: { - // optimisticaly return success; client will abort on an actual error. we assume an error-free async workflow - commandBuffer.push(43, shader.id, pname); - return true; - } - default: abort('unsupported getShaderParameter ' + pname); - } - }; - this.clearDepth = function(depth) { - commandBuffer.push(44, depth); - }; - this.depthFunc = function(depth) { - commandBuffer.push(45, depth); - }; - this.frontFace = function(depth) { - commandBuffer.push(46, depth); - }; - this.cullFace = function(depth) { - commandBuffer.push(47, depth); - }; - this.readPixels = function(depth) { - abort('readPixels is impossible, we are async GL'); - }; - this.pixelStorei = function(pname, param) { - commandBuffer.push(48, pname, param); - }; - this.depthMask = function(flag) { - commandBuffer.push(49, flag); - }; - this.depthRange = function(near, far) { - commandBuffer.push(50, near, far); - }; - this.blendFunc = function(sfactor, dfactor) { - commandBuffer.push(51, sfactor, dfactor); - bindings.blendSrcRGB = bindings.blendSrcAlpha = sfactor; - bindings.blendDstRGB = bindings.blendDstAlpha = dfactor; - }; - this.scissor = function(x, y, width, height) { - commandBuffer.push(52, x, y, width, height); - }; - this.colorMask = function(red, green, blue, alpha) { - commandBuffer.push(53, red, green, blue, alpha); - }; - this.lineWidth = function(width) { - commandBuffer.push(54, width); - }; - this.createFramebuffer = function() { - var id = nextId++; - commandBuffer.push(55, id); - return new WebGLFramebuffer(id); - }; - this.deleteFramebuffer = function(framebuffer) { - if (!framebuffer) return; - commandBuffer.push(56, framebuffer.id); - }; - this.bindFramebuffer = function(target, framebuffer) { - commandBuffer.push(57, target, framebuffer ? framebuffer.id : 0); - bindings.framebuffer = framebuffer; - }; - this.framebufferTexture2D = function(target, attachment, textarget, texture, level) { - commandBuffer.push(58, target, attachment, textarget, texture ? texture.id : 0, level); - }; - this.checkFramebufferStatus = function(target) { - return this.FRAMEBUFFER_COMPLETE; // XXX totally wrong - }; - this.createRenderbuffer = function() { - var id = nextId++; - commandBuffer.push(59, id); - return new WebGLRenderbuffer(id); - }; - this.deleteRenderbuffer = function(renderbuffer) { - if (!renderbuffer) return; - commandBuffer.push(60, renderbuffer.id); - }; - this.bindRenderbuffer = function(target, renderbuffer) { - commandBuffer.push(61, target, renderbuffer ? renderbuffer.id : 0); - }; - this.renderbufferStorage = function(target, internalformat, width, height) { - commandBuffer.push(62, target, internalformat, width, height); - }; - this.framebufferRenderbuffer = function(target, attachment, renderbuffertarget, renderbuffer) { - commandBuffer.push(63, target, attachment, renderbuffertarget, renderbuffer ? renderbuffer.id : 0); - }; - this.debugPrint = function(text) { // useful to interleave debug output properly with client GL commands - commandBuffer.push(64, text); - }; - this.hint = function(target, mode) { - commandBuffer.push(65, target, mode); - if (target == this.GENERATE_MIPMAP_HINT) bindings.generateMipmapHint = mode; - }; - this.blendEquation = function(mode) { - commandBuffer.push(66, mode); - bindings.blendEquationRGB = bindings.blendEquationAlpha = mode; - }; - this.generateMipmap = function(target) { - commandBuffer.push(67, target); - }; - this.uniformMatrix3fv = function(location, transpose, data) { - if (!location) return; - commandBuffer.push(68, location.id, transpose, new Float32Array(data)); - }; - this.stencilMask = function(mask) { - commandBuffer.push(69, mask); - }; - this.clearStencil = function(s) { - commandBuffer.push(70, s); - }; - this.texSubImage2D = function(target, level, xoffset, yoffset, width, height, format, type, pixels) { - if (pixels === undefined) { - // shorter overload: target, level, xoffset, yoffset, format, type, pixels - var formatTemp = format; - format = width; - type = height; - pixels = formatTemp; - assert(pixels instanceof Image); - assert(format === this.RGBA); // HTML Images are RGBA, 8-bit - assert(type === this.UNSIGNED_BYTE); - var data = pixels.data; - width = data.width; - height = data.height; - pixels = new Uint8Array(data.data); // XXX transform from clamped to normal, could have been done in duplicate - } - commandBuffer.push(71, target, level, xoffset, yoffset, width, height, format, type, duplicate(pixels)); - }; - this.uniform3f = function(location, x, y, z) { - if (!location) return; - commandBuffer.push(72, location.id, x, y, z); - }; - this.blendFuncSeparate = function(srcRGB, dstRGB, srcAlpha, dstAlpha) { - commandBuffer.push(73, srcRGB, dstRGB, srcAlpha, dstAlpha); - bindings.blendSrcRGB = srcRGB; - bindings.blendSrcAlpha = srcAlpha; - bindings.blendDstRGB = dstRGB; - bindings.blendDstAlpha = dstAlpha; - } - this.uniform2fv = function(location, data) { - if (!location) return; - commandBuffer.push(74, location.id, new Float32Array(data)); - }; - this.texParameterf = function(target, pname, param) { - commandBuffer.push(75, target, pname, param); - }; - this.isContextLost = function() { - // optimisticaly return that everything is ok; client will abort on an actual context loss. we assume an error-free async workflow - commandBuffer.push(76); - return false; - }; - this.isProgram = function(program) { - return program && program.what === 'program'; - }; - this.blendEquationSeparate = function(rgb, alpha) { - commandBuffer.push(77, rgb, alpha); - bindings.blendEquationRGB = rgb; - bindings.blendEquationAlpha = alpha; - }; - this.stencilFuncSeparate = function(face, func, ref, mask) { - commandBuffer.push(78, face, func, ref, mask); - }; - this.stencilOpSeparate = function(face, fail, zfail, zpass) { - commandBuffer.push(79, face, fail, zfail, zpass); - }; - this.drawBuffersWEBGL = function(buffers) { - commandBuffer.push(80, buffers); - }; - this.uniform1iv = function(location, data) { - if (!location) return; - commandBuffer.push(81, location.id, new Int32Array(data)); - }; - this.uniform1fv = function(location, data) { - if (!location) return; - commandBuffer.push(82, location.id, new Float32Array(data)); - }; - - // Setup - - var theoreticalTracker = new FPSTracker('server (theoretical)'); - var throttledTracker = new FPSTracker('server (client-throttled)'); - - function preRAF() { - //theoreticalTracker.tick(); - // if too many frames in queue, skip a main loop iter - if (Math.abs(frameId - clientFrameId) >= 4) { - return false; - } - //throttledTracker.tick(); - } - - var postRAFed = false; - - function postRAF() { - if (commandBuffer.length > 0) { - postMessage({ target: 'gl', op: 'render', commandBuffer: commandBuffer }); - commandBuffer = []; - } - postRAFed = true; - } - - assert(!Browser.doSwapBuffers); - Browser.doSwapBuffers = postRAF; - - var trueRAF = window.requestAnimationFrame; - window.requestAnimationFrame = (func) => { - trueRAF(() => { - if (preRAF() === false) { - window.requestAnimationFrame(func); // skip this frame, do it later - return; - } - postRAFed = false; - func(); - if (!postRAFed) { // if we already posted this frame (e.g. from doSwapBuffers) do not post again - postRAF(); - } - }); - } - -} - -// share prefetched data among all instances - -WebGLWorker.prototype.prefetchedParameters = {}; -WebGLWorker.prototype.prefetchedExtensions = {}; -WebGLWorker.prototype.prefetchedPrecisions = {}; - diff --git a/test/browser/test_keydown_preventdefault_proxy.c b/test/browser/test_keydown_preventdefault_proxy.c deleted file mode 100644 index 00efc4d34ed6e..0000000000000 --- a/test/browser/test_keydown_preventdefault_proxy.c +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2015 The Emscripten Authors. All rights reserved. -// Emscripten is available under two separate licenses, the MIT license and the -// University of Illinois/NCSA Open Source License. Both these licenses can be -// found in the LICENSE file. - -#include -#include -#include -#include -#include - -static int result = 1; - -// When running PROXY_TO_WORKER mode that return code of key event handlers -// is not honored (since the handlers are run asyncronously in the worker). -// Instead `shouldPreventDefault` in `proxyClient.js` returns true for all keys -// except backspace and tab. -// -// Therefore where we expect the keypress callback to be prevented for '\b' -// but not for 'A'. - -bool keydown_callback(int eventType, const EmscriptenKeyboardEvent *e, void *userData) { - printf("got keydown: %d\n", e->keyCode); - if ((e->keyCode == 'A') || (e->keyCode == '\b')) { - result *= 2; - } else { - printf("done: result=%d\n", result); - emscripten_force_exit(result); - } - return 0; -} - -bool keypress_callback(int eventType, const EmscriptenKeyboardEvent *e, void *userData) { - printf("got keypress: %d\n", e->keyCode); - // preventDefault should have been set for the backspace key so we should - // never get that here. - assert(e->keyCode != '\b'); - result *= 3; - return 0; -} - -bool keyup_callback(int eventType, const EmscriptenKeyboardEvent *e, void *userData) { - printf("got keyup: %d\n", e->keyCode); - if ((e->keyCode == 'A') || (e->keyCode == '\b')) { - result *= 5; - } - return 0; -} - -int main(int argc, char **argv) { - printf("in main\n"); - - emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, 0, 1, keydown_callback); - emscripten_set_keypress_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, 0, 1, keypress_callback); - emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, 0, 1, keyup_callback); - - emscripten_runtime_keepalive_push(); - return 0; -} - diff --git a/test/custom_messages_proxy_postjs.js b/test/custom_messages_proxy_postjs.js deleted file mode 100644 index 1ae8d29d4aa45..0000000000000 --- a/test/custom_messages_proxy_postjs.js +++ /dev/null @@ -1,30 +0,0 @@ -var customMessageData = ''; - -Module.onCustomMessage = function (message) { - var data = message.data.userData; - switch (data.op) { - case 'preMainCustomMessage': { - customMessageData += data.data; - break; - } - case 'runMain': { - postCustomMessage({ op: 'runningMain', data: customMessageData }); - removeRunDependency('Custom Message Init'); - break; - } - case 'postMainCustomMessage': { - customMessageData += data.data; - break; - } - case 'finish': { - postCustomMessage({ op: 'finishing', data: customMessageData + '[finish]' }); - break; - } - default: { - throw 'unknown custom message'; - } - } - -} - -addRunDependency('Custom Message Init'); diff --git a/test/custom_messages_proxy_shell.html b/test/custom_messages_proxy_shell.html deleted file mode 100644 index 71580d9bda550..0000000000000 --- a/test/custom_messages_proxy_shell.html +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - Custom messaging proxy test - - -
- -
- - - {{{ SCRIPT }}} - - - diff --git a/test/test_browser.py b/test/test_browser.py index 224fd4af8976b..5873b92b6f5fa 100644 --- a/test/test_browser.py +++ b/test/test_browser.py @@ -1,4 +1,4 @@ -# Copyright 2013 The Emscripten Authors. All rights reserved. +# Copyright 2013 The Emscripten Authors. All rights reserved. # Emscripten is available under two separate licenses, the MIT license and the # University of Illinois/NCSA Open Source License. Both these licenses can be # found in the LICENSE file. @@ -66,7 +66,7 @@ from tools import ports, shared from tools.feature_matrix import UNSUPPORTED -from tools.shared import DEBUG, EMCC, FILE_PACKAGER, PIPE, WINDOWS +from tools.shared import EMCC, FILE_PACKAGER, PIPE, WINDOWS from tools.utils import delete_dir, memoize @@ -124,33 +124,6 @@ def do_GET(s): return HTTPServer(('localhost', 11111), ChunkedServerHandler) -def also_with_proxying(f): - assert callable(f) - - @wraps(f) - def metafunc(self, proxied, *args, **kwargs): - if DEBUG: - print('parameterize:proxied=%d' % proxied) - if proxied: - self.proxy_to_worker() - f(self, *args, **kwargs) - - parameterize(metafunc, {'': (False,), - 'proxied': (True,)}) - return metafunc - - -def proxied(f): - assert callable(f) - - @wraps(f) - def decorated(self, *args, **kwargs): - self.proxy_to_worker() - return f(self, *args, **kwargs) - - return decorated - - # This is similar to @core.no_wasmfs, but it disable WasmFS and runs the test # normally. That is, in core we skip the test if we are in the wasmfs.* mode, # while in browser we don't have such modes, so we force the test to run without @@ -282,9 +255,6 @@ def setUpClass(cls): print('Running the browser tests. Make sure the browser allows popups from localhost.') print() - def proxy_to_worker(self): - self.cflags += ['--proxy-to-worker', '-Wno-deprecated', '-sGL_TESTING'] - def require_jspi(self): if not is_chrome(): self.skipTest(f'Current browser ({common.EMTEST_BROWSER}) does not support JSPI. Only chromium-based browsers ({CHROMIUM_BASED_BROWSERS}) support JSPI today.') @@ -325,14 +295,8 @@ def reftest(self, filename, reference, reference_slack=0, *args, **kwargs): assert 'expected' not in kwargs expected = [str(i) for i in range(reference_slack + 1)] self.make_reftest(reference) - if '--proxy-to-worker' in self.cflags: - assert 'post_build' not in kwargs - kwargs['post_build'] = self.post_manual_reftest - create_file('fakereftest.js', 'var reftestUnblock = () => {}; var reftestBlock = () => {};') - kwargs['cflags'] += ['--pre-js', 'fakereftest.js'] - else: - kwargs.setdefault('cflags', []) - kwargs['cflags'] += ['--pre-js', 'reftest.js', '-sGL_TESTING'] + kwargs.setdefault('cflags', []) + kwargs['cflags'] += ['--pre-js', 'reftest.js', '-sGL_TESTING'] try: return self.btest(filename, expected=expected, *args, **kwargs) @@ -902,7 +866,6 @@ def test_sdl_image_webp(self): ]) @also_with_wasmfs - @also_with_proxying def test_sdl_image_prepare(self): # load an image file, get pixel data. shutil.copy(test_file('screenshot.jpg'), 'screenshot.not') @@ -967,21 +930,6 @@ def test_sdl_stb_image_cleanup(self): def test_sdl_canvas(self, args): self.btest_exit('test_sdl_canvas.c', cflags=['-sLEGACY_GL_EMULATION', '-lSDL', '-lGL'] + args) - @proxied - def test_sdl_canvas_proxy(self): - create_file('data.txt', 'datum') - self.reftest('test_sdl_canvas_proxy.c', 'test_sdl_canvas_proxy.png', cflags=['--proxy-to-worker', '-Wno-deprecated', '--preload-file', 'data.txt', '-lSDL', '-lGL']) - - @requires_graphics_hardware - @flaky('https://github.com/emscripten-core/emscripten/issues/25329') - def test_glgears_proxy_jstarget(self): - # test .js target with --proxy-worker; emits 2 js files, client and worker - self.compile_btest('hello_world_gles_proxy.c', ['-o', 'test.js', '--proxy-to-worker', '-Wno-deprecated', '-sGL_TESTING', '-lGL', '-lglut']) - shell_with_script('shell_minimal.html', 'test.html', '') - self.make_reftest(test_file('gears.png')) - self.post_manual_reftest() - self.run_browser('test.html', '/report_result?0') - def test_sdl_canvas_alpha(self): # N.B. On Linux with Intel integrated graphics cards, this test needs Firefox 49 or newer. # See https://github.com/emscripten-core/emscripten/issues/4069. @@ -1024,63 +972,9 @@ def test_sdl_key(self, defines, async_, delay): ''' % (settimeout_start, settimeout_end, settimeout_start, settimeout_end)) self.btest_exit('test_sdl_key.c', 223092870, cflags=defines + async_ + ['--pre-js', test_file('browser/fake_events.js'), '--pre-js=pre.js', '-lSDL', '-lGL']) - def test_sdl_key_proxy(self): - shutil.copy(test_file('browser/fake_events.js'), '.') - create_file('pre.js', ''' - Module.postRun = () => { - function doOne() { - Module._one(); - setTimeout(doOne, 1000/60); - } - setTimeout(doOne, 1000/60); - } - ''') - - def post(): - html = read_file('test.html') - html = html.replace('', ''' - - -''') - create_file('test.html', html) - - self.btest_exit('test_sdl_key_proxy.c', 223092870, cflags=['--proxy-to-worker', '-Wno-deprecated', '--pre-js', 'pre.js', '-lSDL', '-lGL', '-sRUNTIME_DEBUG'], post_build=post) - def test_canvas_focus(self): self.btest_exit('test_canvas_focus.c', cflags=['--pre-js', test_file('browser/fake_events.js')]) - def test_keydown_preventdefault_proxy(self): - def post(): - html = read_file('test.html') - html = html.replace('', ''' - - -''') - - create_file('test.html', html) - - shutil.copy(test_file('browser/fake_events.js'), '.') - self.btest_exit('browser/test_keydown_preventdefault_proxy.c', 300, cflags=['--proxy-to-worker', '-Wno-deprecated'], post_build=post) - def test_sdl_text(self): create_file('pre.js', ''' Module.postRun = () => { @@ -1787,13 +1681,8 @@ def test_glgears_pthreads(self, extra_args=[]): # noqa self.test_glgears(['-pthread']) @requires_graphics_hardware - @parameterized({ - '': ([],), - # Enabling FULL_ES3 also enables ES2 automatically - 'proxy': (['--proxy-to-worker', '-Wno-deprecated'],), - }) - def test_glgears_long(self, args): - args += ['-DHAVE_BUILTIN_SINCOS', '-DLONGTEST', '-lGL', '-lglut', '-DANIMATE'] + def test_glgears_long(self): + args = ['-DHAVE_BUILTIN_SINCOS', '-DLONGTEST', '-lGL', '-lglut', '-DANIMATE'] self.btest('hello_world_gles.c', expected='0', cflags=args) @requires_graphics_hardware @@ -1966,7 +1855,6 @@ def test_emscripten_main_loop_and_blocker_exit(self): @parameterized({ '': ([],), - 'worker': (['--proxy-to-worker', '-Wno-deprecated'],), 'pthreads': (['-pthread', '-sPROXY_TO_PTHREAD'],), 'strict': (['-sSTRICT'],), }) @@ -2005,7 +1893,6 @@ def test_sdl_glshader(self): self.reftest('test_sdl_glshader.c', 'test_sdl_glshader.png', cflags=['-O2', '--closure=1', '-sLEGACY_GL_EMULATION', '-lGL', '-lSDL', '-sGL_ENABLE_GET_PROC_ADDRESS']) @requires_graphics_hardware - @also_with_proxying def test_sdl_glshader2(self): self.btest_exit('test_sdl_glshader2.c', cflags=['-sLEGACY_GL_EMULATION', '-lGL', '-lSDL', '-sGL_ENABLE_GET_PROC_ADDRESS']) @@ -2040,7 +1927,6 @@ def test_gl_ps_strides(self): self.reftest('gl_ps_strides.c', 'gl_ps_strides.png', cflags=['--preload-file', 'screenshot.png', '-sLEGACY_GL_EMULATION', '-lGL', '-lSDL', '--use-preload-plugins']) @requires_graphics_hardware - @also_with_proxying def test_gl_ps_worker(self): shutil.copy(test_file('screenshot.png'), '.') self.reftest('gl_ps_worker.c', 'gl_ps.png', cflags=['--preload-file', 'screenshot.png', '-sLEGACY_GL_EMULATION', '-lGL', '-lSDL', '--use-preload-plugins'], reference_slack=1) @@ -2064,7 +1950,6 @@ def test_gl_vertex_buffer(self): self.reftest('gl_vertex_buffer.c', 'gl_vertex_buffer.png', cflags=['-sGL_UNSAFE_OPTS=0', '-sLEGACY_GL_EMULATION', '-lGL', '-lSDL'], reference_slack=1) @requires_graphics_hardware - @also_with_proxying def test_gles2_uniform_arrays(self): self.btest_exit('test_gles2_uniform_arrays.c', cflags=['-sGL_ASSERTIONS', '-lGL', '-lSDL']) @@ -2096,25 +1981,19 @@ def test_cubegeom_pre2(self): def test_cubegeom_pre3(self): self.reftest('third_party/cubegeom/cubegeom_pre3.c', 'third_party/cubegeom/cubegeom_pre2.png', cflags=['-sLEGACY_GL_EMULATION', '-lGL', '-lSDL']) - @also_with_proxying @parameterized({ '': ([],), 'tracing': (['-sTRACE_WEBGL_CALLS'],), }) @requires_graphics_hardware def test_cubegeom(self, args): - if '--proxy-to-worker' in self.cflags and args: - # proxy only in the simple, normal case (we can't trace GL calls when proxied) - self.skipTest('tracing + proxying not supported') self.reftest('third_party/cubegeom/cubegeom.c', 'third_party/cubegeom/cubegeom.png', cflags=['-O2', '-g', '-sLEGACY_GL_EMULATION', '-lGL', '-lSDL'] + args) @requires_graphics_hardware - @also_with_proxying def test_cubegeom_regal(self): self.reftest('third_party/cubegeom/cubegeom.c', 'third_party/cubegeom/cubegeom.png', cflags=['-O2', '-g', '-DUSE_REGAL', '-sUSE_REGAL', '-lGL', '-lSDL', '-lc++', '-lc++abi']) @requires_graphics_hardware - @also_with_proxying def test_cubegeom_regal_pthread(self): self.reftest('third_party/cubegeom/cubegeom.c', 'third_party/cubegeom/cubegeom.png', cflags=['-O2', '-g', '-pthread', '-DUSE_REGAL', '-pthread', '-sUSE_REGAL', '-lGL', '-lSDL', '-lc++', '-lc++abi']) @@ -2150,12 +2029,10 @@ def test_cubegeom_color(self): self.reftest('third_party/cubegeom/cubegeom_color.c', 'third_party/cubegeom/cubegeom_color.png', cflags=['-sLEGACY_GL_EMULATION', '-lGL', '-lSDL']) @requires_graphics_hardware - @also_with_proxying def test_cubegeom_normal(self): self.reftest('third_party/cubegeom/cubegeom_normal.c', 'third_party/cubegeom/cubegeom_normal.png', cflags=['-sLEGACY_GL_EMULATION', '-lGL', '-lSDL']) @requires_graphics_hardware - @also_with_proxying def test_cubegeom_normal_dap(self): # draw is given a direct pointer to clientside memory, no element array buffer self.reftest('third_party/cubegeom/cubegeom_normal_dap.c', 'third_party/cubegeom/cubegeom_normal.png', cflags=['-sLEGACY_GL_EMULATION', '-lGL', '-lSDL']) @@ -2181,7 +2058,6 @@ def test_cubegeom_mt(self): self.reftest('third_party/cubegeom/cubegeom_mt.c', 'third_party/cubegeom/cubegeom_mt.png', cflags=['-sLEGACY_GL_EMULATION', '-lGL', '-lSDL']) # multitexture @requires_graphics_hardware - @also_with_proxying def test_cubegeom_color2(self): self.reftest('third_party/cubegeom/cubegeom_color2.c', 'third_party/cubegeom/cubegeom_color2.png', cflags=['-sLEGACY_GL_EMULATION', '-lGL', '-lSDL']) @@ -2227,7 +2103,6 @@ def test_cubegeom_u4fv_2(self): self.reftest('third_party/cubegeom/cubegeom_u4fv_2.c', 'third_party/cubegeom/cubegeom_u4fv_2.png', cflags=['-sLEGACY_GL_EMULATION', '-lGL', '-lSDL']) @requires_graphics_hardware - @also_with_proxying def test_cube_explosion(self): self.reftest('cube_explosion.c', 'cube_explosion.png', cflags=['-sLEGACY_GL_EMULATION', '-lGL', '-lSDL']) @@ -3122,11 +2997,8 @@ def test_sdl2_threads(self): self.btest_exit('test_sdl2_threads.c', cflags=['-pthread', '-sUSE_SDL=2', '-sPROXY_TO_PTHREAD']) @requires_graphics_hardware - @also_with_proxying def test_sdl2_glshader(self): - if '--proxy-to-worker' not in self.cflags: - # closure build current fails on proxying - self.cflags += ['--closure=1', '-g1'] + self.cflags += ['--closure=1', '-g1'] self.reftest('test_sdl2_glshader.c', 'test_sdl_glshader.png', cflags=['-sUSE_SDL=2', '-sLEGACY_GL_EMULATION']) @requires_graphics_hardware @@ -3178,12 +3050,6 @@ def test_sdl2_image_prepare_data(self): shutil.copy(test_file('screenshot.jpg'), 'screenshot.not') self.reftest('test_sdl2_image_prepare_data.c', 'screenshot.jpg', cflags=['--preload-file', 'screenshot.not', '-sUSE_SDL=2', '-sUSE_SDL_IMAGE=2']) - @requires_graphics_hardware - @proxied - def test_sdl2_canvas_proxy(self): - create_file('data.txt', 'datum') - self.reftest('test_sdl2_canvas_proxy.c', 'test_sdl2_canvas.png', cflags=['-sUSE_SDL=2', '--proxy-to-worker', '-Wno-deprecated', '--preload-file', 'data.txt']) - def test_sdl2_pumpevents(self): # key events should be detected using SDL_PumpEvents self.btest_exit('test_sdl2_pumpevents.c', cflags=['--pre-js', test_file('browser/fake_events.js'), '-sUSE_SDL=2']) @@ -3255,11 +3121,6 @@ def test_sdl2_unwasteful(self): def test_sdl2_canvas_write(self): self.btest_exit('test_sdl2_canvas_write.c', cflags=['-sUSE_SDL=2']) - @requires_graphics_hardware - @proxied - def test_sdl2_gl_frames_swap(self): - self.reftest('test_sdl2_gl_frames_swap.c', 'test_sdl2_gl_frames_swap.png', cflags=['--proxy-to-worker', '-Wno-deprecated', '-sUSE_SDL=2']) - @requires_graphics_hardware def test_sdl2_ttf(self): shutil.copy2(test_file('freetype/LiberationSansBold.ttf'), self.get_dir()) @@ -3593,7 +3454,6 @@ def test_webidl(self, args): self.btest('webidl/test.cpp', '1', cflags=['--post-js', 'glue.js', '-I.', '-DBROWSER'] + args) @no_wasm64('https://github.com/llvm/llvm-project/issues/98778') - @also_with_proxying def test_dylink(self): create_file('main.c', r''' #include @@ -3633,11 +3493,7 @@ def test_dlopen_blocking(self): # verify that dynamic linking works in all kinds of in-browser environments. # don't mix different kinds in a single test. - @parameterized({ - '': ([0],), - 'inworker': ([1],), - }) - def test_dylink_dso_needed(self, inworker): + def test_dylink_dso_needed(self): self.cflags += ['-O2'] def do_run(src, expected_output, cflags): @@ -3668,9 +3524,6 @@ def do_run(src, expected_output, cflags): return rtn; } ''' % expected_output) - # --proxy-to-worker only on main - if inworker: - cflags += ['--proxy-to-worker', '-Wno-deprecated'] self.btest_exit('test_dylink_dso_needed.c', cflags=['--post-js', 'post.js'] + cflags) self._test_dylink_dso_needed(do_run) @@ -4243,25 +4096,6 @@ def test_main_thread_em_asm_blocking(self): def test_sigalrm(self): self.btest_exit('test_sigalrm.c', cflags=['-O3']) - def test_canvas_style_proxy(self): - self.btest('canvas_style_proxy.c', expected='1', cflags=['--proxy-to-worker', '-Wno-deprecated', '--shell-file', test_file('canvas_style_proxy_shell.html'), '--pre-js', test_file('canvas_style_proxy_pre.js')]) - - def test_canvas_size_proxy(self): - self.btest('canvas_size_proxy.c', expected='0', cflags=['--proxy-to-worker', '-Wno-deprecated']) - - def test_custom_messages_proxy(self): - self.btest('custom_messages_proxy.c', expected='1', cflags=['--proxy-to-worker', '-Wno-deprecated', '--shell-file', test_file('custom_messages_proxy_shell.html'), '--post-js', test_file('custom_messages_proxy_postjs.js')]) - - @parameterized({ - '': ([],), - 'O1': (['-O1'],), - 'O2': (['-O2'],), - }) - def test_vanilla_html_when_proxying(self, args): - self.compile_btest('browser_test_hello_world.c', ['-o', 'test.js', '--proxy-to-worker', '-Wno-deprecated'] + args) - create_file('test.html', '') - self.run_browser('test.html', '/report_result?0') - @parameterized({ '': ([], 1), 'O1': (['-O1'], 1), @@ -4650,13 +4484,6 @@ def test_fetch_sync(self): shutil.copy(test_file('gears.png'), '.') self.btest_exit('fetch/test_fetch_sync.c', cflags=['-sFETCH', '-pthread', '-sPROXY_TO_PTHREAD']) - # Tests that the Fetch API works for synchronous XHRs when used with --proxy-to-worker. - @no_firefox('https://github.com/emscripten-core/emscripten/issues/16868') - @also_with_wasm2js - def test_fetch_sync_xhr_in_proxy_to_worker(self): - shutil.copy(test_file('gears.png'), '.') - self.btest_exit('fetch/test_fetch_sync_xhr.cpp', cflags=['-sFETCH_DEBUG', '-sFETCH', '--proxy-to-worker', '-Wno-deprecated']) - @disabled('https://github.com/emscripten-core/emscripten/issues/16746') def test_fetch_idb_store(self): self.btest_exit('fetch/test_fetch_idb_store.cpp', cflags=['-pthread', '-sFETCH', '-sPROXY_TO_PTHREAD']) @@ -4862,7 +4689,6 @@ def test_mainScriptUrlOrBlob(self, es6, use_blob): self.run_browser('hello_thread_with_loader.html', '/report_result?exit:0') # Tests that SINGLE_FILE works as intended in generated HTML (with and without Worker) - @also_with_proxying def test_single_file_html(self): self.btest('single_file_static_initializer.cpp', '19', cflags=['-sSINGLE_FILE']) self.assertExists('test.html') @@ -4911,14 +4737,6 @@ def test_single_file_locate_file(self): self.run_browser('test.html', '/report_result?0') - # Tests that SINGLE_FILE works as intended in a Worker in JS output - def test_single_file_worker_js(self): - self.compile_btest('browser_test_hello_world.c', ['-o', 'test.js', '--proxy-to-worker', '-Wno-deprecated', '-sSINGLE_FILE']) - create_file('test.html', '') - self.run_browser('test.html', '/report_result?0') - self.assertExists('test.js') - self.assertNotExists('test.worker.js') - # Tests that pthreads code works as intended in a Worker. That is, a pthreads-using # program can run either on the main thread (normal tests) or when we start it in # a Worker in this test (in that case, both the main application thread and the worker @@ -5021,7 +4839,6 @@ def test_emscripten_request_animation_frame(self): def test_emscripten_request_animation_frame_loop(self): self.btest_exit('emscripten_request_animation_frame_loop.c') - @also_with_proxying def test_request_animation_frame(self): self.btest_exit('test_request_animation_frame.c') diff --git a/tools/cmdline.py b/tools/cmdline.py index c115d1b953b0f..e63e29c27732a 100644 --- a/tools/cmdline.py +++ b/tools/cmdline.py @@ -489,7 +489,7 @@ def consume_arg_file(): elif check_arg('--memory-init-file'): exit_with_error('--memory-init-file is no longer supported') elif check_flag('--proxy-to-worker'): - settings_changes.append('PROXY_TO_WORKER=1') + exit_with_error('--proxy-to-worker is no longer supported') elif check_arg('--valid-abspath'): options.valid_abspaths.append(consume_arg()) elif check_flag('--separate-asm'): diff --git a/tools/link.py b/tools/link.py index 26e647c5e04bd..561fbdf5dafef 100644 --- a/tools/link.py +++ b/tools/link.py @@ -1138,7 +1138,7 @@ def limit_incoming_module_api(): settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$ExitStatus'] # Certain configurations require the removeRunDependency/addRunDependency system. - if settings.LOAD_SOURCE_MAP or settings.PROXY_TO_WORKER or (settings.WASM_ASYNC_COMPILATION and not settings.MODULARIZE): + if settings.LOAD_SOURCE_MAP or (settings.WASM_ASYNC_COMPILATION and not settings.MODULARIZE): settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$addRunDependency', '$removeRunDependency'] if settings.ABORT_ON_WASM_EXCEPTIONS or settings.SPLIT_MODULE: @@ -1396,7 +1396,7 @@ def limit_incoming_module_api(): if settings.SIDE_MODULE and 'GLOBAL_BASE' in user_settings: diagnostics.warning('unused-command-line-argument', 'GLOBAL_BASE is not compatible with SIDE_MODULE') - if settings.PROXY_TO_WORKER or options.use_preload_plugins: + if options.use_preload_plugins: settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$Browser'] if not settings.BOOTSTRAPPING_STRUCT_INFO: @@ -2252,8 +2252,6 @@ def phase_final_emitting(options, target, js_target, wasm_target): if options.oformat == OFormat.HTML: generate_html(target, options, js_target, target_basename, wasm_target) - elif settings.PROXY_TO_WORKER: - generate_worker_js(target, options, js_target, target_basename) if settings.SPLIT_MODULE: diagnostics.warning('experimental', 'the SPLIT_MODULE setting is experimental and subject to change') @@ -2487,8 +2485,7 @@ def module_export_name_substitution(): save_intermediate('module_export_name_substitution') -def generate_traditional_runtime_html(target, options, js_target, target_basename, - wasm_target): +def generate_traditional_runtime_html(target, options, js_target, wasm_target): script = ScriptSource() if settings.EXPORT_NAME != 'Module' and options.shell_path == DEFAULT_SHELL_HTML: @@ -2499,23 +2496,13 @@ def generate_traditional_runtime_html(target, options, js_target, target_basenam shell = building.read_and_preprocess(options.shell_path) if '{{{ SCRIPT }}}' not in shell: exit_with_error('HTML shell must contain {{{ SCRIPT }}}, see src/shell.html for an example') - base_js_target = os.path.basename(js_target) - - if settings.PROXY_TO_WORKER: - proxy_worker_filename = (settings.PROXY_TO_WORKER_FILENAME or target_basename) + '.js' - script.inline = worker_js_script(proxy_worker_filename) - else: - # Normal code generation path - script.src = base_js_target - if settings.SINGLE_FILE: js_contents = script.inline or '' - if script.src: - js_contents += read_file(js_target) - script.src = None + js_contents += read_file(js_target) script.inline = read_file(js_target) delete_file(js_target) else: + script.src = os.path.basename(js_target) if not settings.WASM_ASYNC_COMPILATION: # We need to load the wasm file before anything else, since it # has be synchronously ready. @@ -2645,7 +2632,7 @@ def generate_html(target, options, js_target, target_basename, wasm_target): if settings.MINIMAL_RUNTIME: generate_minimal_runtime_html(target, options, js_target, target_basename) else: - generate_traditional_runtime_html(target, options, js_target, target_basename, wasm_target) + generate_traditional_runtime_html(target, options, js_target, wasm_target) if settings.MINIFY_HTML and (settings.OPT_LEVEL >= 1 or settings.SHRINK_LEVEL >= 1): minify_html(target) @@ -2653,20 +2640,6 @@ def generate_html(target, options, js_target, target_basename, wasm_target): utils.convert_line_endings_in_file(target, options.output_eol) -def generate_worker_js(target, options, js_target, target_basename): - if settings.SINGLE_FILE: - # compiler output is embedded as base64 data URL - proxy_worker_filename = get_subresource_location_js(js_target) - else: - # compiler output goes in .worker.js file - move_file(js_target, utils.replace_suffix(js_target, get_worker_js_suffix())) - worker_target_basename = target_basename + '.worker' - proxy_worker_filename = (settings.PROXY_TO_WORKER_FILENAME or worker_target_basename) + '.js' - - target_contents = worker_js_script(proxy_worker_filename) - utils.write_file(target, target_contents, options.output_eol) - - def worker_js_script(proxy_worker_filename): web_gl_client_src = read_file(utils.path_from_root('src/webGLClient.js')) proxy_client_src = building.read_and_preprocess(utils.path_from_root('src/proxyClient.js'), expand_macros=True) diff --git a/tools/settings.py b/tools/settings.py index b315e9e82fe6c..c40973419a81c 100644 --- a/tools/settings.py +++ b/tools/settings.py @@ -124,8 +124,6 @@ 'ASYNCIFY_EXPORTS': 'please use JSPI_EXPORTS instead', 'LINKABLE': 'under consideration for removal (https://github.com/emscripten-core/emscripten/issues/25262)', 'RELOCATABLE': ' under consideration for removal (https://github.com/emscripten-core/emscripten/issues/25262)', - 'PROXY_TO_WORKER': 'under consideration for removal (See https://github.com/emscripten-core/emscripten/issues/25440)', - 'PROXY_TO_WORKER_FILENAME': 'under consideration for removal (See https://github.com/emscripten-core/emscripten/issues/25440)', } # Settings that don't need to be externalized when serializing to json because they @@ -253,6 +251,7 @@ ['USE_OFFSET_COVERTER', [0], 'No longer supported, not needed with modern v8 versions'], ['ASYNCIFY_LAZY_LOAD_CODE', [0], 'No longer supported'], ['USE_WEBGPU', [0], 'No longer supported; replaced by --use-port=emdawnwebgpu, which implements a newer (but incompatible) version of webgpu.h - see tools/ports/emdawnwebgpu.py'], + ['PROXY_TO_WORKER', [0], 'No longer supported'], ] user_settings: Dict[str, str] = {}