diff --git a/emscripten.py b/emscripten.py index 1d7fa919eca6c..cc0f71a7cceff 100644 --- a/emscripten.py +++ b/emscripten.py @@ -937,6 +937,8 @@ def create_pointer_conversion_wrappers(metadata): 'emscripten_proxy_finish': '_p', 'emscripten_proxy_execute_queue': '_p', '_emval_coro_resume': '_pp', + 'emscripten_main_runtime_thread_id': 'p', + '_emscripten_set_offscreencanvas_size_on_thread': '_pp__', } for function in settings.SIGNATURE_CONVERSIONS: diff --git a/src/generated_struct_info32.json b/src/generated_struct_info32.json index 1ce4ff12493eb..94cad3db229ce 100644 --- a/src/generated_struct_info32.json +++ b/src/generated_struct_info32.json @@ -207,7 +207,7 @@ "EM_FUNC_SIG_PARAM_F": 2, "EM_FUNC_SIG_PARAM_F2I": 5, "EM_FUNC_SIG_PARAM_I": 0, - "EM_FUNC_SIG_PARAM_I64": 1, + "EM_FUNC_SIG_PARAM_J": 1, "EM_HTML5_LONG_STRING_LEN_BYTES": 128, "EM_HTML5_MEDIUM_STRING_LEN_BYTES": 64, "EM_HTML5_SHORT_STRING_LEN_BYTES": 32, diff --git a/src/generated_struct_info64.json b/src/generated_struct_info64.json index 000837cfa450d..4695a2546c12b 100644 --- a/src/generated_struct_info64.json +++ b/src/generated_struct_info64.json @@ -207,7 +207,7 @@ "EM_FUNC_SIG_PARAM_F": 2, "EM_FUNC_SIG_PARAM_F2I": 5, "EM_FUNC_SIG_PARAM_I": 0, - "EM_FUNC_SIG_PARAM_I64": 1, + "EM_FUNC_SIG_PARAM_J": 1, "EM_HTML5_LONG_STRING_LEN_BYTES": 128, "EM_HTML5_MEDIUM_STRING_LEN_BYTES": 64, "EM_HTML5_SHORT_STRING_LEN_BYTES": 32, diff --git a/src/library_pthread.js b/src/library_pthread.js index 0f2d08f80a348..74224fbefaf99 100644 --- a/src/library_pthread.js +++ b/src/library_pthread.js @@ -23,6 +23,14 @@ #error "EVAL_CTORS is not compatible with pthreads yet (passive segments)" #endif +{{{ +#if MEMORY64 +globalThis.MAX_PTR = Number((2n ** 64n) - 1n); +#else +globalThis.MAX_PTR = (2 ** 32) - 1 +#endif +}}} + var LibraryPThread = { $PThread__postset: 'PThread.init();', $PThread__deps: ['_emscripten_thread_init', @@ -763,11 +771,12 @@ var LibraryPThread = { // Comma-delimited list of CSS selectors that must identify canvases by IDs: "#canvas1, #canvas2, ..." var transferredCanvasNames = attr ? {{{ makeGetValue('attr', C_STRUCTS.pthread_attr_t._a_transferredcanvases, '*') }}} : 0; #if OFFSCREENCANVASES_TO_PTHREAD - // Proxied canvases string pointer -1 is used as a special token to fetch - // whatever canvases were passed to build in -s - // OFFSCREENCANVASES_TO_PTHREAD= command line. - if (transferredCanvasNames == (-1 >>> 0)) transferredCanvasNames = '{{{ OFFSCREENCANVASES_TO_PTHREAD }}}'; - else + // Proxied canvases string pointer -1/MAX_PTR is used as a special token to + // fetch whatever canvases were passed to build in + // -sOFFSCREENCANVASES_TO_PTHREAD= command line. + if (transferredCanvasNames == {{{ MAX_PTR }}}) { + transferredCanvasNames = '{{{ OFFSCREENCANVASES_TO_PTHREAD }}}'; + } else #endif if (transferredCanvasNames) transferredCanvasNames = UTF8ToString(transferredCanvasNames).trim(); if (transferredCanvasNames) transferredCanvasNames = transferredCanvasNames.split(','); @@ -816,10 +825,10 @@ var LibraryPThread = { // Create a shared information block in heap so that we can control // the canvas size from any thread. if (!canvas.canvasSharedPtr) { - canvas.canvasSharedPtr = _malloc(12); + canvas.canvasSharedPtr = _malloc({{{ 8 + POINTER_SIZE }}}); {{{ makeSetValue('canvas.canvasSharedPtr', 0, 'canvas.width', 'i32') }}}; {{{ makeSetValue('canvas.canvasSharedPtr', 4, 'canvas.height', 'i32') }}}; - {{{ makeSetValue('canvas.canvasSharedPtr', 8, 0, 'i32') }}}; // pthread ptr to the thread that owns this canvas, filled in below. + {{{ makeSetValue('canvas.canvasSharedPtr', 8, 0, '*') }}}; // pthread ptr to the thread that owns this canvas, filled in below. } offscreenCanvasInfo = { offscreenCanvas: canvas.transferControlToOffscreen(), diff --git a/src/library_sigs.js b/src/library_sigs.js index adcfb09621fd2..8a543bec40021 100644 --- a/src/library_sigs.js +++ b/src/library_sigs.js @@ -669,7 +669,7 @@ sigs = { emscripten_idb_read_from_blob__sig: 'viiip', emscripten_idb_store__sig: 'vpppip', emscripten_idb_store_blob__sig: 'vpppip', - emscripten_is_webgl_context_lost__sig: 'ii', + emscripten_is_webgl_context_lost__sig: 'ip', emscripten_lazy_load_code__sig: 'v', emscripten_lock_async_acquire__sig: 'vpppd', emscripten_lock_orientation__sig: 'ii', @@ -850,21 +850,21 @@ sigs = { emscripten_wasm_worker_post_function_viii__sig: 'vipiii', emscripten_wasm_worker_self_id__sig: 'i', emscripten_webgl_commit_frame__sig: 'i', - emscripten_webgl_create_context__sig: 'ipp', - emscripten_webgl_destroy_context__sig: 'ii', + emscripten_webgl_create_context__sig: 'ppp', + emscripten_webgl_destroy_context__sig: 'ip', emscripten_webgl_do_commit_frame__sig: 'i', - emscripten_webgl_do_create_context__sig: 'ipp', - emscripten_webgl_do_get_current_context__sig: 'i', - emscripten_webgl_enable_ANGLE_instanced_arrays__sig: 'ii', - emscripten_webgl_enable_OES_vertex_array_object__sig: 'ii', - emscripten_webgl_enable_WEBGL_draw_buffers__sig: 'ii', - emscripten_webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance__sig: 'ii', - emscripten_webgl_enable_WEBGL_multi_draw__sig: 'ii', - emscripten_webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance__sig: 'ii', - emscripten_webgl_enable_extension__sig: 'iip', - emscripten_webgl_get_context_attributes__sig: 'iip', - emscripten_webgl_get_current_context__sig: 'i', - emscripten_webgl_get_drawing_buffer_size__sig: 'iipp', + emscripten_webgl_do_create_context__sig: 'ppp', + emscripten_webgl_do_get_current_context__sig: 'p', + emscripten_webgl_enable_ANGLE_instanced_arrays__sig: 'ip', + emscripten_webgl_enable_OES_vertex_array_object__sig: 'ip', + emscripten_webgl_enable_WEBGL_draw_buffers__sig: 'ip', + emscripten_webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance__sig: 'ip', + emscripten_webgl_enable_WEBGL_multi_draw__sig: 'ip', + emscripten_webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance__sig: 'ip', + emscripten_webgl_enable_extension__sig: 'ipp', + emscripten_webgl_get_context_attributes__sig: 'ipp', + emscripten_webgl_get_current_context__sig: 'p', + emscripten_webgl_get_drawing_buffer_size__sig: 'ippp', emscripten_webgl_get_parameter_d__sig: 'di', emscripten_webgl_get_parameter_i64v__sig: 'vip', emscripten_webgl_get_parameter_o__sig: 'ii', @@ -882,7 +882,7 @@ sigs = { emscripten_webgl_get_vertex_attrib_o__sig: 'iii', emscripten_webgl_get_vertex_attrib_v__sig: 'iiipii', emscripten_webgl_init_context_attributes__sig: 'vp', - emscripten_webgl_make_context_current__sig: 'ii', + emscripten_webgl_make_context_current__sig: 'ip', emscripten_webgpu_export_bind_group__sig: 'ip', emscripten_webgpu_export_bind_group_layout__sig: 'ip', emscripten_webgpu_export_buffer__sig: 'ip', diff --git a/src/library_webgl.js b/src/library_webgl.js index 9c4a155ebe031..cfde53ce6732d 100644 --- a/src/library_webgl.js +++ b/src/library_webgl.js @@ -991,15 +991,16 @@ for (/**@suppress{duplicate}*/var i = 0; i < {{{ GL_POOL_TEMP_BUFFERS_SIZE }}}; registerContext: (ctx, webGLContextAttributes) => { #if PTHREADS - // with pthreads a context is a location in memory with some synchronized data between threads - var handle = _malloc(8); + // with pthreads a context is a location in memory with some synchronized + // data between threads + var handle = _malloc({{{ 2 * POINTER_SIZE }}}); #if GL_ASSERTIONS assert(handle, 'malloc() failed in GL.registerContext!'); #endif #if GL_SUPPORT_EXPLICIT_SWAP_CONTROL - {{{ makeSetValue('handle', 0, 'webGLContextAttributes.explicitSwapControl', 'i32')}}}; // explicitSwapControl + {{{ makeSetValue('handle', 0, 'webGLContextAttributes.explicitSwapControl', 'i32')}}}; #endif - {{{ makeSetValue('handle', 4, '_pthread_self()', 'i32')}}}; // the thread pointer of the thread that owns the control of the context + {{{ makeSetValue('handle', POINTER_SIZE, '_pthread_self()', '*')}}}; // the thread pointer of the thread that owns the control of the context #else // PTHREADS // without pthreads a context is just an integer ID var handle = GL.getNewId(GL.contexts); @@ -1307,7 +1308,7 @@ for (/**@suppress{duplicate}*/var i = 0; i < {{{ GL_POOL_TEMP_BUFFERS_SIZE }}}; break; case 0x8DF8: // GL_SHADER_BINARY_FORMATS #if GL_TRACK_ERRORS - if (type != {{{ cDefs.EM_FUNC_SIG_PARAM_I }}} && type != {{{ cDefs.EM_FUNC_SIG_PARAM_I64 }}}) { + if (type != {{{ cDefs.EM_FUNC_SIG_PARAM_I }}} && type != {{{ cDefs.EM_FUNC_SIG_PARAM_J }}}) { GL.recordError(0x500); // GL_INVALID_ENUM #if GL_ASSERTIONS err(`GL_INVALID_ENUM in glGet${type}v(GL_SHADER_BINARY_FORMATS): Invalid parameter type!`); @@ -1464,7 +1465,7 @@ for (/**@suppress{duplicate}*/var i = 0; i < {{{ GL_POOL_TEMP_BUFFERS_SIZE }}}; } switch (type) { - case {{{ cDefs.EM_FUNC_SIG_PARAM_I64 }}}: writeI53ToI64(p, ret); break; + case {{{ cDefs.EM_FUNC_SIG_PARAM_J }}}: writeI53ToI64(p, ret); break; case {{{ cDefs.EM_FUNC_SIG_PARAM_I }}}: {{{ makeSetValue('p', '0', 'ret', 'i32') }}}; break; case {{{ cDefs.EM_FUNC_SIG_PARAM_F }}}: {{{ makeSetValue('p', '0', 'ret', 'float') }}}; break; case {{{ cDefs.EM_FUNC_SIG_PARAM_B }}}: {{{ makeSetValue('p', '0', 'ret ? 1 : 0', 'i8') }}}; break; diff --git a/src/library_webgl2.js b/src/library_webgl2.js index b854312ad3ac9..c972f726c3a1e 100644 --- a/src/library_webgl2.js +++ b/src/library_webgl2.js @@ -45,7 +45,7 @@ var LibraryWebGL2 = { glGetInteger64v__deps: ['$emscriptenWebGLGet'], glGetInteger64v: (name_, p) => { - emscriptenWebGLGet(name_, p, {{{ cDefs.EM_FUNC_SIG_PARAM_I64 }}}); + emscriptenWebGLGet(name_, p, {{{ cDefs.EM_FUNC_SIG_PARAM_J }}}); }, glGetInternalformativ: (target, internalformat, pname, bufSize, params) => { @@ -456,7 +456,7 @@ var LibraryWebGL2 = { } switch (type) { - case {{{ cDefs.EM_FUNC_SIG_PARAM_I64 }}}: writeI53ToI64(data, ret); break; + case {{{ cDefs.EM_FUNC_SIG_PARAM_J }}}: writeI53ToI64(data, ret); break; case {{{ cDefs.EM_FUNC_SIG_PARAM_I }}}: {{{ makeSetValue('data', '0', 'ret', 'i32') }}}; break; case {{{ cDefs.EM_FUNC_SIG_PARAM_F }}}: {{{ makeSetValue('data', '0', 'ret', 'float') }}}; break; case {{{ cDefs.EM_FUNC_SIG_PARAM_B }}}: {{{ makeSetValue('data', '0', 'ret ? 1 : 0', 'i8') }}}; break; @@ -470,7 +470,7 @@ var LibraryWebGL2 = { glGetInteger64i_v__deps: ['$emscriptenWebGLGetIndexed'], glGetInteger64i_v: (target, index, data) => - emscriptenWebGLGetIndexed(target, index, data, {{{ cDefs.EM_FUNC_SIG_PARAM_I64 }}}), + emscriptenWebGLGetIndexed(target, index, data, {{{ cDefs.EM_FUNC_SIG_PARAM_J }}}), // Uniform Buffer objects glBindBufferBase: (target, index, buffer) => { diff --git a/src/struct_info.json b/src/struct_info.json index 9f9aaa4c9194c..72356980b849f 100644 --- a/src/struct_info.json +++ b/src/struct_info.json @@ -951,7 +951,7 @@ "file": "emscripten/threading.h", "defines": [ "EM_FUNC_SIG_PARAM_I", - "EM_FUNC_SIG_PARAM_I64", + "EM_FUNC_SIG_PARAM_J", "EM_FUNC_SIG_PARAM_F", "EM_FUNC_SIG_PARAM_D", "EM_FUNC_SIG_PARAM_B", diff --git a/src/threadprofiler.js b/src/threadprofiler.js index 4cf2de3bbda5b..4aa35a7427b85 100644 --- a/src/threadprofiler.js +++ b/src/threadprofiler.js @@ -44,12 +44,12 @@ var emscriptenThreadProfiler = { var profilerBlock = Atomics.load(HEAPU32, (threadPtr + 8 /* {{{ C_STRUCTS.pthread.profilerBlock }}}*/) >> 2); var threadName = PThread.getThreadName(threadPtr); if (threadName) { - threadName = '"' + threadName + '" (' + ptrToString(threadPtr) + ')'; + threadName = `"${threadName}" (${ptrToString(threadPtr)})`; } else { - threadName = '(' + ptrToString(threadPtr) + ')'; + threadName = `(${ptrToString(threadPtr)}})`; } - console.log('Thread ' + threadName + ' now: ' + PThread.threadStatusAsString(threadPtr) + '. '); + console.log(`Thread ${threadName} now: ${PThread.threadStatusAsString(threadPtr)}. `); } }, @@ -72,19 +72,20 @@ var emscriptenThreadProfiler = { var profilerBlock = Atomics.load(HEAPU32, (threadPtr + 8 /* {{{ C_STRUCTS.pthread.profilerBlock }}}*/) >> 2); var threadName = PThread.getThreadName(threadPtr); if (threadName) { - threadName = '"' + threadName + '" (' + ptrToString(threadPtr) + ')'; + threadName = `"${threadName}" (${ptrToString(threadPtr)})`; } else { - threadName = '(' + ptrToString(threadPtr) + ')'; + threadName = `(${ptrToString(threadPtr)})`; } - str += 'Thread ' + threadName + ' now: ' + PThread.threadStatusAsString(threadPtr) + '. '; + str += `Thread ${threadName} now: ${PThread.threadStatusAsString(threadPtr)}. `; var threadTimesInStatus = []; var totalTime = 0; - for (var j = 0; j < 7/*EM_THREAD_STATUS_NUMFIELDS*/; ++j) { - threadTimesInStatus.push(HEAPF64[((profilerBlock + 16/*C_STRUCTS.thread_profiler_block.timeSpentInStatus*/) >> 3) + j]); + var offset = profilerBlock + 16/*C_STRUCTS.thread_profiler_block.timeSpentInStatus*/; + for (var j = 0; j < 7/*EM_THREAD_STATUS_NUMFIELDS*/; ++j, offset += 8) { + threadTimesInStatus.push(Number(getValue(offset, 'double'))); totalTime += threadTimesInStatus[j]; - HEAPF64[((profilerBlock + 16/*C_STRUCTS.thread_profiler_block.timeSpentInStatus*/) >> 3) + j] = 0; + setValue(offset, 0, 'double'); } var recent = ''; if (threadTimesInStatus[1] > 0) recent += (threadTimesInStatus[1] / totalTime * 100.0).toFixed(1) + '% running. '; @@ -92,7 +93,7 @@ var emscriptenThreadProfiler = { if (threadTimesInStatus[3] > 0) recent += (threadTimesInStatus[3] / totalTime * 100.0).toFixed(1) + '% waiting for futex. '; if (threadTimesInStatus[4] > 0) recent += (threadTimesInStatus[4] / totalTime * 100.0).toFixed(1) + '% waiting for mutex. '; if (threadTimesInStatus[5] > 0) recent += (threadTimesInStatus[5] / totalTime * 100.0).toFixed(1) + '% waiting for proxied ops. '; - if (recent.length > 0) str += 'Recent activity: ' + recent; + if (recent.length > 0) str += `Recent activity: ${recent}`; str += '
'; } this.threadProfilerDiv.innerHTML = str; diff --git a/system/include/emscripten/html5_webgl.h b/system/include/emscripten/html5_webgl.h index ed20cbd8f0931..98971be3216db 100644 --- a/system/include/emscripten/html5_webgl.h +++ b/system/include/emscripten/html5_webgl.h @@ -7,13 +7,14 @@ #pragma once +#include #include #ifdef __cplusplus extern "C" { #endif -typedef int EMSCRIPTEN_WEBGL_CONTEXT_HANDLE; +typedef intptr_t EMSCRIPTEN_WEBGL_CONTEXT_HANDLE; typedef int EMSCRIPTEN_WEBGL_CONTEXT_PROXY_MODE; #define EMSCRIPTEN_WEBGL_CONTEXT_PROXY_DISALLOW 0 diff --git a/system/include/emscripten/threading_legacy.h b/system/include/emscripten/threading_legacy.h index 1d247a7be283d..3c467f1181290 100644 --- a/system/include/emscripten/threading_legacy.h +++ b/system/include/emscripten/threading_legacy.h @@ -37,9 +37,14 @@ typedef struct em_queued_call em_queued_call; #define EM_FUNC_SIG_RETURN_VALUE_V 0 #define EM_FUNC_SIG_RETURN_VALUE_I (0x1U << 29) -#define EM_FUNC_SIG_RETURN_VALUE_I64 (0x2U << 29) +#define EM_FUNC_SIG_RETURN_VALUE_J (0x2U << 29) #define EM_FUNC_SIG_RETURN_VALUE_F (0x3U << 29) #define EM_FUNC_SIG_RETURN_VALUE_D (0x4U << 29) +#if __wasm64__ +#define EM_FUNC_SIG_RETURN_VALUE_P EM_FUNC_SIG_RETURN_VALUE_J +#else +#define EM_FUNC_SIG_RETURN_VALUE_P EM_FUNC_SIG_RETURN_VALUE_I +#endif // - next highest four bits specify the number of input parameters to the // function (allowed values are 0-12, inclusively) @@ -56,10 +61,15 @@ typedef struct em_queued_call em_queued_call; #define EM_FUNC_SIG_ARGUMENT_TYPE_SIZE_SHIFT 2 #define EM_FUNC_SIG_PARAM_I 0 -#define EM_FUNC_SIG_PARAM_I64 0x1U +#define EM_FUNC_SIG_PARAM_J 0x1U #define EM_FUNC_SIG_PARAM_F 0x2U #define EM_FUNC_SIG_PARAM_D 0x3U -#define EM_FUNC_SIG_SET_PARAM(i, type) ((EM_FUNC_SIGNATURE)(type) << (2*i)) +#if __wasm64__ +#define EM_FUNC_SIG_PARAM_P EM_FUNC_SIG_PARAM_J +#else +#define EM_FUNC_SIG_PARAM_P EM_FUNC_SIG_PARAM_I +#endif +#define EM_FUNC_SIG_SET_PARAM(i, type) ((EM_FUNC_SIGNATURE)(type) << (EM_FUNC_SIG_ARGUMENT_TYPE_SIZE_SHIFT*i)) // Extra types used in WebGL glGet*() calls (not used in proxying) #define EM_FUNC_SIG_PARAM_B 0x4U @@ -111,6 +121,22 @@ typedef struct em_queued_call em_queued_call; #define EM_FUNC_SIG_IIIIIIIII (EM_FUNC_SIG_RETURN_VALUE_I | EM_FUNC_SIG_WITH_N_PARAMETERS(8) | EM_FUNC_SIG_SET_PARAM(0, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(1, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(2, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(3, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(4, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(5, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(6, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(7, EM_FUNC_SIG_PARAM_I)) #define EM_FUNC_SIG_IIIIIIIIII (EM_FUNC_SIG_RETURN_VALUE_I | EM_FUNC_SIG_WITH_N_PARAMETERS(9) | EM_FUNC_SIG_SET_PARAM(0, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(1, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(2, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(3, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(4, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(5, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(6, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(7, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(8, EM_FUNC_SIG_PARAM_I)) +#define EM_FUNC_SIG_IP (EM_FUNC_SIG_RETURN_VALUE_I | EM_FUNC_SIG_WITH_N_PARAMETERS(1) | EM_FUNC_SIG_SET_PARAM(0, EM_FUNC_SIG_PARAM_P)) +#define EM_FUNC_SIG_PI (EM_FUNC_SIG_RETURN_VALUE_P | EM_FUNC_SIG_WITH_N_PARAMETERS(1) | EM_FUNC_SIG_SET_PARAM(0, EM_FUNC_SIG_PARAM_I)) +#define EM_FUNC_SIG_PPP (EM_FUNC_SIG_RETURN_VALUE_P | EM_FUNC_SIG_WITH_N_PARAMETERS(2) | EM_FUNC_SIG_SET_PARAM(0, EM_FUNC_SIG_PARAM_P) | EM_FUNC_SIG_SET_PARAM(1, EM_FUNC_SIG_PARAM_P)) +#define EM_FUNC_SIG_PII (EM_FUNC_SIG_RETURN_VALUE_P | EM_FUNC_SIG_WITH_N_PARAMETERS(2) | EM_FUNC_SIG_SET_PARAM(0, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(1, EM_FUNC_SIG_PARAM_I)) +#define EM_FUNC_SIG_PIIII (EM_FUNC_SIG_RETURN_VALUE_P | EM_FUNC_SIG_WITH_N_PARAMETERS(4) | EM_FUNC_SIG_SET_PARAM(0, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(1, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(2, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(3, EM_FUNC_SIG_PARAM_I)) +#define EM_FUNC_SIG_VIIP (EM_FUNC_SIG_RETURN_VALUE_V | EM_FUNC_SIG_WITH_N_PARAMETERS(3) | EM_FUNC_SIG_SET_PARAM(0, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(1, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(2, EM_FUNC_SIG_PARAM_P)) +#define EM_FUNC_SIG_VIPI (EM_FUNC_SIG_RETURN_VALUE_V | EM_FUNC_SIG_WITH_N_PARAMETERS(3) | EM_FUNC_SIG_SET_PARAM(0, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(1, EM_FUNC_SIG_PARAM_P) | EM_FUNC_SIG_SET_PARAM(2, EM_FUNC_SIG_PARAM_I)) +#define EM_FUNC_SIG_VIP (EM_FUNC_SIG_RETURN_VALUE_V | EM_FUNC_SIG_WITH_N_PARAMETERS(2) | EM_FUNC_SIG_SET_PARAM(0, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(1, EM_FUNC_SIG_PARAM_P)) +#define EM_FUNC_SIG_IIP (EM_FUNC_SIG_RETURN_VALUE_I | EM_FUNC_SIG_WITH_N_PARAMETERS(2) | EM_FUNC_SIG_SET_PARAM(0, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(1, EM_FUNC_SIG_PARAM_P)) +#define EM_FUNC_SIG_VIIPP (EM_FUNC_SIG_RETURN_VALUE_V | EM_FUNC_SIG_WITH_N_PARAMETERS(4) | EM_FUNC_SIG_SET_PARAM(0, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(1, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(2, EM_FUNC_SIG_PARAM_P) | EM_FUNC_SIG_SET_PARAM(3, EM_FUNC_SIG_PARAM_P)) +#define EM_FUNC_SIG_VIPPI (EM_FUNC_SIG_RETURN_VALUE_V | EM_FUNC_SIG_WITH_N_PARAMETERS(4) | EM_FUNC_SIG_SET_PARAM(0, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(1, EM_FUNC_SIG_PARAM_P) | EM_FUNC_SIG_SET_PARAM(2, EM_FUNC_SIG_PARAM_P) | EM_FUNC_SIG_SET_PARAM(3, EM_FUNC_SIG_PARAM_I)) +#define EM_FUNC_SIG_VIIIP (EM_FUNC_SIG_RETURN_VALUE_V | EM_FUNC_SIG_WITH_N_PARAMETERS(4) | EM_FUNC_SIG_SET_PARAM(0, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(1, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(2, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(3, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(4, EM_FUNC_SIG_PARAM_P)) +#define EM_FUNC_SIG_VIIIIIP (EM_FUNC_SIG_RETURN_VALUE_V | EM_FUNC_SIG_WITH_N_PARAMETERS(6) | EM_FUNC_SIG_SET_PARAM(0, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(1, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(2, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(3, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(4, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(5, EM_FUNC_SIG_PARAM_P)) +#define EM_FUNC_SIG_VIIIIIIP (EM_FUNC_SIG_RETURN_VALUE_V | EM_FUNC_SIG_WITH_N_PARAMETERS(7) | EM_FUNC_SIG_SET_PARAM(0, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(1, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(2, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(3, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(4, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(5, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(6, EM_FUNC_SIG_PARAM_P)) +#define EM_FUNC_SIG_VIIIIIIIIP (EM_FUNC_SIG_RETURN_VALUE_V | EM_FUNC_SIG_WITH_N_PARAMETERS(9) | EM_FUNC_SIG_SET_PARAM(0, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(1, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(2, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(3, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(4, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(5, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(6, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(7, EM_FUNC_SIG_PARAM_I) | EM_FUNC_SIG_SET_PARAM(8, EM_FUNC_SIG_PARAM_P)) + #define EM_FUNC_SIG_NUM_FUNC_ARGUMENTS(x) ((((EM_FUNC_SIGNATURE)x) & EM_FUNC_SIG_NUM_PARAMETERS_MASK) >> EM_FUNC_SIG_NUM_PARAMETERS_SHIFT) // There are some built-in special proxied functions, that embed the signatures @@ -151,6 +177,16 @@ em_queued_call *emscripten_async_waitable_run_in_main_runtime_thread_(EM_FUNC_SI // Since we can't validate the function pointer type, allow implicit casting of // functions to void* without complaining. #define emscripten_sync_run_in_main_runtime_thread(sig, func_ptr, ...) emscripten_sync_run_in_main_runtime_thread_((sig), (void*)(func_ptr),##__VA_ARGS__) + +#ifdef __wasm64__ +// For wasm64 we need to special handling of pointer (P) return types since +// int and pointer have different widths +void* emscripten_sync_run_in_main_runtime_thread_ptr_(EM_FUNC_SIGNATURE sig, void *func_ptr __attribute__((nonnull)), ...); +#define emscripten_sync_run_in_main_runtime_thread_ptr(sig, func_ptr, ...) emscripten_sync_run_in_main_runtime_thread_ptr_((sig), (void*)(func_ptr),##__VA_ARGS__) +#else +#define emscripten_sync_run_in_main_runtime_thread_ptr emscripten_sync_run_in_main_runtime_thread +#endif + #define emscripten_async_run_in_main_runtime_thread(sig, func_ptr, ...) emscripten_async_run_in_main_runtime_thread_((sig), (void*)(func_ptr),##__VA_ARGS__) #define emscripten_async_waitable_run_in_main_runtime_thread(sig, func_ptr, ...) emscripten_async_waitable_run_in_main_runtime_thread_((sig), (void*)(func_ptr),##__VA_ARGS__) diff --git a/system/lib/gl/webgl1.c b/system/lib/gl/webgl1.c index 701b8b031d539..78afe29c23707 100644 --- a/system/lib/gl/webgl1.c +++ b/system/lib/gl/webgl1.c @@ -56,7 +56,7 @@ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE emscripten_webgl_create_context(const char *targ (attributes->proxyContextToMainThread == EMSCRIPTEN_WEBGL_CONTEXT_PROXY_FALLBACK && !emscripten_supports_offscreencanvas())) { EmscriptenWebGLContextAttributes attrs = *attributes; attrs.renderViaOffscreenBackBuffer = EM_TRUE; - return (EMSCRIPTEN_WEBGL_CONTEXT_HANDLE)emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_III, &emscripten_webgl_do_create_context, target, &attrs); + return (EMSCRIPTEN_WEBGL_CONTEXT_HANDLE)emscripten_sync_run_in_main_runtime_thread_ptr(EM_FUNC_SIG_PPP, &emscripten_webgl_do_create_context, target, &attrs); } else { return emscripten_webgl_do_create_context(target, attributes); } @@ -75,7 +75,7 @@ EMSCRIPTEN_RESULT emscripten_webgl_make_context_current(EMSCRIPTEN_WEBGL_CONTEXT } return r; } else { - EMSCRIPTEN_RESULT r = emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_II, &emscripten_webgl_make_context_current_calling_thread, context); + EMSCRIPTEN_RESULT r = emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_IP, &emscripten_webgl_make_context_current_calling_thread, context); if (r == EMSCRIPTEN_RESULT_SUCCESS) { pthread_setspecific(currentActiveWebGLContext, (void*)context); pthread_setspecific(currentThreadOwnsItsWebGLContext, (void*)0); @@ -106,7 +106,7 @@ static void *memdup(const void *ptr, size_t sz) { ASYNC_GL_FUNCTION_1(EM_FUNC_SIG_VI, void, glActiveTexture, GLenum); ASYNC_GL_FUNCTION_2(EM_FUNC_SIG_VII, void, glAttachShader, GLuint, GLuint); -VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIII, void, glBindAttribLocation, GLuint, GLuint, const GLchar*); +VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIIP, void, glBindAttribLocation, GLuint, GLuint, const GLchar*); ASYNC_GL_FUNCTION_2(EM_FUNC_SIG_VII, void, glBindBuffer, GLenum, GLuint); ASYNC_GL_FUNCTION_2(EM_FUNC_SIG_VII, void, glBindFramebuffer, GLenum, GLuint); ASYNC_GL_FUNCTION_2(EM_FUNC_SIG_VII, void, glBindRenderbuffer, GLenum, GLuint); @@ -127,13 +127,13 @@ void glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage if (size < 256*1024) { // run small buffer sizes asynchronously by copying - large buffers run synchronously void *ptr = memdup(data, size); if (ptr || !data) { // glBufferData(data=0) can always be handled asynchronously - emscripten_dispatch_to_thread(GetCurrentTargetThread(), EM_FUNC_SIG_VIIII, &emscripten_glBufferData, ptr, target, size, ptr, usage); + emscripten_dispatch_to_thread(GetCurrentTargetThread(), EM_FUNC_SIG_VIPPI, &emscripten_glBufferData, ptr, target, size, ptr, usage); return; } // Fall through on allocation failure and run synchronously. } - emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_VIIII, &emscripten_glBufferData, target, size, data, usage); + emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_VIPPI, &emscripten_glBufferData, target, size, data, usage); } void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data) { @@ -195,37 +195,37 @@ VOID_SYNC_GL_FUNCTION_0(EM_FUNC_SIG_V, void, glFlush); // TODO: THIS COULD POTEN ASYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIII, void, glFramebufferRenderbuffer, GLenum, GLenum, GLenum, GLuint); ASYNC_GL_FUNCTION_5(EM_FUNC_SIG_VIIIII, void, glFramebufferTexture2D, GLenum, GLenum, GLenum, GLuint, GLint); ASYNC_GL_FUNCTION_1(EM_FUNC_SIG_VI, void, glFrontFace, GLenum); -VOID_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_VII, void, glGenBuffers, GLsizei, GLuint *); +VOID_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_VIP, void, glGenBuffers, GLsizei, GLuint *); ASYNC_GL_FUNCTION_1(EM_FUNC_SIG_VI, void, glGenerateMipmap, GLenum); -VOID_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_VII, void, glGenFramebuffers, GLsizei, GLuint *); -VOID_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_VII, void, glGenRenderbuffers, GLsizei, GLuint *); -VOID_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_VII, void, glGenTextures, GLsizei, GLuint *); +VOID_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_VIP, void, glGenFramebuffers, GLsizei, GLuint *); +VOID_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_VIP, void, glGenRenderbuffers, GLsizei, GLuint *); +VOID_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_VIP, void, glGenTextures, GLsizei, GLuint *); VOID_SYNC_GL_FUNCTION_7(EM_FUNC_SIG_VIIIIIII, void, glGetActiveAttrib, GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *); VOID_SYNC_GL_FUNCTION_7(EM_FUNC_SIG_VIIIIIII, void, glGetActiveUniform, GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *); VOID_SYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIII, void, glGetAttachedShaders, GLuint, GLsizei, GLsizei *, GLuint *); -RET_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_III, GLint, glGetAttribLocation, GLuint, const GLchar *); +RET_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_IIP, GLint, glGetAttribLocation, GLuint, const GLchar *); VOID_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_VII, void, glGetBooleanv, GLenum, GLboolean *); -VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIII, void, glGetBufferParameteriv, GLenum, GLenum, GLint *); +VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIIP, void, glGetBufferParameteriv, GLenum, GLenum, GLint *); RET_SYNC_GL_FUNCTION_0(EM_FUNC_SIG_I, GLenum, glGetError); -VOID_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_VII, void, glGetFloatv, GLenum, GLfloat *); +VOID_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_VIP, void, glGetFloatv, GLenum, GLfloat *); VOID_SYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIII, void, glGetFramebufferAttachmentParameteriv, GLenum, GLenum, GLenum, GLint *); -VOID_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_VII, void, glGetIntegerv, GLenum, GLint *); -VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIII, void, glGetProgramiv, GLuint, GLenum, GLint *); -VOID_SYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIII, void, glGetProgramInfoLog, GLuint, GLsizei, GLsizei *, GLchar *); -VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIII, void, glGetRenderbufferParameteriv, GLenum, GLenum, GLint *); -VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIII, void, glGetShaderiv, GLuint, GLenum, GLint *); -VOID_SYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIII, void, glGetShaderInfoLog, GLuint, GLsizei, GLsizei *, GLchar *); -VOID_SYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIII, void, glGetShaderPrecisionFormat, GLenum, GLenum, GLint *, GLint *); -VOID_SYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIII, void, glGetShaderSource, GLuint, GLsizei, GLsizei *, GLchar *); -RET_SYNC_GL_FUNCTION_1(EM_FUNC_SIG_II, const GLubyte *, glGetString, GLenum); -VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIII, void, glGetTexParameterfv, GLenum, GLenum, GLfloat *); -VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIII, void, glGetTexParameteriv, GLenum, GLenum, GLint *); -VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIII, void, glGetUniformfv, GLuint, GLint, GLfloat *); -VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIII, void, glGetUniformiv, GLuint, GLint, GLint *); -RET_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_III, GLint, glGetUniformLocation, GLuint, const GLchar *); -VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIII, void, glGetVertexAttribfv, GLuint, GLenum, GLfloat *); -VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIII, void, glGetVertexAttribiv, GLuint, GLenum, GLint *); -VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIII, void, glGetVertexAttribPointerv, GLuint, GLenum, void **); +VOID_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_VIP, void, glGetIntegerv, GLenum, GLint *); +VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIIP, void, glGetProgramiv, GLuint, GLenum, GLint *); +VOID_SYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIPP, void, glGetProgramInfoLog, GLuint, GLsizei, GLsizei *, GLchar *); +VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIIP, void, glGetRenderbufferParameteriv, GLenum, GLenum, GLint *); +VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIIP, void, glGetShaderiv, GLuint, GLenum, GLint *); +VOID_SYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIPP, void, glGetShaderInfoLog, GLuint, GLsizei, GLsizei *, GLchar *); +VOID_SYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIPP, void, glGetShaderPrecisionFormat, GLenum, GLenum, GLint *, GLint *); +VOID_SYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIPP, void, glGetShaderSource, GLuint, GLsizei, GLsizei *, GLchar *); +RET_PTR_SYNC_GL_FUNCTION_1(EM_FUNC_SIG_PI, const GLubyte *, glGetString, GLenum); +VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIIP, void, glGetTexParameterfv, GLenum, GLenum, GLfloat *); +VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIIP, void, glGetTexParameteriv, GLenum, GLenum, GLint *); +VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIIP, void, glGetUniformfv, GLuint, GLint, GLfloat *); +VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIIP, void, glGetUniformiv, GLuint, GLint, GLint *); +RET_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_IIP, GLint, glGetUniformLocation, GLuint, const GLchar *); +VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIIP, void, glGetVertexAttribfv, GLuint, GLenum, GLfloat *); +VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIIP, void, glGetVertexAttribiv, GLuint, GLenum, GLint *); +VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIIP, void, glGetVertexAttribPointerv, GLuint, GLenum, void **); ASYNC_GL_FUNCTION_2(EM_FUNC_SIG_VII, void, glHint, GLenum, GLenum); RET_SYNC_GL_FUNCTION_1(EM_FUNC_SIG_II, GLboolean, glIsBuffer, GLuint); RET_SYNC_GL_FUNCTION_1(EM_FUNC_SIG_II, GLboolean, glIsEnabled, GLenum); @@ -238,13 +238,13 @@ ASYNC_GL_FUNCTION_1(EM_FUNC_SIG_VF, void, glLineWidth, GLfloat); ASYNC_GL_FUNCTION_1(EM_FUNC_SIG_VI, void, glLinkProgram, GLuint); ASYNC_GL_FUNCTION_2(EM_FUNC_SIG_VII, void, glPixelStorei, GLenum, GLint); ASYNC_GL_FUNCTION_2(EM_FUNC_SIG_VFF, void, glPolygonOffset, GLfloat, GLfloat); -VOID_SYNC_GL_FUNCTION_7(EM_FUNC_SIG_VIIIIIII, void, glReadPixels, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, void *); +VOID_SYNC_GL_FUNCTION_7(EM_FUNC_SIG_VIIIIIIP, void, glReadPixels, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, void *); ASYNC_GL_FUNCTION_0(EM_FUNC_SIG_V, void, glReleaseShaderCompiler); ASYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIII, void, glRenderbufferStorage, GLenum, GLenum, GLsizei, GLsizei); ASYNC_GL_FUNCTION_2(EM_FUNC_SIG_VII, void, glSampleCoverage, GLfloat, GLboolean); ASYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIII, void, glScissor, GLint, GLint, GLsizei, GLsizei); VOID_SYNC_GL_FUNCTION_5(EM_FUNC_SIG_VIIIII, void, glShaderBinary, GLsizei, const GLuint *, GLenum, const void *, GLsizei); -VOID_SYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIII, void, glShaderSource, GLuint, GLsizei, const GLchar *const*, const GLint *); +VOID_SYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIPP, void, glShaderSource, GLuint, GLsizei, const GLchar *const*, const GLint *); ASYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIII, void, glStencilFunc, GLenum, GLint, GLuint); ASYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIII, void, glStencilFuncSeparate, GLenum, GLenum, GLint, GLuint); ASYNC_GL_FUNCTION_1(EM_FUNC_SIG_VI, void, glStencilMask, GLuint); @@ -282,13 +282,13 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei widt if (!pixels || (sz >= 0 && sz < 256*1024)) { // run small buffer sizes asynchronously by copying - large buffers run synchronously void *ptr = memdup(pixels, sz); if (ptr || !pixels) { - emscripten_dispatch_to_thread(GetCurrentTargetThread(), EM_FUNC_SIG_VIIIIIIIII, &emscripten_glTexImage2D, ptr, target, level, internalformat, width, height, border, format, type, ptr); + emscripten_dispatch_to_thread(GetCurrentTargetThread(), EM_FUNC_SIG_VIIIIIIIIP, &emscripten_glTexImage2D, ptr, target, level, internalformat, width, height, border, format, type, ptr); return; } // Fall through on allocation failure and run synchronously. } - emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_VIIIIIIIII, &emscripten_glTexImage2D, target, level, internalformat, width, height, border, format, type, pixels); + emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_VIIIIIIIIP, &emscripten_glTexImage2D, target, level, internalformat, width, height, border, format, type, pixels); } ASYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIIF, void, glTexParameterf, GLenum, GLenum, GLfloat); @@ -537,13 +537,13 @@ void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, cons if (sz < 256*1024) { // run small buffer sizes asynchronously by copying - large buffers run synchronously void *ptr = memdup(value, sz); if (ptr) { - emscripten_dispatch_to_thread(GetCurrentTargetThread(), EM_FUNC_SIG_VIIII, &emscripten_glUniformMatrix4fv, ptr, location, count, transpose, (GLfloat*)ptr); + emscripten_dispatch_to_thread(GetCurrentTargetThread(), EM_FUNC_SIG_VIIIP, &emscripten_glUniformMatrix4fv, ptr, location, count, transpose, (GLfloat*)ptr); return; } // Fall through on allocation failure and run synchronously. } - emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_VIIII, &emscripten_glUniformMatrix4fv, location, count, transpose, value); + emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_VIIIP, &emscripten_glUniformMatrix4fv, location, count, transpose, value); } ASYNC_GL_FUNCTION_1(EM_FUNC_SIG_VI, void, glUseProgram, GLuint); @@ -559,9 +559,9 @@ VOID_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_VII, void, glVertexAttrib4fv, GLuint, const // TODO: The following #define FULL_ES2 does not yet exist, we'll need to compile this file twice, for FULL_ES2 mode and without #if FULL_ES2 -VOID_SYNC_GL_FUNCTION_6(EM_FUNC_SIG_VIIIIII, void, glVertexAttribPointer, GLuint, GLint, GLenum, GLboolean, GLsizei, const void *); +VOID_SYNC_GL_FUNCTION_6(EM_FUNC_SIG_PIIIIIP, void, glVertexAttribPointer, GLuint, GLint, GLenum, GLboolean, GLsizei, const void *); #else -ASYNC_GL_FUNCTION_6(EM_FUNC_SIG_VIIIIII, void, glVertexAttribPointer, GLuint, GLint, GLenum, GLboolean, GLsizei, const void *); +ASYNC_GL_FUNCTION_6(EM_FUNC_SIG_VIIIIIP, void, glVertexAttribPointer, GLuint, GLint, GLenum, GLboolean, GLsizei, const void *); #endif ASYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIII, void, glViewport, GLint, GLint, GLsizei, GLsizei); diff --git a/system/lib/gl/webgl2.c b/system/lib/gl/webgl2.c index a9512fdf06df6..1362475437f72 100644 --- a/system/lib/gl/webgl2.c +++ b/system/lib/gl/webgl2.c @@ -45,7 +45,7 @@ ASYNC_GL_FUNCTION_10(EM_FUNC_SIG_VIIIIIIIIII, void, glBlitFramebuffer, GLint, GL ASYNC_GL_FUNCTION_5(EM_FUNC_SIG_VIIIII, void, glRenderbufferStorageMultisample, GLenum, GLsizei, GLenum, GLsizei, GLsizei); ASYNC_GL_FUNCTION_5(EM_FUNC_SIG_VIIIII, void, glFramebufferTextureLayer, GLenum, GLenum, GLuint, GLint, GLint); #ifdef __EMSCRIPTEN_FULL_ES3__ -RET_SYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIII, void *, glMapBufferRange, GLenum, GLintptr, GLsizeiptr, GLbitfield); +RET_PTR_SYNC_GL_FUNCTION_4(EM_FUNC_SIG_PIIII, void *, glMapBufferRange, GLenum, GLintptr, GLsizeiptr, GLbitfield); ASYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIII, void, glFlushMappedBufferRange, GLenum, GLintptr, GLsizeiptr); #endif ASYNC_GL_FUNCTION_1(EM_FUNC_SIG_VI, void, glBindVertexArray, GLuint); @@ -80,7 +80,7 @@ VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIII, void, glClearBufferiv, GLenum, GLint, VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIII, void, glClearBufferuiv, GLenum, GLint, const GLuint *); VOID_SYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIII, void, glClearBufferfv, GLenum, GLint, const GLfloat *); ASYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIFI, void, glClearBufferfi, GLenum, GLint, GLfloat, GLint); -RET_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_III, const GLubyte *, glGetStringi, GLenum, GLuint); +RET_PTR_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_PII, const GLubyte *, glGetStringi, GLenum, GLuint); ASYNC_GL_FUNCTION_5(EM_FUNC_SIG_VIIIII, void, glCopyBufferSubData, GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr); VOID_SYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIII, void, glGetUniformIndices, GLuint, GLsizei, const GLchar *const*, GLuint *); VOID_SYNC_GL_FUNCTION_5(EM_FUNC_SIG_VIIIII, void, glGetActiveUniformsiv, GLuint, GLsizei, const GLuint *, GLenum, GLint *); @@ -90,7 +90,7 @@ VOID_SYNC_GL_FUNCTION_5(EM_FUNC_SIG_VIIIII, void, glGetActiveUniformBlockName, G ASYNC_GL_FUNCTION_3(EM_FUNC_SIG_VIII, void, glUniformBlockBinding, GLuint, GLuint, GLuint); ASYNC_GL_FUNCTION_4(EM_FUNC_SIG_VIIII, void, glDrawArraysInstanced, GLenum, GLint, GLsizei, GLsizei); ASYNC_GL_FUNCTION_5(EM_FUNC_SIG_VIIIII, void, glDrawElementsInstanced, GLenum, GLsizei, GLenum, const void *, GLsizei); // TODO: Not async if rendering from client side memory -RET_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_III, GLsync, glFenceSync, GLenum, GLbitfield); +RET_PTR_SYNC_GL_FUNCTION_2(EM_FUNC_SIG_PII, GLsync, glFenceSync, GLenum, GLbitfield); RET_SYNC_GL_FUNCTION_1(EM_FUNC_SIG_II, GLboolean, glIsSync, GLsync); ASYNC_GL_FUNCTION_1(EM_FUNC_SIG_VI, void, glDeleteSync, GLsync); GLenum glClientWaitSync(GLsync p0, GLbitfield p1, GLuint64 p2) { diff --git a/system/lib/gl/webgl_internal.h b/system/lib/gl/webgl_internal.h index 17562f43b527e..8e25acc9790e2 100644 --- a/system/lib/gl/webgl_internal.h +++ b/system/lib/gl/webgl_internal.h @@ -16,9 +16,9 @@ void _emscripten_proxied_gl_context_activated_from_main_browser_thread(EMSCRIPTE #if defined(__EMSCRIPTEN_PTHREADS__) && defined(__EMSCRIPTEN_OFFSCREEN_FRAMEBUFFER__) #ifdef EMSCRIPTEN_WEBGL_TRACE -#define GL_FUNCTION_TRACE(func) printf(#func "\n") +#define GL_FUNCTION_TRACE() emscripten_out(__FUNCTION__) #else -#define GL_FUNCTION_TRACE(func) ((void)0) +#define GL_FUNCTION_TRACE() ((void)0) #endif #define ASYNC_GL_FUNCTION_0(sig, ret, functionName) ret functionName(void) { GL_FUNCTION_TRACE(); if (pthread_getspecific(currentThreadOwnsItsWebGLContext)) emscripten_##functionName(); else emscripten_async_run_in_main_runtime_thread(sig, &emscripten_##functionName); } @@ -36,8 +36,11 @@ void _emscripten_proxied_gl_context_activated_from_main_browser_thread(EMSCRIPTE #define RET_SYNC_GL_FUNCTION_0(sig, ret, functionName) ret functionName(void) { GL_FUNCTION_TRACE(); if (pthread_getspecific(currentThreadOwnsItsWebGLContext)) return emscripten_##functionName(); else return (ret)emscripten_sync_run_in_main_runtime_thread(sig, &emscripten_##functionName); } #define RET_SYNC_GL_FUNCTION_1(sig, ret, functionName, t0) ret functionName(t0 p0) { GL_FUNCTION_TRACE(); if (pthread_getspecific(currentThreadOwnsItsWebGLContext)) return emscripten_##functionName(p0); else return (ret)emscripten_sync_run_in_main_runtime_thread(sig, &emscripten_##functionName, p0); } +#define RET_PTR_SYNC_GL_FUNCTION_1(sig, ret, functionName, t0) ret functionName(t0 p0) { GL_FUNCTION_TRACE(); if (pthread_getspecific(currentThreadOwnsItsWebGLContext)) return emscripten_##functionName(p0); else return (ret)emscripten_sync_run_in_main_runtime_thread_ptr(sig, &emscripten_##functionName, p0); } +#define RET_PTR_SYNC_GL_FUNCTION_2(sig, ret, functionName, t0, t1) ret functionName(t0 p0, t1 p1) { GL_FUNCTION_TRACE(); if (pthread_getspecific(currentThreadOwnsItsWebGLContext)) return emscripten_##functionName(p0, p1); else return (ret)emscripten_sync_run_in_main_runtime_thread_ptr(sig, &emscripten_##functionName, p0, p1); } #define RET_SYNC_GL_FUNCTION_2(sig, ret, functionName, t0, t1) ret functionName(t0 p0, t1 p1) { GL_FUNCTION_TRACE(); if (pthread_getspecific(currentThreadOwnsItsWebGLContext)) return emscripten_##functionName(p0, p1); else return (ret)emscripten_sync_run_in_main_runtime_thread(sig, &emscripten_##functionName, p0, p1); } #define RET_SYNC_GL_FUNCTION_3(sig, ret, functionName, t0, t1, t2) ret functionName(t0 p0, t1 p1, t2 p2) { GL_FUNCTION_TRACE(); if (pthread_getspecific(currentThreadOwnsItsWebGLContext)) return emscripten_##functionName(p0, p1, p2); else return (ret)emscripten_sync_run_in_main_runtime_thread(sig, &emscripten_##functionName, p0, p1, p2); } +#define RET_PTR_SYNC_GL_FUNCTION_4(sig, ret, functionName, t0, t1, t2, t3) ret functionName(t0 p0, t1 p1, t2 p2, t3 p3) { GL_FUNCTION_TRACE(); if (pthread_getspecific(currentThreadOwnsItsWebGLContext)) return emscripten_##functionName(p0, p1, p2, p3); else return (ret)emscripten_sync_run_in_main_runtime_thread_ptr(sig, &emscripten_##functionName, p0, p1, p2, p3); } #define RET_SYNC_GL_FUNCTION_4(sig, ret, functionName, t0, t1, t2, t3) ret functionName(t0 p0, t1 p1, t2 p2, t3 p3) { GL_FUNCTION_TRACE(); if (pthread_getspecific(currentThreadOwnsItsWebGLContext)) return emscripten_##functionName(p0, p1, p2, p3); else return (ret)emscripten_sync_run_in_main_runtime_thread(sig, &emscripten_##functionName, p0, p1, p2, p3); } #define RET_SYNC_GL_FUNCTION_5(sig, ret, functionName, t0, t1, t2, t3, t4) ret functionName(t0 p0, t1 p1, t2 p2, t3 p3, t4 p4) { GL_FUNCTION_TRACE(); if (pthread_getspecific(currentThreadOwnsItsWebGLContext)) return emscripten_##functionName(p0, p1, p2, p3, p4); else return (ret)emscripten_sync_run_in_main_runtime_thread(sig, &emscripten_##functionName, p0, p1, p2, p3, p4); } #define RET_SYNC_GL_FUNCTION_6(sig, ret, functionName, t0, t1, t2, t3, t4, t5) ret functionName(t0 p0, t1 p1, t2 p2, t3 p3, t4 p4, t5 p5) { GL_FUNCTION_TRACE(); if (pthread_getspecific(currentThreadOwnsItsWebGLContext)) return emscripten_##functionName(p0, p1, p2, p3, p4, p5); else return (ret)emscripten_sync_run_in_main_runtime_thread(sig, &emscripten_##functionName, p0, p1, p2, p3, p4, p5); } diff --git a/system/lib/libc/crt1_proxy_main.c b/system/lib/libc/crt1_proxy_main.c index 458f69b9993ad..2d178ca2e473a 100644 --- a/system/lib/libc/crt1_proxy_main.c +++ b/system/lib/libc/crt1_proxy_main.c @@ -42,9 +42,9 @@ EMSCRIPTEN_KEEPALIVE int _emscripten_proxy_main(int argc, char** argv) { // Use the size of the current stack, which is the normal size of the stack // that main() would have without PROXY_TO_PTHREAD. pthread_attr_setstacksize(&attr, emscripten_stack_get_base() - emscripten_stack_get_end()); - // Pass special ID -1 to the list of transferred canvases to denote that the thread creation - // should instead take a list of canvases that are specified from the command line with - // -sOFFSCREENCANVASES_TO_PTHREAD linker flag. + // Pass special ID -1 to the list of transferred canvases to denote that the + // thread creation should instead take a list of canvases that are specified + // from the command line with -sOFFSCREENCANVASES_TO_PTHREAD linker flag. emscripten_pthread_attr_settransferredcanvases(&attr, (const char*)-1); _main_argc = argc; _main_argv = argv; diff --git a/system/lib/pthread/proxying_legacy.c b/system/lib/pthread/proxying_legacy.c index 0f073ef5bf8f0..7b0407c2f000f 100644 --- a/system/lib/pthread/proxying_legacy.c +++ b/system/lib/pthread/proxying_legacy.c @@ -9,6 +9,7 @@ #include #include +#include #include "../internal/pthread_impl.h" @@ -17,7 +18,7 @@ typedef union em_variant_val { int i; - int64_t i64; + int64_t j; float f; double d; void *vp; @@ -83,6 +84,23 @@ typedef int (*em_func_iiiiiiii)(int, int, int, int, int, int, int); typedef int (*em_func_iiiiiiiii)(int, int, int, int, int, int, int, int); typedef int (*em_func_iiiiiiiiii)(int, int, int, int, int, int, int, int, int); +#ifdef __wasm64__ +typedef int (*em_func_ij)(uint64_t); +typedef uint64_t (*em_func_ji)(int); +typedef int (*em_func_ijj)(uint64_t, uint64_t); +typedef int (*em_func_iij)(int, uint64_t); +typedef uint64_t (*em_func_jjj)(uint64_t, uint64_t); +typedef void (*em_func_vij)(int, uint64_t); +typedef void (*em_func_viij)(int, int, uint64_t); +typedef void (*em_func_viji)(int, uint64_t, int); +typedef void (*em_func_vijji)(int, uint64_t, uint64_t, int); +typedef void (*em_func_viijj)(int, int, uint64_t, uint64_t); +typedef void (*em_func_viiij)(int, int, int, uint64_t); +typedef void (*em_func_viiiiij)(int, int, int, int, int, uint64_t); +typedef void (*em_func_viiiiiij)(int, int, int, int, int, int, uint64_t); +typedef void (*em_func_viiiiiiiij)(int, int, int, int, int, int, int, int, uint64_t); +#endif + // Allocator and deallocator for em_queued_call objects. static em_queued_call* em_queued_call_malloc() { em_queued_call* call = (em_queued_call*)malloc(sizeof(em_queued_call)); @@ -111,8 +129,8 @@ static void init_em_queued_call_args(em_queued_call* q, case EM_FUNC_SIG_PARAM_I: q->args[i].i = va_arg(args, int); break; - case EM_FUNC_SIG_PARAM_I64: - q->args[i].i64 = va_arg(args, int64_t); + case EM_FUNC_SIG_PARAM_J: + q->args[i].j = va_arg(args, int64_t); break; case EM_FUNC_SIG_PARAM_F: q->args[i].f = (float)va_arg(args, double); @@ -120,6 +138,8 @@ static void init_em_queued_call_args(em_queued_call* q, case EM_FUNC_SIG_PARAM_D: q->args[i].d = va_arg(args, double); break; + default: + assert(false && "unknown proxy param type"); } argumentsType >>= EM_FUNC_SIG_ARGUMENT_TYPE_SIZE_SHIFT; } @@ -225,6 +245,50 @@ static void _do_call(void* arg) { q->args[3].i, q->args[4].i, q->args[5].i, q->args[6].i, q->args[7].i, q->args[8].i, q->args[9].i, q->args[10].i); break; +#ifdef __wasm64__ + case EM_FUNC_SIG_IP: + q->returnValue.i = ((em_func_ij)q->functionPtr)(q->args[0].j); + break; + case EM_FUNC_SIG_PI: + q->returnValue.j = ((em_func_ji)q->functionPtr)(q->args[0].i); + break; + case EM_FUNC_SIG_IIP: + q->returnValue.i = ((em_func_iij)q->functionPtr)(q->args[0].i, q->args[1].j); + break; + case EM_FUNC_SIG_PPP: + q->returnValue.j = ((em_func_jjj)q->functionPtr)(q->args[0].j, q->args[1].j); + break; + case EM_FUNC_SIG_VIP: + ((em_func_vij)q->functionPtr)(q->args[0].i, q->args[1].j); + break; + case EM_FUNC_SIG_VIIP: + ((em_func_viij)q->functionPtr)(q->args[0].i, q->args[1].i, q->args[2].j); + break; + case EM_FUNC_SIG_VIIPP: + ((em_func_viijj)q->functionPtr)(q->args[0].i, q->args[1].i, q->args[2].j, q->args[3].j); + break; + case EM_FUNC_SIG_VIIIP: + ((em_func_viiij)q->functionPtr)(q->args[0].i, q->args[1].i, q->args[2].i, q->args[3].j); + break; + case EM_FUNC_SIG_VIPPI: + ((em_func_vijji)q->functionPtr)(q->args[0].i, q->args[1].j, q->args[2].j, q->args[3].i); + break; + case EM_FUNC_SIG_VIPI: + ((em_func_viji)q->functionPtr)(q->args[0].i, q->args[1].j, q->args[3].i); + break; + case EM_FUNC_SIG_VIIIIIP: + ((em_func_viiiiij)q->functionPtr)( + q->args[0].i, q->args[1].i, q->args[2].i, q->args[3].i, q->args[4].i, q->args[5].j); + break; + case EM_FUNC_SIG_VIIIIIIP: + ((em_func_viiiiiij)q->functionPtr)( + q->args[0].i, q->args[1].i, q->args[2].i, q->args[3].i, q->args[4].i, q->args[5].i, q->args[6].j); + break; + case EM_FUNC_SIG_VIIIIIIIIP: + ((em_func_viiiiiiiij)q->functionPtr)( + q->args[0].i, q->args[1].i, q->args[2].i, q->args[3].i, q->args[4].i, q->args[5].i, q->args[6].i, q->args[7].i, q->args[8].j); + break; +#endif case EM_FUNC_SIG_I: q->returnValue.i = ((em_func_i)q->functionPtr)(); break; @@ -405,6 +469,20 @@ int emscripten_sync_run_in_main_runtime_thread_(EM_FUNC_SIGNATURE sig, void* fun return q.returnValue.i; } +#ifdef __wasm64__ +void* emscripten_sync_run_in_main_runtime_thread_ptr_(EM_FUNC_SIGNATURE sig, void* func_ptr, ...) { + em_queued_call q = {sig, func_ptr}; + + va_list args; + va_start(args, func_ptr); + init_em_queued_call_args(&q, sig, args); + va_end(args); + sync_run_in_main_thread(&q); + emscripten_outf("sync_run_in_main_ptr: %p\n", q.returnValue.vp); + return q.returnValue.vp; +} +#endif + void emscripten_async_run_in_main_runtime_thread_(EM_FUNC_SIGNATURE sig, void* func_ptr, ...) { em_queued_call* q = em_queued_call_malloc(); if (!q) diff --git a/test/gl_textures.cpp b/test/gl_textures.cpp index 1697bf0e33bf1..eec0a6bd16580 100644 --- a/test/gl_textures.cpp +++ b/test/gl_textures.cpp @@ -63,6 +63,7 @@ int main() EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context("#canvas", &attr); emscripten_webgl_make_context_current(ctx); GLuint vs = glCreateShader(GL_VERTEX_SHADER); + assert(vs); const char *vss = "attribute vec4 vPosition; uniform mat4 mat; varying vec2 texCoord; void main() { gl_Position = vPosition; texCoord = (vPosition.xy + vec2(1.0)) * vec2(0.5); }"; glShaderSource(vs, 1, &vss, 0); glCompileShader(vs); @@ -94,6 +95,7 @@ int main() } program = glCreateProgram(); + assert(program); glAttachShader(program, vs); glAttachShader(program, ps); glBindAttribLocation(program, 0, "vPosition"); @@ -113,6 +115,7 @@ int main() GLuint vbo; glGenBuffers(1, &vbo); + assert(vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); float verts[] = { -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1 }; diff --git a/test/test_browser.py b/test/test_browser.py index caa12da92be56..c8b1b3309ebf3 100644 --- a/test/test_browser.py +++ b/test/test_browser.py @@ -1641,7 +1641,6 @@ def _test_egl_base(self, *args): def test_egl(self): self._test_egl_base() - @no_wasm64('TODO: wasm64 + OFB') @requires_threads @requires_graphics_hardware def test_egl_with_proxy_to_pthread(self): @@ -2021,9 +2020,7 @@ def test_gl_glteximage(self): @requires_graphics_hardware @requires_threads def test_gl_textures(self, args): - if args and self.is_wasm64(): - self.skipTest('TODO: wasm64 + OFB') - self.btest_exit('gl_textures.cpp', args=['-lGL'] + args) + self.btest_exit('gl_textures.cpp', args=['-lGL', '-g', '-sSTACK_SIZE=1MB'] + args) @requires_graphics_hardware @no_wasm64('TODO: wasm64 + LEGACY_GL_EMULATION') @@ -2832,13 +2829,8 @@ def test_webgl2_objects(self): 'offscreenframbuffer': (['-sOFFSCREEN_FRAMEBUFFER', '-pthread', '-sPROXY_TO_PTHREAD'],), }) def test_html5_webgl_api(self, args): - if '-sOFFSCREENCANVAS_SUPPORT' in args: - if os.getenv('EMTEST_LACKS_OFFSCREEN_CANVAS'): - return - if self.is_wasm64(): - self.skipTest('TODO: wasm64 + OFFSCREENCANVAS') - if '-sOFFSCREEN_FRAMEBUFFER' in args and self.is_wasm64(): - self.skipTest('TODO: wasm64 + OFB') + if '-sOFFSCREENCANVAS_SUPPORT' in args and os.getenv('EMTEST_LACKS_OFFSCREEN_CANVAS'): + return self.btest_exit('html5_webgl.c', args=['-sMAX_WEBGL_VERSION=2', '-lGL'] + args) @parameterized({ @@ -4619,7 +4611,6 @@ def test_small_js_flags(self): @requires_threads @requires_offscreen_canvas @requires_graphics_hardware - @no_wasm64('TODO: wasm64 + OFFSCREENCANVAS') def test_webgl_offscreen_canvas_in_pthread(self, args): self.btest('gl_in_pthread.cpp', expected='1', args=args + ['-pthread', '-sPTHREAD_POOL_SIZE=2', '-sOFFSCREENCANVAS_SUPPORT', '-lGL']) @@ -4636,11 +4627,9 @@ def test_webgl_offscreen_canvas_in_pthread(self, args): def test_webgl_offscreen_canvas_in_mainthread_after_pthread(self, args): self.btest('gl_in_mainthread_after_pthread.cpp', expected='0', args=args + ['-pthread', '-sPTHREAD_POOL_SIZE=2', '-sOFFSCREENCANVAS_SUPPORT', '-lGL']) - @no_wasm64() @requires_threads @requires_offscreen_canvas @requires_graphics_hardware - @no_wasm64('TODO: wasm64 + OFFSCREENCANVAS') def test_webgl_offscreen_canvas_only_in_pthread(self): self.btest_exit('gl_only_in_pthread.cpp', args=['-pthread', '-sPTHREAD_POOL_SIZE', '-sOFFSCREENCANVAS_SUPPORT', '-lGL', '-sOFFSCREEN_FRAMEBUFFER']) @@ -4652,7 +4641,6 @@ def test_webgl_from_client_side_memory_without_default_enabled_extensions(self): # Tests for WEBGL_multi_draw extension # For testing WebGL draft extensions like this, if using chrome as the browser, # We might want to append the --enable-webgl-draft-extensions to the EMTEST_BROWSER env arg. - @no_wasm64() @requires_graphics_hardware @parameterized({ 'arrays': (['-DMULTI_DRAW_ARRAYS'],), @@ -4701,16 +4689,17 @@ def test_webgl_timer_query(self, args): self.btest_exit('webgl_timer_query.c', args=args + ['-lGL']) # Tests that -sOFFSCREEN_FRAMEBUFFER rendering works. - @no_wasm64() @requires_graphics_hardware - @no_wasm64('TODO: wasm64 + OFB') - def test_webgl_offscreen_framebuffer(self): + @parameterized({ + '': ([],), + 'threads': (['-pthread', '-sPROXY_TO_PTHREAD'],) + }) + def test_webgl_offscreen_framebuffer(self, threads): # Tests all the different possible versions of libgl - for threads in [[], ['-pthread', '-sPROXY_TO_PTHREAD']]: - for version in [[], ['-sFULL_ES3'], ['-sFULL_ES3']]: - args = ['-lGL', '-sOFFSCREEN_FRAMEBUFFER', '-DEXPLICIT_SWAP=1'] + threads + version - print('with args: %s' % str(args)) - self.btest_exit('webgl_draw_triangle.c', args=args) + for version in [[], ['-sFULL_ES3'], ['-sFULL_ES3']]: + args = ['-lGL', '-sOFFSCREEN_FRAMEBUFFER', '-DEXPLICIT_SWAP=1'] + threads + version + print('with args: %s' % str(args)) + self.btest_exit('webgl_draw_triangle.c', args=args) # Tests that VAOs can be used even if WebGL enableExtensionsByDefault is set to 0. @requires_graphics_hardware @@ -4753,11 +4742,9 @@ def test_webgl_array_of_structs_uniform(self): '': ([False],), 'asyncify': ([True],), }) - @no_wasm64() @requires_threads @requires_offscreen_canvas @requires_graphics_hardware - @no_wasm64('TODO: wasm64 + OFFSCREENCANVAS') def test_webgl_offscreen_canvas_in_proxied_pthread(self, asyncify): cmd = ['-pthread', '-sOFFSCREENCANVAS_SUPPORT', '-lGL', '-sGL_DEBUG', '-sPROXY_TO_PTHREAD'] if asyncify: @@ -4767,7 +4754,6 @@ def test_webgl_offscreen_canvas_in_proxied_pthread(self, asyncify): print(str(cmd)) self.btest_exit('gl_in_proxy_pthread.cpp', args=cmd) - @no_wasm64() @parameterized({ 'proxy': (['-sPROXY_TO_PTHREAD'],), '': ([],), @@ -4775,7 +4761,6 @@ def test_webgl_offscreen_canvas_in_proxied_pthread(self, asyncify): @requires_threads @requires_graphics_hardware @requires_offscreen_canvas - @no_wasm64('TODO: wasm64 + OFFSCREENCANVAS') def test_webgl_resize_offscreencanvas_from_main_thread(self, args): for args2 in [[], ['-DTEST_SYNC_BLOCKING_LOOP=1']]: for args3 in [[], ['-sOFFSCREENCANVAS_SUPPORT', '-sOFFSCREEN_FRAMEBUFFER']]: @@ -4981,21 +4966,21 @@ def test_pthread_run_script(self, args): self.btest_exit('pthread/test_pthread_run_script.c', args=['-O3'] + args) # Tests emscripten_set_canvas_element_size() and OffscreenCanvas functionality in different build configurations. - @no_wasm64() @requires_threads @requires_graphics_hardware - def test_emscripten_animate_canvas_element_size(self): - for args in [ - ['-DTEST_EMSCRIPTEN_SET_MAIN_LOOP=1'], - ['-DTEST_EMSCRIPTEN_SET_MAIN_LOOP=1', '-sPROXY_TO_PTHREAD', '-pthread', '-sOFFSCREEN_FRAMEBUFFER'], - ['-DTEST_EMSCRIPTEN_SET_MAIN_LOOP=1', '-sPROXY_TO_PTHREAD', '-pthread', '-sOFFSCREEN_FRAMEBUFFER', '-DTEST_EXPLICIT_CONTEXT_SWAP=1'], - ['-DTEST_EXPLICIT_CONTEXT_SWAP=1', '-sPROXY_TO_PTHREAD', '-pthread', '-sOFFSCREEN_FRAMEBUFFER'], - ['-DTEST_EXPLICIT_CONTEXT_SWAP=1', '-sPROXY_TO_PTHREAD', '-pthread', '-sOFFSCREEN_FRAMEBUFFER', '-DTEST_MANUALLY_SET_ELEMENT_CSS_SIZE=1'], - ['-DTEST_EMSCRIPTEN_SET_MAIN_LOOP=1', '-sOFFSCREENCANVAS_SUPPORT'], - ]: - cmd = ['-lGL', '-O3', '-g2', '--shell-file', test_file('canvas_animate_resize_shell.html'), '-sGL_DEBUG', '--threadprofiler', '-sASSERTIONS'] + args - print(' '.join(cmd)) - self.btest_exit('canvas_animate_resize.cpp', args=cmd) + @parameterized({ + '': ([], True), + 'offscreen': (['-sOFFSCREENCANVAS_SUPPORT'], True), + 'pthread': (['-sPROXY_TO_PTHREAD', '-pthread', '-sOFFSCREEN_FRAMEBUFFER'], True), + 'pthread_ofb_main_loop': (['-sPROXY_TO_PTHREAD', '-pthread', '-sOFFSCREEN_FRAMEBUFFER', '-DTEST_EXPLICIT_CONTEXT_SWAP=1'], True), + 'pthread_ofb': (['-sPROXY_TO_PTHREAD', '-pthread', '-sOFFSCREEN_FRAMEBUFFER', '-DTEST_EXPLICIT_CONTEXT_SWAP=1'], False), + 'manual_css': (['-sPROXY_TO_PTHREAD', '-pthread', '-sOFFSCREEN_FRAMEBUFFER', '-DTEST_EXPLICIT_CONTEXT_SWAP=1', '-DTEST_MANUALLY_SET_ELEMENT_CSS_SIZE=1'], False), + }) + def test_emscripten_animate_canvas_element_size(self, args, main_loop): + cmd = ['-lGL', '-O3', '-g2', '--shell-file', test_file('canvas_animate_resize_shell.html'), '-sGL_DEBUG', '--threadprofiler', '-sASSERTIONS'] + args + if main_loop: + cmd.append('-DTEST_EMSCRIPTEN_SET_MAIN_LOOP=1') + self.btest_exit('canvas_animate_resize.cpp', args=cmd) # Tests the absolute minimum pthread-enabled application. @parameterized({