From 4b587e7ce58f2aac7aaa4689f5a5159f9eb9b412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Fri, 1 Feb 2019 01:22:52 +0200 Subject: [PATCH 01/14] Micro-optimize WebGL support: each GL object table stores null at index 0, so testing "id ? GL.table[id] : null" is redundant. Optimizes -21 bytes (-0.13%) in minimal WebGL demo --- src/library_gl.js | 47 ++++++++++++++++++----------------------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/src/library_gl.js b/src/library_gl.js index 3d88e27172129..42c0209700c73 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -1692,7 +1692,7 @@ var LibraryGL = { #if GL_ASSERTIONS GL.validateGLObjectID(GL.textures, texture, 'glBindTexture', 'texture'); #endif - GLctx.bindTexture(target, texture ? GL.textures[texture] : null); + GLctx.bindTexture(target, GL.textures[texture]); }, glGetTexParameterfv__sig: 'viii', @@ -1927,7 +1927,7 @@ var LibraryGL = { #if GL_ASSERTIONS GL.validateGLObjectID(GL.timerQueriesEXT, id, 'glBeginQueryEXT', 'id'); #endif - GLctx.disjointTimerQueryExt['beginQueryEXT'](target, id ? GL.timerQueriesEXT[id] : null); + GLctx.disjointTimerQueryExt['beginQueryEXT'](target, GL.timerQueriesEXT[id]); }, glEndQueryEXT__sig: 'vi', @@ -1940,7 +1940,7 @@ var LibraryGL = { #if GL_ASSERTIONS GL.validateGLObjectID(GL.timerQueriesEXT, id, 'glQueryCounterEXT', 'id'); #endif - GLctx.disjointTimerQueryExt['queryCounterEXT'](id ? GL.timerQueriesEXT[id] : null, target); + GLctx.disjointTimerQueryExt['queryCounterEXT'](GL.timerQueriesEXT[id], target); }, glGetQueryivEXT__sig: 'viii', @@ -2235,7 +2235,7 @@ var LibraryGL = { #if GL_ASSERTIONS GL.validateGLObjectID(GL.queries, id, 'glBeginQuery', 'id'); #endif - GLctx['beginQuery'](target, id ? GL.queries[id] : null); + GLctx['beginQuery'](target, GL.queries[id]); }, glGetQueryiv__sig: 'viii', @@ -2312,7 +2312,7 @@ var LibraryGL = { #if GL_ASSERTIONS GL.validateGLObjectID(GL.samplers, sampler, 'glBindSampler', 'sampler'); #endif - GLctx['bindSampler'](unit, sampler ? GL.samplers[sampler] : null); + GLctx['bindSampler'](unit, GL.samplers[sampler]); }, glSamplerParameterf__sig: 'viif', @@ -2320,7 +2320,7 @@ var LibraryGL = { #if GL_ASSERTIONS GL.validateGLObjectID(GL.samplers, sampler, 'glBindSampler', 'sampler'); #endif - GLctx['samplerParameterf'](sampler ? GL.samplers[sampler] : null, pname, param); + GLctx['samplerParameterf'](GL.samplers[sampler], pname, param); }, glSamplerParameteri__sig: 'viii', @@ -2328,7 +2328,7 @@ var LibraryGL = { #if GL_ASSERTIONS GL.validateGLObjectID(GL.samplers, sampler, 'glBindSampler', 'sampler'); #endif - GLctx['samplerParameteri'](sampler ? GL.samplers[sampler] : null, pname, param); + GLctx['samplerParameteri'](GL.samplers[sampler], pname, param); }, glSamplerParameterfv__sig: 'viii', @@ -2337,7 +2337,7 @@ var LibraryGL = { GL.validateGLObjectID(GL.samplers, sampler, 'glBindSampler', 'sampler'); #endif var param = {{{ makeGetValue('params', '0', 'float') }}}; - GLctx['samplerParameterf'](sampler ? GL.samplers[sampler] : null, pname, param); + GLctx['samplerParameterf'](GL.samplers[sampler], pname, param); }, glSamplerParameteriv__sig: 'viii', @@ -2346,7 +2346,7 @@ var LibraryGL = { GL.validateGLObjectID(GL.samplers, sampler, 'glBindSampler', 'sampler'); #endif var param = {{{ makeGetValue('params', '0', 'i32') }}}; - GLctx['samplerParameteri'](sampler ? GL.samplers[sampler] : null, pname, param); + GLctx['samplerParameteri'](GL.samplers[sampler], pname, param); }, glGetSamplerParameterfv__sig: 'viii', @@ -2403,10 +2403,8 @@ var LibraryGL = { }, glIsTransformFeedback__sig: 'ii', - glIsTransformFeedback: function(transformFeedback) { - var transformFeedback = GL.transformFeedbacks[transformFeedback]; - if (!transformFeedback) return 0; - return GLctx['isTransformFeedback'](transformFeedback); + glIsTransformFeedback: function(id) { + return GLctx['isTransformFeedback'](GL.transformFeedbacks[id]); }, glBindTransformFeedback__sig: 'vii', @@ -2414,12 +2412,7 @@ var LibraryGL = { #if GL_ASSERTIONS GL.validateGLObjectID(GL.transformFeedbacks, id, 'glBindTransformFeedback', 'id'); #endif - var transformFeedback = id ? GL.transformFeedbacks[id] : null; - if (id && !transformFeedback) { // Passing an nonexisting or an already deleted id is an error. - GL.recordError(0x0502 /* GL_INVALID_OPERATION */); - return; - } - GLctx['bindTransformFeedback'](target, transformFeedback); + GLctx['bindTransformFeedback'](target, GL.transformFeedbacks[id]); }, glTransformFeedbackVaryings__sig: 'viiii', @@ -2534,8 +2527,7 @@ var LibraryGL = { #if GL_ASSERTIONS GL.validateGLObjectID(GL.buffers, buffer, 'glBindBufferBase', 'buffer'); #endif - var bufferObj = buffer ? GL.buffers[buffer] : null; - GLctx['bindBufferBase'](target, index, bufferObj); + GLctx['bindBufferBase'](target, index, GL.buffers[buffer]); }, glBindBufferRange__sig: 'viiiii', @@ -2543,8 +2535,7 @@ var LibraryGL = { #if GL_ASSERTIONS GL.validateGLObjectID(GL.buffers, buffer, 'glBindBufferRange', 'buffer'); #endif - var bufferObj = buffer ? GL.buffers[buffer] : null; - GLctx['bindBufferRange'](target, index, bufferObj, offset, ptrsize); + GLctx['bindBufferRange'](target, index, GL.buffers[buffer], offset, ptrsize); }, glGetUniformIndices__sig: 'viiii', @@ -2851,7 +2842,7 @@ var LibraryGL = { #if GL_ASSERTIONS GL.validateGLObjectID(GL.renderbuffers, renderbuffer, 'glBindRenderbuffer', 'renderbuffer'); #endif - GLctx.bindRenderbuffer(target, renderbuffer ? GL.renderbuffers[renderbuffer] : null); + GLctx.bindRenderbuffer(target, GL.renderbuffers[renderbuffer]); }, glGetRenderbufferParameteriv__sig: 'viii', @@ -3636,8 +3627,6 @@ var LibraryGL = { #if GL_ASSERTIONS GL.validateGLObjectID(GL.buffers, buffer, 'glBindBuffer', 'buffer'); #endif - var bufferObj = buffer ? GL.buffers[buffer] : null; - #if FULL_ES2 || LEGACY_GL_EMULATION if (target == GLctx.ARRAY_BUFFER) { GL.currArrayBuffer = buffer; @@ -3664,7 +3653,7 @@ var LibraryGL = { GLctx.currentPixelUnpackBufferBinding = buffer; } #endif - GLctx.bindBuffer(target, bufferObj); + GLctx.bindBuffer(target, GL.buffers[buffer]); }, glVertexAttrib1fv__sig: 'vii', @@ -4070,7 +4059,7 @@ var LibraryGL = { #if GL_ASSERTIONS GL.validateGLObjectID(GL.programs, program, 'glUseProgram', 'program'); #endif - GLctx.useProgram(program ? GL.programs[program] : null); + GLctx.useProgram(GL.programs[program]); }, glValidateProgram__sig: 'vi', @@ -4135,7 +4124,7 @@ var LibraryGL = { // is being used, but that is ultimately decided at context creation time. GLctx.bindFramebuffer(target, framebuffer ? GL.framebuffers[framebuffer] : GL.currentContext.defaultFbo); #else - GLctx.bindFramebuffer(target, framebuffer ? GL.framebuffers[framebuffer] : null); + GLctx.bindFramebuffer(target, GL.framebuffers[framebuffer]); #endif }, From 631bf290caab6c59875ce5e0a66e56c4a3970516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Fri, 1 Feb 2019 01:34:13 +0200 Subject: [PATCH 02/14] Micro-optimize WebGL support: Collapse WebGL 1 bufferData() call to one. Saves -17 bytes (-0.11%) on minimal WebGL demo --- src/library_gl.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/library_gl.js b/src/library_gl.js index 42c0209700c73..84a3ff3657f16 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -1860,17 +1860,21 @@ var LibraryGL = { break; } #endif - if (!data) { - GLctx.bufferData(target, size, usage); - } else { #if USE_WEBGL2 - if (GL.currentContext.supportsWebGL2EntryPoints) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible. + if (GL.currentContext.supportsWebGL2EntryPoints) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible. + if (data) { GLctx.bufferData(target, HEAPU8, usage, data, size); - return; + } else { + GLctx.bufferData(target, size, usage); } + } else { #endif - GLctx.bufferData(target, HEAPU8.subarray(data, data+size), usage); + // N.b. here first form specifies a heap subarray, second form an integer size, so the ?: code here is polymorphic. It is advised to avoid + // randomly mixing both uses in calling code, to avoid any potential JS engine JIT issues. + GLctx.bufferData(target, data ? HEAPU8.subarray(data, data+size) : size, usage); +#if USE_WEBGL2 } +#endif }, glBufferSubData__sig: 'viiii', From be0ceb4181f9096277f60832c74f5642e4df7a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Fri, 1 Feb 2019 01:41:49 +0200 Subject: [PATCH 03/14] Micro-optimize WebGL library: save -7 bytes (-0.11%) on redundant null check --- src/library_gl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library_gl.js b/src/library_gl.js index 84a3ff3657f16..5d020fb91b86b 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -987,7 +987,7 @@ var LibraryGL = { // only store the string 'colors' in utable, and 'colors[0]', 'colors[1]' and 'colors[2]' will be parsed as 'colors'+i. // Note that for the GL.uniforms table, we still need to fetch the all WebGLUniformLocations for all the indices. var loc = GLctx.getUniformLocation(p, name); - if (loc != null) + if (loc) { var id = GL.getNewId(GL.uniforms); utable[name] = [u.size, id]; From 85c9c6bd91939152cbd8b8646b12fa9de6dfe897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Fri, 1 Feb 2019 02:08:33 +0200 Subject: [PATCH 04/14] Micro-optimize WebGL library: simplify uniform array bracket parsing --- src/library_gl.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/library_gl.js b/src/library_gl.js index 5d020fb91b86b..6b8a60a679349 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -978,8 +978,8 @@ var LibraryGL = { ptable.maxUniformLength = Math.max(ptable.maxUniformLength, name.length+1); // Strip off any trailing array specifier we might have got, e.g. "[0]". - if (name.indexOf(']', name.length-1) !== -1) { - var ls = name.lastIndexOf('['); + var ls = name.lastIndexOf('['); + if (ls > 0) { name = name.slice(0, ls); } From 39a71f2bd67e56692f5b9994839aae0c5dd9f0e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Fri, 1 Feb 2019 02:09:21 +0200 Subject: [PATCH 05/14] Micro-optimize WebGL library: simplify uniform array bracket parsing. Reduces minimal WebGL demo by -57 bytes (-0.92%) --- src/library_gl.js | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/src/library_gl.js b/src/library_gl.js index 6b8a60a679349..63e8584e79665 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -2927,28 +2927,17 @@ var LibraryGL = { #endif name = UTF8ToString(name); - var arrayOffset = 0; + var arrayIndex = 0; // If user passed an array accessor "[index]", parse the array index off the accessor. - if (name.indexOf(']', name.length-1) !== -1) { - var ls = name.lastIndexOf('['); - var arrayIndex = name.slice(ls+1, -1); - if (arrayIndex.length > 0) { - arrayOffset = parseInt(arrayIndex); - if (arrayOffset < 0) { - return -1; - } - } - name = name.slice(0, ls); + if (name[name.length - 1] == ']') { + var leftBrace = name.lastIndexOf('['); + arrayIndex = name[leftBrace+1] != ']' ? parseInt(name.slice(leftBrace + 1)) : 0; // "index]", parseInt will ignore the ']' at the end; but treat "foo[]" as "foo[0]" + name = name.slice(0, leftBrace); } - var ptable = GL.programInfos[program]; - if (!ptable) { - return -1; - } - var utable = ptable.uniforms; - var uniformInfo = utable[name]; // returns pair [ dimension_of_uniform_array, uniform_location ] - if (uniformInfo && arrayOffset < uniformInfo[0]) { // Check if user asked for an out-of-bounds element, i.e. for 'vec4 colors[3];' user could ask for 'colors[10]' which should return -1. - return uniformInfo[1]+arrayOffset; + var uniformInfo = GL.programInfos[program] && GL.programInfos[program].uniforms[name]; // returns pair [ dimension_of_uniform_array, uniform_location ] + if (uniformInfo && arrayIndex >= 0 && arrayIndex < uniformInfo[0]) { // Check if user asked for an out-of-bounds element, i.e. for 'vec4 colors[3];' user could ask for 'colors[10]' which should return -1. + return uniformInfo[1] + arrayIndex; } else { return -1; } From 37fbd191cfd9bccd924402d5343743413f59e7ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Fri, 1 Feb 2019 02:14:35 +0200 Subject: [PATCH 06/14] Micro-optimize WebGL support library: avoid Math.max() to save -5 bytes (-0.03%) on minimal WebGL demo --- src/library_gl.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/library_gl.js b/src/library_gl.js index 63e8584e79665..e9181d2b9d5da 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -975,7 +975,10 @@ var LibraryGL = { var u = GLctx.getActiveUniform(p, i); var name = u.name; - ptable.maxUniformLength = Math.max(ptable.maxUniformLength, name.length+1); + var length = name.length + 1; + if (length > ptable.maxUniformLength) { + ptable.maxUniformLength = length; + } // Strip off any trailing array specifier we might have got, e.g. "[0]". var ls = name.lastIndexOf('['); @@ -987,8 +990,7 @@ var LibraryGL = { // only store the string 'colors' in utable, and 'colors[0]', 'colors[1]' and 'colors[2]' will be parsed as 'colors'+i. // Note that for the GL.uniforms table, we still need to fetch the all WebGLUniformLocations for all the indices. var loc = GLctx.getUniformLocation(p, name); - if (loc) - { + if (loc) { var id = GL.getNewId(GL.uniforms); utable[name] = [u.size, id]; GL.uniforms[id] = loc; From 15c6ed7a360dc84dc4be36ec2a18b81355535d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Sat, 2 Feb 2019 13:09:07 +0200 Subject: [PATCH 07/14] Micro-optimize WebGL library: GL.getSource() smaller, saves -8 bytes (-0.14%) --- src/library_gl.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/library_gl.js b/src/library_gl.js index e9181d2b9d5da..183d8a41c2007 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -251,8 +251,8 @@ var LibraryGL = { getSource: function(shader, count, string, length) { var source = ''; for (var i = 0; i < count; ++i) { - var len = length ? {{{ makeGetValue('length', 'i*4', 'i32') }}} : undefined; - source += UTF8ToString({{{ makeGetValue('string', 'i*4', 'i32') }}}, len >= 0 ? len : undefined); + var len = length ? {{{ makeGetValue('length', 'i*4', 'i32') }}} : -1; + source += UTF8ToString({{{ makeGetValue('string', 'i*4', 'i32') }}}, len < 0 ? 9e9/*short abbrv. for infinity*/ : len); } #if LEGACY_GL_EMULATION // Let's see if we need to enable the standard derivatives extension From c78243f0e207deeabe45a39e5a11fed1513dd450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Sat, 2 Feb 2019 14:39:08 +0200 Subject: [PATCH 08/14] Micro-optimize WebGL glBindAttribLocation and glGetUniformBlockIndex. Optimizes -4 bytes (0.07%) --- src/library_gl.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/library_gl.js b/src/library_gl.js index 183d8a41c2007..6bbe4453dc78c 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -2614,9 +2614,7 @@ var LibraryGL = { #if GL_ASSERTIONS GL.validateGLObjectID(GL.programs, program, 'glGetUniformBlockIndex', 'program'); #endif - program = GL.programs[program]; - uniformBlockName = UTF8ToString(uniformBlockName); - return GLctx['getUniformBlockIndex'](program, uniformBlockName); + return GLctx['getUniformBlockIndex'](GL.programs[program], UTF8ToString(uniformBlockName)); }, glGetActiveUniformBlockiv__sig: 'viiii', @@ -4103,8 +4101,7 @@ var LibraryGL = { #if GL_ASSERTIONS GL.validateGLObjectID(GL.programs, program, 'glBindAttribLocation', 'program'); #endif - name = UTF8ToString(name); - GLctx.bindAttribLocation(GL.programs[program], index, name); + GLctx.bindAttribLocation(GL.programs[program], index, UTF8ToString(name)); }, glBindFramebuffer__sig: 'vii', From f91575aba5523c9ef619bfa154bc9544a2283199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Sat, 2 Feb 2019 15:25:31 +0200 Subject: [PATCH 09/14] Micro-optimize WebGL glLinkProgram: Closure is for some reason unable to collapse redundant assignments. Saves -16 bytes (-0.31%) in minimal WebGL demo. --- src/library_gl.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/library_gl.js b/src/library_gl.js index 6bbe4453dc78c..51c20453a324c 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -959,14 +959,13 @@ var LibraryGL = { GL.validateGLObjectID(GL.programs, program, 'populateUniformTable', 'program'); #endif var p = GL.programs[program]; - GL.programInfos[program] = { + var ptable = GL.programInfos[program] = { uniforms: {}, maxUniformLength: 0, // This is eagerly computed below, since we already enumerate all uniforms anyway. maxAttributeLength: -1, // This is lazily computed and cached, computed when/if first asked, "-1" meaning not computed yet. maxUniformBlockNameLength: -1 // Lazily computed as well }; - var ptable = GL.programInfos[program]; var utable = ptable.uniforms; // A program's uniform table maps the string name of an uniform to an integer location of that uniform. // The global GL.uniforms map maps integer locations to WebGLUniformLocations. @@ -4027,7 +4026,6 @@ var LibraryGL = { var log = (GLctx.getProgramInfoLog(GL.programs[program]) || '').trim(); if (log) console.error('glLinkProgram: ' + log); #endif - GL.programInfos[program] = null; // uniforms no longer keep the same names after linking GL.populateUniformTable(program); }, From 5b8be3765071f14ba8b09d9555408c0e834a0692 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Sat, 2 Feb 2019 18:20:51 +0200 Subject: [PATCH 10/14] Micro-optimize WebGL library: Power of 2 rounding up when computing unpack alignment. Saves -5 bytes (-0.10%). Also use GL_ASSERTIONS instead of ASSERTIONS in WebGL library. --- src/library_gl.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/library_gl.js b/src/library_gl.js index 51c20453a324c..f04b82be849ea 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -752,7 +752,7 @@ var LibraryGL = { registerContext: function(ctx, webGLContextAttributes) { var handle = _malloc(8); // Make space on the heap to store GL context attributes that need to be accessible as shared between threads. -#if ASSERTIONS +#if GL_ASSERTIONS assert(handle, 'malloc() failed in GL.registerContext!'); #endif #if GL_SUPPORT_EXPLICIT_SWAP_CONTROL @@ -1417,7 +1417,10 @@ var LibraryGL = { _computeUnpackAlignedImageSize: function(width, height, sizePerPixel, alignment) { function roundedToNextMultipleOf(x, y) { - return Math.ceil(x/y)*y; +#if GL_ASSERTIONS + assert((y & (y-1)) === 0, 'Unpack alignment must be a power of 2! (Allowed values per WebGL spec are 1, 2, 4 or 8)'); +#endif + return (x + y - 1) & -y; } var plainRowSize = width * sizePerPixel; var alignedRowSize = roundedToNextMultipleOf(plainRowSize, alignment); @@ -1621,10 +1624,7 @@ var LibraryGL = { return; } #endif - - var pixelData = null; - if (pixels) pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, internalFormat); - GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixelData); + GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, internalFormat) : null); }, glTexSubImage2D__sig: 'viiiiiiiii', @@ -3765,7 +3765,7 @@ var LibraryGL = { {{{ makeSetValue('count', '0', 'len', 'i32') }}}; for (var i = 0; i < len; ++i) { var id = GL.shaders.indexOf(result[i]); -#if ASSERTIONS +#if GL_ASSERTIONS assert(id !== -1, 'shader not bound to local id'); #endif {{{ makeSetValue('shaders', 'i*4', 'id', 'i32') }}}; @@ -4354,7 +4354,7 @@ var LibraryGL = { glVertexAttribPointer: function(index, size, type, normalized, stride, ptr) { #if FULL_ES2 var cb = GL.currentContext.clientBuffers[index]; -#if ASSERTIONS +#if GL_ASSERTIONS assert(cb, index); #endif if (!GL.currArrayBuffer) { @@ -4382,7 +4382,7 @@ var LibraryGL = { glVertexAttribIPointer: function(index, size, type, stride, ptr) { #if FULL_ES3 var cb = GL.currentContext.clientBuffers[index]; -#if ASSERTIONS +#if GL_ASSERTIONS assert(cb, index); #endif if (!GL.currArrayBuffer) { @@ -4411,7 +4411,7 @@ var LibraryGL = { glEnableVertexAttribArray: function(index) { #if FULL_ES2 var cb = GL.currentContext.clientBuffers[index]; -#if ASSERTIONS +#if GL_ASSERTIONS assert(cb, index); #endif cb.enabled = true; @@ -4423,7 +4423,7 @@ var LibraryGL = { glDisableVertexAttribArray: function(index) { #if FULL_ES2 var cb = GL.currentContext.clientBuffers[index]; -#if ASSERTIONS +#if GL_ASSERTIONS assert(cb, index); #endif cb.enabled = false; From e28c7742c601874eea31e0cd7331535c28fb29cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Sat, 2 Feb 2019 18:36:17 +0200 Subject: [PATCH 11/14] Micro-optimize WebGL context activation. Saves -18 bytes (0.12%) --- src/library_gl.js | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/library_gl.js b/src/library_gl.js index f04b82be849ea..2e61720c4f7e5 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -833,25 +833,19 @@ var LibraryGL = { }, makeContextCurrent: function(contextHandle) { - // Deactivating current context? - if (!contextHandle) { - GLctx = Module.ctx = GL.currentContext = null; - return true; - } - var context = GL.contexts[contextHandle]; - if (!context) { #if GL_DEBUG + if (contextHandle && !GL.contexts[contextHandle]) { #if USE_PTHREADS console.error('GL.makeContextCurrent() failed! WebGL context ' + contextHandle + ' does not exist, or was created on another thread!'); #else console.error('GL.makeContextCurrent() failed! WebGL context ' + contextHandle + ' does not exist!'); #endif -#endif - return false; } - GLctx = Module.ctx = context.GLctx; // Active WebGL context object. - GL.currentContext = context; // Active Emscripten GL layer context object. - return true; +#endif + + GL.currentContext = GL.contexts[contextHandle]; // Active Emscripten GL layer context object. + Module.ctx = GLctx = GL.currentContext && GL.currentContext.GLctx; // Active WebGL context object. + return !(contextHandle && !GLctx); }, getContext: function(contextHandle) { From f4efaccf224ef16900f35b694d3d75643044ad9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Mon, 4 Feb 2019 10:23:03 +0200 Subject: [PATCH 12/14] Micro-optimize WebGL object creation --- src/library_gl.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/library_gl.js b/src/library_gl.js index 2e61720c4f7e5..804dc16ff8c10 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -1749,17 +1749,16 @@ var LibraryGL = { ) { for (var i = 0; i < n; i++) { var buffer = GLctx[createFunction](); - if (!buffer) { + var id = buffer && GL.getNewId(objectTable); + if (buffer) { + buffer.name = id; + objectTable[id] = buffer; + } else { GL.recordError(0x0502 /* GL_INVALID_OPERATION */); #if GL_ASSERTIONS err('GL_INVALID_OPERATION in ' + functionName + ': GLctx.' + createFunction + ' returned null - most likely GL context is lost!'); #endif - while(i < n) {{{ makeSetValue('buffers', 'i++*4', 0, 'i32') }}}; - return; } - var id = GL.getNewId(objectTable); - buffer.name = id; - objectTable[id] = buffer; {{{ makeSetValue('buffers', 'i*4', 'id', 'i32') }}}; } }, From 6144f213a0f80c7b817f7a37ba6a055693a26603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Wed, 6 Feb 2019 18:07:04 +0200 Subject: [PATCH 13/14] Revert unreadable '9e9' and 'if (x > max) max = x;' optimizations from srx/library_gl.js. Regresses hello webgl by 10 bytes (+0.17%) --- src/library_gl.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/library_gl.js b/src/library_gl.js index 804dc16ff8c10..884e31f7e0dd1 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -252,7 +252,7 @@ var LibraryGL = { var source = ''; for (var i = 0; i < count; ++i) { var len = length ? {{{ makeGetValue('length', 'i*4', 'i32') }}} : -1; - source += UTF8ToString({{{ makeGetValue('string', 'i*4', 'i32') }}}, len < 0 ? 9e9/*short abbrv. for infinity*/ : len); + source += UTF8ToString({{{ makeGetValue('string', 'i*4', 'i32') }}}, len < 0 ? undefined : len); } #if LEGACY_GL_EMULATION // Let's see if we need to enable the standard derivatives extension @@ -968,10 +968,7 @@ var LibraryGL = { var u = GLctx.getActiveUniform(p, i); var name = u.name; - var length = name.length + 1; - if (length > ptable.maxUniformLength) { - ptable.maxUniformLength = length; - } + ptable.maxUniformLength = Math.max(ptable.maxUniformLength, name.length+1); // Strip off any trailing array specifier we might have got, e.g. "[0]". var ls = name.lastIndexOf('['); From 3730baede8d504af7f26a5624d4cd09f332f72f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Wed, 6 Feb 2019 22:13:56 +0200 Subject: [PATCH 14/14] Update expected code sizes --- tests/test_other.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_other.py b/tests/test_other.py index 098e3f7b00984..93906cfe5c167 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -8890,8 +8890,8 @@ def test_minimal_runtime_code_size(self): test_cases = [ (asmjs + opts, hello_world_sources, {'a.html': 665, 'a.js': 518, 'a.asm.js': 741, 'a.mem': 6}), (opts, hello_world_sources, {'a.html': 623, 'a.js': 624, 'a.wasm': 86}), - (asmjs + opts, hello_webgl_sources, {'a.html': 665, 'a.js': 5605, 'a.asm.js': 11361, 'a.mem': 321}), - (opts, hello_webgl_sources, {'a.html': 623, 'a.js': 5568, 'a.wasm': 8978}) + (asmjs + opts, hello_webgl_sources, {'a.html': 665, 'a.js': 5403, 'a.asm.js': 11361, 'a.mem': 321}), + (opts, hello_webgl_sources, {'a.html': 623, 'a.js': 5380, 'a.wasm': 8978}) ] success = True