From ec91007185ebadb596334ce608835ab9a51b3027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Sat, 29 Aug 2015 01:57:26 +0300 Subject: [PATCH 1/2] Implement glGetStringi() for GLES3 compatibility and add a test. Closes #3472. --- src/library_gl.js | 57 +++++++++++++++++++++++++++++++++++++++++++ tests/test_browser.py | 5 ++++ tests/webgl2.cpp | 45 ++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 tests/webgl2.cpp diff --git a/src/library_gl.js b/src/library_gl.js index 8678503ae..bc7fdb0aa 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -56,6 +56,9 @@ var LibraryGL = { } */ stringCache: {}, +#if USE_WEBGL2 + stringiCache: {}, +#endif packAlignment: 4, // default alignment is 4 bytes unpackAlignment: 4, // default alignment is 4 bytes @@ -343,6 +346,16 @@ var LibraryGL = { case 0x8B9B: // GL_IMPLEMENTATION_COLOR_READ_FORMAT ret = 0x1908; // GL_RGBA break; +#if USE_WEBGL2 + case 0x821D: // GL_NUM_EXTENSIONS + if (GLctx.canvas.GLctxObject.version < 2) { + GL.recordError(0x0502 /* GL_INVALID_OPERATION */); // Calling GLES3/WebGL2 function with a GLES2/WebGL1 context + return; + } + var exts = GLctx.getSupportedExtensions(); + ret = 2*exts.length; // each extension is duplicated, first in unprefixed WebGL form, and then a second time with "GL_" prefix. + break; +#endif } if (ret === undefined) { @@ -963,6 +976,50 @@ var LibraryGL = { return ret; }, +#if USE_WEBGL2 + glGetStringi: function(name, index) { + if (GLctx.canvas.GLctxObject.version < 2) { + GL.recordError(0x0502 /* GL_INVALID_OPERATION */); // Calling GLES3/WebGL2 function with a GLES2/WebGL1 context + return 0; + } + if (GL.stringiCache[name]) { + if (index < 0 || index >= GL.stringiCache[name].length) { + GL.recordError(0x0501/*GL_INVALID_VALUE*/); +#if GL_ASSERTIONS + Module.printErr('GL_INVALID_VALUE in glGetStringi: index out of range (' + index + ')!'); +#endif + return 0; + } + return GL.stringiCache[name][index]; + } + switch(name) { + case 0x1F03 /* GL_EXTENSIONS */: + var exts = GLctx.getSupportedExtensions(); + var gl_exts = []; + // each extension is duplicated, first in unprefixed WebGL form, and then a second time with "GL_" prefix. + for (var i in exts) { + gl_exts.push(allocate(intArrayFromString(exts[i]), 'i8', ALLOC_NORMAL)); + gl_exts.push(allocate(intArrayFromString("GL_" + exts[i]), 'i8', ALLOC_NORMAL)); + } + GL.stringiCache[name] = gl_exts; + if (index < 0 || index >= GL.stringiCache[name].length) { + GL.recordError(0x0501/*GL_INVALID_VALUE*/); +#if GL_ASSERTIONS + Module.printErr('GL_INVALID_VALUE in glGetStringi: index out of range (' + index + ') in a call to GL_EXTENSIONS!'); +#endif + return 0; + } + return GL.stringiCache[name][index]; + default: + GL.recordError(0x0500/*GL_INVALID_ENUM*/); +#if GL_ASSERTIONS + Module.printErr('GL_INVALID_ENUM in glGetStringi: Unknown parameter ' + name + '!'); +#endif + return 0; + } + }, +#endif + glGetIntegerv__sig: 'vii', glGetIntegerv: function(name_, p) { return GL.get(name_, p, 'Integer'); diff --git a/tests/test_browser.py b/tests/test_browser.py index 6506bfd47..4efaa704f 100644 --- a/tests/test_browser.py +++ b/tests/test_browser.py @@ -1930,6 +1930,11 @@ Module["preRun"].push(function () { print opts self.btest(path_from_root('tests', 'webgl_destroy_context.cpp'), args=opts + ['--shell-file', path_from_root('tests/webgl_destroy_context_shell.html'), '-s', 'NO_EXIT_RUNTIME=1'], expected='0') + def test_webgl2(self): + for opts in [[], ['-O2', '-g1', '--closure', '1'], ['-s', 'FULL_ES2=1']]: + print opts + self.btest(path_from_root('tests', 'webgl2.cpp'), args=['-s', 'USE_WEBGL2=1'] + opts, expected='0') + def test_sdl_touch(self): for opts in [[], ['-O2', '-g1', '--closure', '1']]: print opts diff --git a/tests/webgl2.cpp b/tests/webgl2.cpp new file mode 100644 index 000000000..1726378d5 --- /dev/null +++ b/tests/webgl2.cpp @@ -0,0 +1,45 @@ +#include + +#include +#include +#include +#include +#include + +EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context; + +int main() +{ + EmscriptenWebGLContextAttributes attrs; + emscripten_webgl_init_context_attributes(&attrs); + attrs.majorVersion = 2; + attrs.minorVersion = 0; + + int result = 0; + + EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context(0, &attrs); + if (context) + { + EMSCRIPTEN_RESULT res = emscripten_webgl_make_context_current(context); + assert(res == EMSCRIPTEN_RESULT_SUCCESS); + assert(emscripten_webgl_get_current_context() == context); + + int numExtensions = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions); + bool hasGLExtension = false; + for(int i = 0; i < numExtensions; ++i) + { + const char *ext = (const char *)glGetStringi(GL_EXTENSIONS, i); + printf("extension %d: %s\n", i, ext); + if (strstr(ext, "GL_") == 0) + hasGLExtension = true; + } + if (!hasGLExtension) + result = 1; + } + +#ifdef REPORT_RESULT + REPORT_RESULT(); +#endif + return 0; +} From 05abad16e65cc737ec21537cc753e6f46c783521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Wed, 2 Sep 2015 16:51:55 +0300 Subject: [PATCH 2/2] Clean up GL.stringiCache[name] access to its own variable in glGetStringi. --- src/library_gl.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/library_gl.js b/src/library_gl.js index bc7fdb0aa..94a54c0bf 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -982,15 +982,16 @@ var LibraryGL = { GL.recordError(0x0502 /* GL_INVALID_OPERATION */); // Calling GLES3/WebGL2 function with a GLES2/WebGL1 context return 0; } - if (GL.stringiCache[name]) { - if (index < 0 || index >= GL.stringiCache[name].length) { + var stringiCache = GL.stringiCache[name]; + if (stringiCache) { + if (index < 0 || index >= stringiCache.length) { GL.recordError(0x0501/*GL_INVALID_VALUE*/); #if GL_ASSERTIONS Module.printErr('GL_INVALID_VALUE in glGetStringi: index out of range (' + index + ')!'); #endif return 0; } - return GL.stringiCache[name][index]; + return stringiCache[index]; } switch(name) { case 0x1F03 /* GL_EXTENSIONS */: @@ -1001,15 +1002,15 @@ var LibraryGL = { gl_exts.push(allocate(intArrayFromString(exts[i]), 'i8', ALLOC_NORMAL)); gl_exts.push(allocate(intArrayFromString("GL_" + exts[i]), 'i8', ALLOC_NORMAL)); } - GL.stringiCache[name] = gl_exts; - if (index < 0 || index >= GL.stringiCache[name].length) { + stringiCache = GL.stringiCache[name] = gl_exts; + if (index < 0 || index >= stringiCache.length) { GL.recordError(0x0501/*GL_INVALID_VALUE*/); #if GL_ASSERTIONS Module.printErr('GL_INVALID_VALUE in glGetStringi: index out of range (' + index + ') in a call to GL_EXTENSIONS!'); #endif return 0; } - return GL.stringiCache[name][index]; + return stringiCache[index]; default: GL.recordError(0x0500/*GL_INVALID_ENUM*/); #if GL_ASSERTIONS