diff --git a/src/library_glemu.js b/src/library_glemu.js index 51cf48fa57c46..3e439ec7aa497 100644 --- a/src/library_glemu.js +++ b/src/library_glemu.js @@ -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. @@ -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' : '') diff --git a/src/library_glew.js b/src/library_glew.js index 0c03085c3d8a3..e1058b90f3dff 100644 --- a/src/library_glew.js +++ b/src/library_glew.js @@ -20,7 +20,7 @@ */ var LibraryGLEW = { - $GLEW__deps: ['glGetString', '$stringToNewUTF8', '$UTF8ToString'], + $GLEW__deps: ['glGetString', '$stringToNewUTF8', '$UTF8ToString', '$glGetExtensions'], $GLEW: { isLinaroFork: 1, extensions: null, @@ -99,7 +99,7 @@ var LibraryGLEW = { }, extensionIsSupported(name) { - GLEW.extensions ||= GL.getExtensions(); + GLEW.extensions ||= glGetExtensions(); if (GLEW.extensions.includes(name)) return 1; diff --git a/src/library_glfw.js b/src/library_glfw.js index 7f306a7e83240..ede30302e38f0 100644 --- a/src/library_glfw.js +++ b/src/library_glfw.js @@ -1483,9 +1483,9 @@ var LibraryGLFW = { GLFW.initialTime = GLFW.getTime() - time; }, - glfwExtensionSupported__deps: ['glGetString'], + glfwExtensionSupported__deps: ['glGetString', 'glGetExtensions'], glfwExtensionSupported: (extension) => { - GLFW.extensions ||= GL.getExtensions(); + GLFW.extensions ||= glGetExtensions(); if (GLFW.extensions.includes(extension)) return 1; diff --git a/src/library_html5_webgl.js b/src/library_html5_webgl.js index c0e984bc4dd62..468fe487c6423 100644 --- a/src/library_html5_webgl.js +++ b/src/library_html5_webgl.js @@ -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(' ')), diff --git a/src/library_webgl.js b/src/library_webgl.js index 2096d85d59543..ebc59456f4ef0 100644 --- a/src/library_webgl.js +++ b/src/library_webgl.js @@ -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. @@ -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, @@ -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; }, @@ -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')) { @@ -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() || []; + }, + + $glGetExtensions__internal: true, + $glGetExtensions__deps: ['$getEmscriptenSupportedExtensions'], + $glGetExtensions() { + 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) => { @@ -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', '$glGetExtensions'], glGetString: (name_) => { var ret = GL.stringCache[name_]; if (!ret) { switch (name_) { case 0x1F03 /* GL_EXTENSIONS */: - ret = stringToNewUTF8(GL.getExtensions().join(' ')); + ret = stringToNewUTF8(glGetExtensions().join(' ')); break; case 0x1F00 /* GL_VENDOR */: case 0x1F01 /* GL_RENDERER */: @@ -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 + '$glGetExtensions', // 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 @@ -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 = glGetExtensions(GLctx).length; break; case 0x821B: // GL_MAJOR_VERSION case 0x821C: // GL_MINOR_VERSION diff --git a/src/library_webgl2.js b/src/library_webgl2.js index c972f726c3a1e..aecfc05077483 100644 --- a/src/library_webgl2.js +++ b/src/library_webgl2.js @@ -5,7 +5,7 @@ */ var LibraryWebGL2 = { - glGetStringi__deps: ['$stringToNewUTF8'], + glGetStringi__deps: ['$glGetExtensions', '$stringToNewUTF8'], glGetStringi: (name, index) => { if (GL.currentContext.version < 2) { GL.recordError(0x502 /* GL_INVALID_OPERATION */); // Calling GLES3/WebGL2 function with a GLES2/WebGL1 context @@ -24,7 +24,7 @@ var LibraryWebGL2 = { } switch (name) { case 0x1F03 /* GL_EXTENSIONS */: - var exts = GL.getExtensions().map((e) => stringToNewUTF8(e)); + var exts = glGetExtensions().map((e) => stringToNewUTF8(e)); stringiCache = GL.stringiCache[name] = exts; if (index < 0 || index >= stringiCache.length) { GL.recordError(0x501/*GL_INVALID_VALUE*/);