Skip to content

Commit

Permalink
Include GL extension fliter/allowlist if and only if its needed
Browse files Browse the repository at this point in the history
Here we use the JS library dependency mechanism to include this code
only when its needed.

Sadly this will end up being preset in almost all GL-using programs
because most of them will end up using `emscriptenWebGLGet` (e.g. any
app that calls `glGetInteger`, `glGetString`, etc)

Fixes: #20798
  • Loading branch information
sbc100 committed Jan 5, 2024
1 parent ba02e4f commit 9e3c841
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 85 deletions.
12 changes: 10 additions & 2 deletions src/library_glemu.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@

var LibraryGLEmulation = {
// GL emulation: provides misc. functionality not present in OpenGL ES 2.0 or WebGL
$GLEmulation__deps: ['$GLImmediateSetup', 'glEnable', 'glDisable', 'glIsEnabled', 'glGetBooleanv', 'glGetIntegerv', 'glGetString', 'glCreateShader', 'glShaderSource', 'glCompileShader', 'glAttachShader', 'glDetachShader', 'glUseProgram', 'glDeleteProgram', 'glBindAttribLocation', 'glLinkProgram', 'glBindBuffer', 'glGetFloatv', 'glHint', 'glEnableVertexAttribArray', 'glDisableVertexAttribArray', 'glVertexAttribPointer', 'glActiveTexture', '$stringToNewUTF8', '$ptrToString'],
$GLEmulation__deps: ['$GLImmediateSetup', 'glEnable', 'glDisable',
'glIsEnabled', 'glGetBooleanv', 'glGetIntegerv', 'glGetString',
'glCreateShader', 'glShaderSource', 'glCompileShader', 'glAttachShader',
'glDetachShader', 'glUseProgram', 'glDeleteProgram', 'glBindAttribLocation',
'glLinkProgram', 'glBindBuffer', 'glGetFloatv', 'glHint',
'glEnableVertexAttribArray', 'glDisableVertexAttribArray',
'glVertexAttribPointer', 'glActiveTexture', '$stringToNewUTF8',
'$ptrToString', '$getEmscriptenSupportedExtensions',
],
$GLEmulation__postset:
#if MAYBE_CLOSURE_COMPILER
// Forward declare GL functions that are overridden by GLEmulation here to appease Closure compiler.
Expand Down Expand Up @@ -394,7 +402,7 @@ var LibraryGLEmulation = {
if (GL.stringCache[name_]) return GL.stringCache[name_];
switch (name_) {
case 0x1F03 /* GL_EXTENSIONS */: // Add various extensions that we can support
var ret = stringToNewUTF8((GLctx.getSupportedExtensions() || []).join(' ') +
var ret = stringToNewUTF8(getEmscriptenSupportedExtensions(GLctx).join(' ') +
' GL_EXT_texture_env_combine GL_ARB_texture_env_crossbar GL_ATI_texture_env_combine3 GL_NV_texture_env_combine4 GL_EXT_texture_env_dot3 GL_ARB_multitexture GL_ARB_vertex_buffer_object GL_EXT_framebuffer_object GL_ARB_vertex_program GL_ARB_fragment_program GL_ARB_shading_language_100 GL_ARB_shader_objects GL_ARB_vertex_shader GL_ARB_fragment_shader GL_ARB_texture_cube_map GL_EXT_draw_range_elements' +
(GL.currentContext.compressionExt ? ' GL_ARB_texture_compression GL_EXT_texture_compression_s3tc' : '') +
(GL.currentContext.anisotropicExt ? ' GL_EXT_texture_filter_anisotropic' : '')
Expand Down
4 changes: 2 additions & 2 deletions src/library_glew.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
*/

var LibraryGLEW = {
$GLEW__deps: ['glGetString', '$stringToNewUTF8', '$UTF8ToString'],
$GLEW__deps: ['glGetString', '$stringToNewUTF8', '$UTF8ToString', '$webglGetExtensions'],
$GLEW: {
isLinaroFork: 1,
extensions: null,
Expand Down Expand Up @@ -99,7 +99,7 @@ var LibraryGLEW = {
},

extensionIsSupported(name) {
GLEW.extensions ||= GL.getExtensions();
GLEW.extensions ||= webglGetExtensions();

if (GLEW.extensions.includes(name))
return 1;
Expand Down
4 changes: 2 additions & 2 deletions src/library_glfw.js
Original file line number Diff line number Diff line change
Expand Up @@ -1468,9 +1468,9 @@ var LibraryGLFW = {
GLFW.initialTime = GLFW.getTime() - time;
},

glfwExtensionSupported__deps: ['glGetString'],
glfwExtensionSupported__deps: ['glGetString', 'webglGetExtensions'],
glfwExtensionSupported: (extension) => {
GLFW.extensions ||= GL.getExtensions();
GLFW.extensions ||= webglGetExtensions();

if (GLFW.extensions.includes(extension)) return 1;

Expand Down
3 changes: 3 additions & 0 deletions src/library_html5_webgl.js
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,9 @@ var LibraryHtml5WebGL = {
emscripten_webgl_get_supported_extensions__proxy: 'sync_on_current_webgl_context_thread',
emscripten_webgl_get_supported_extensions__deps: ['$stringToNewUTF8'],
// Here we report the full list of extensions supported by WebGL rather than
// using getEmscriptenSupportedExtensions which filters the list based on
// what is has explicit support in.
emscripten_webgl_get_supported_extensions: () =>
stringToNewUTF8(GLctx.getSupportedExtensions().join(' ')),
Expand Down
146 changes: 69 additions & 77 deletions src/library_webgl.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,56 @@ for (/**@suppress{duplicate}*/var i = 0; i < {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
emscripten_webgl_enable_WEBGL_multi_draw__deps: ['$webgl_enable_WEBGL_multi_draw'],
emscripten_webgl_enable_WEBGL_multi_draw: (ctx) => webgl_enable_WEBGL_multi_draw(GL.contexts[ctx].GLctx),

$getEmscriptenSupportedExtensions__internal: true,
$getEmscriptenSupportedExtensions: function(ctx) {
// Restrict the list of advertised extensions to those that we actually
// support.
var supportedExtensions = [
#if MIN_WEBGL_VERSION == 1
// WebGL 1 extensions
'ANGLE_instanced_arrays',
'EXT_blend_minmax',
'EXT_disjoint_timer_query',
'EXT_frag_depth',
'EXT_shader_texture_lod',
'EXT_sRGB',
'OES_element_index_uint',
'OES_fbo_render_mipmap',
'OES_standard_derivatives',
'OES_texture_float',
'OES_texture_half_float',
'OES_texture_half_float_linear',
'OES_vertex_array_object',
'WEBGL_color_buffer_float',
'WEBGL_depth_texture',
'WEBGL_draw_buffers',
#endif
#if MAX_WEBGL_VERSION >= 2
// WebGL 2 extensions
'EXT_color_buffer_float',
'EXT_disjoint_timer_query_webgl2',
'EXT_texture_norm16',
'WEBGL_clip_cull_distance',
#endif
// WebGL 1 and WebGL 2 extensions
'EXT_color_buffer_half_float',
'EXT_float_blend',
'EXT_texture_compression_bptc',
'EXT_texture_compression_rgtc',
'EXT_texture_filter_anisotropic',
'KHR_parallel_shader_compile',
'OES_texture_float_linear',
'WEBGL_compressed_texture_s3tc',
'WEBGL_compressed_texture_s3tc_srgb',
'WEBGL_debug_renderer_info',
'WEBGL_debug_shaders',
'WEBGL_lose_context',
'WEBGL_multi_draw',
];
// .getSupportedExtensions() can return null if context is lost, so coerce to empty array.
return (ctx.getSupportedExtensions() || []).filter(ext => supportedExtensions.includes(ext));
},

$GL__postset: 'var GLctx;',
#if GL_SUPPORT_AUTOMATIC_ENABLE_EXTENSIONS
// If GL_SUPPORT_AUTOMATIC_ENABLE_EXTENSIONS is enabled, GL.initExtensions() will call to initialize these.
Expand All @@ -153,8 +203,9 @@ for (/**@suppress{duplicate}*/var i = 0; i < {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
'$webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance',
#endif
'$webgl_enable_WEBGL_multi_draw',
'$getEmscriptenSupportedExtensions',
],
#endif
#endif // GL_SUPPORT_AUTOMATIC_ENABLE_EXTENSIONS
$GL: {
#if GL_DEBUG
debug: true,
Expand Down Expand Up @@ -738,60 +789,6 @@ for (/**@suppress{duplicate}*/var i = 0; i < {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
}
disableHalfFloatExtensionIfBroken(ctx);
#endif
// If end user enables *glGetProcAddress() functionality or
// GL_SUPPORT_AUTOMATIC_ENABLE_EXTENSIONS, then we must filter out
// all future WebGL extensions from being passed to the user, and only restrict to advertising
// extensions that the *glGetProcAddress() function knows to handle.
#if GL_ENABLE_GET_PROC_ADDRESS || GL_SUPPORT_AUTOMATIC_ENABLE_EXTENSIONS
var _allSupportedExtensions = ctx.getSupportedExtensions;
var supportedExtensionsForGetProcAddress = [
#if MIN_WEBGL_VERSION == 1
// WebGL 1 extensions
'ANGLE_instanced_arrays',
'EXT_blend_minmax',
'EXT_disjoint_timer_query',
'EXT_frag_depth',
'EXT_shader_texture_lod',
'EXT_sRGB',
'OES_element_index_uint',
'OES_fbo_render_mipmap',
'OES_standard_derivatives',
'OES_texture_float',
'OES_texture_half_float',
'OES_texture_half_float_linear',
'OES_vertex_array_object',
'WEBGL_color_buffer_float',
'WEBGL_depth_texture',
'WEBGL_draw_buffers',
#endif
#if MAX_WEBGL_VERSION >= 2
// WebGL 2 extensions
'EXT_color_buffer_float',
'EXT_disjoint_timer_query_webgl2',
'EXT_texture_norm16',
'WEBGL_clip_cull_distance',
#endif
// WebGL 1 and WebGL 2 extensions
'EXT_color_buffer_half_float',
'EXT_float_blend',
'EXT_texture_compression_bptc',
'EXT_texture_compression_rgtc',
'EXT_texture_filter_anisotropic',
'KHR_parallel_shader_compile',
'OES_texture_float_linear',
'WEBGL_compressed_texture_s3tc',
'WEBGL_compressed_texture_s3tc_srgb',
'WEBGL_debug_renderer_info',
'WEBGL_debug_shaders',
'WEBGL_lose_context',
'WEBGL_multi_draw',
];
ctx.getSupportedExtensions = function() {
return (_allSupportedExtensions.apply(this) || []).filter(ext => supportedExtensionsForGetProcAddress.includes(ext));
}
#endif
return handle;
},
Expand Down Expand Up @@ -1206,10 +1203,7 @@ for (/**@suppress{duplicate}*/var i = 0; i < {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
webgl_enable_WEBGL_multi_draw(GLctx);
// .getSupportedExtensions() can return null if context is lost, so coerce
// to empty array.
var exts = GLctx.getSupportedExtensions() || [];
exts.forEach((ext) => {
getEmscriptenSupportedExtensions(GLctx).forEach((ext) => {
// WEBGL_lose_context, WEBGL_debug_renderer_info and WEBGL_debug_shaders
// are not enabled by default.
if (!ext.includes('lose_context') && !ext.includes('debug')) {
Expand All @@ -1220,14 +1214,16 @@ for (/**@suppress{duplicate}*/var i = 0; i < {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
},
#endif
getExtensions() {
// .getSupportedExtensions() can return null if context is lost, so coerce to empty array.
var exts = GLctx.getSupportedExtensions() || [];
},
$webglGetExtensions__internal: true,
$webglGetExtensions__deps: ['$getEmscriptenSupportedExtensions'],
$webglGetExtensions() {
var exts = getEmscriptenSupportedExtensions(GLctx);
#if GL_EXTENSIONS_IN_PREFIXED_FORMAT
exts = exts.concat(exts.map((e) => "GL_" + e));
exts = exts.concat(exts.map((e) => "GL_" + e));
#endif
return exts;
},
return exts;
},
glPixelStorei: (pname, param) => {
Expand All @@ -1237,13 +1233,13 @@ for (/**@suppress{duplicate}*/var i = 0; i < {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
GLctx.pixelStorei(pname, param);
},
glGetString__deps: ['$stringToNewUTF8'],
glGetString__deps: ['$stringToNewUTF8', '$webglGetExtensions'],
glGetString: (name_) => {
var ret = GL.stringCache[name_];
if (!ret) {
switch (name_) {
case 0x1F03 /* GL_EXTENSIONS */:
ret = stringToNewUTF8(GL.getExtensions().join(' '));
ret = stringToNewUTF8(webglGetExtensions().join(' '));
break;
case 0x1F00 /* GL_VENDOR */:
case 0x1F01 /* GL_RENDERER */:
Expand Down Expand Up @@ -1305,7 +1301,11 @@ for (/**@suppress{duplicate}*/var i = 0; i < {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
return ret;
},
$emscriptenWebGLGet__deps: ['$writeI53ToI64'],
$emscriptenWebGLGet__deps: ['$writeI53ToI64',
#if MAX_WEBGL_VERSION >= 2
'$webglGetExtensions', // For GL_NUM_EXTENSIONS
#endif
],
$emscriptenWebGLGet: (name_, p, type) => {
// Guard against user passing a null pointer.
// Note that GLES2 spec does not say anything about how passing a null
Expand Down Expand Up @@ -1368,15 +1368,7 @@ for (/**@suppress{duplicate}*/var i = 0; i < {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
return;
}
#endif
// .getSupportedExtensions() can return null if context is lost, so coerce to empty array.
var exts = GLctx.getSupportedExtensions() || [];
#if GL_EXTENSIONS_IN_PREFIXED_FORMAT
// each extension is duplicated, first in unprefixed WebGL form, and
// then a second time with "GL_" prefix.
ret = 2 * exts.length;
#else
ret = exts.length;
#endif
ret = webglGetExtensions().length;
break;
case 0x821B: // GL_MAJOR_VERSION
case 0x821C: // GL_MINOR_VERSION
Expand Down
4 changes: 2 additions & 2 deletions src/library_webgl2.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

var LibraryWebGL2 = {
glGetStringi__deps: ['$stringToNewUTF8'],
glGetStringi__deps: ['$webglGetExtensions', '$stringToNewUTF8'],
glGetStringi: (name, index) => {
if (GL.currentContext.version < 2) {
GL.recordError(0x502 /* GL_INVALID_OPERATION */); // Calling GLES3/WebGL2 function with a GLES2/WebGL1 context
Expand All @@ -24,7 +24,7 @@ var LibraryWebGL2 = {
}
switch (name) {
case 0x1F03 /* GL_EXTENSIONS */:
var exts = GL.getExtensions().map(stringToNewUTF8);
var exts = webglGetExtensions().map(stringToNewUTF8);
stringiCache = GL.stringiCache[name] = exts;
if (index < 0 || index >= stringiCache.length) {
GL.recordError(0x501/*GL_INVALID_VALUE*/);
Expand Down

0 comments on commit 9e3c841

Please sign in to comment.