Skip to content

Commit 38b559c

Browse files
authored
Optimize -s MIN_WEBGL_VERSION=2 and WebGL context creation (#12623)
* Micro-optimize emscripten_webgl_do_create_context(). * Drop WebGL 1 specific code when -s MIN_WEBGL_VERSION=2 is used. * Address review
1 parent b2191bd commit 38b559c

File tree

2 files changed

+53
-39
lines changed

2 files changed

+53
-39
lines changed

src/library_html5_webgl.js

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -74,23 +74,25 @@ var LibraryHtml5WebGL = {
7474
#if ASSERTIONS
7575
assert(attributes);
7676
#endif
77-
var contextAttributes = {};
7877
var a = attributes >> 2;
79-
contextAttributes['alpha'] = !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.alpha }}}>>2)];
80-
contextAttributes['depth'] = !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.depth }}}>>2)];
81-
contextAttributes['stencil'] = !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.stencil }}}>>2)];
82-
contextAttributes['antialias'] = !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.antialias }}}>>2)];
83-
contextAttributes['premultipliedAlpha'] = !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.premultipliedAlpha }}}>>2)];
84-
contextAttributes['preserveDrawingBuffer'] = !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.preserveDrawingBuffer }}}>>2)];
8578
var powerPreference = HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.powerPreference }}}>>2)];
86-
contextAttributes['powerPreference'] = __emscripten_webgl_power_preferences[powerPreference];
87-
contextAttributes['failIfMajorPerformanceCaveat'] = !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.failIfMajorPerformanceCaveat }}}>>2)];
88-
contextAttributes.majorVersion = HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.majorVersion }}}>>2)];
89-
contextAttributes.minorVersion = HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.minorVersion }}}>>2)];
90-
contextAttributes.enableExtensionsByDefault = HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.enableExtensionsByDefault }}}>>2)];
91-
contextAttributes.explicitSwapControl = HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.explicitSwapControl }}}>>2)];
92-
contextAttributes.proxyContextToMainThread = HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.proxyContextToMainThread }}}>>2)];
93-
contextAttributes.renderViaOffscreenBackBuffer = HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.renderViaOffscreenBackBuffer }}}>>2)];
79+
var contextAttributes = {
80+
'alpha': !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.alpha }}}>>2)],
81+
'depth': !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.depth }}}>>2)],
82+
'stencil': !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.stencil }}}>>2)],
83+
'antialias': !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.antialias }}}>>2)],
84+
'premultipliedAlpha': !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.premultipliedAlpha }}}>>2)],
85+
'preserveDrawingBuffer': !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.preserveDrawingBuffer }}}>>2)],
86+
'powerPreference': __emscripten_webgl_power_preferences[powerPreference],
87+
'failIfMajorPerformanceCaveat': !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.failIfMajorPerformanceCaveat }}}>>2)],
88+
// The following are not predefined WebGL context attributes in the WebGL specification, so the property names can be minified by Closure.
89+
majorVersion: HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.majorVersion }}}>>2)],
90+
minorVersion: HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.minorVersion }}}>>2)],
91+
enableExtensionsByDefault: HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.enableExtensionsByDefault }}}>>2)],
92+
explicitSwapControl: HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.explicitSwapControl }}}>>2)],
93+
proxyContextToMainThread: HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.proxyContextToMainThread }}}>>2)],
94+
renderViaOffscreenBackBuffer: HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.renderViaOffscreenBackBuffer }}}>>2)]
95+
};
9496

9597
var canvas = findCanvasEventTarget(target);
9698

src/library_webgl.js

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@
88
// of 9 and 16.
99
{{{ GL_POOL_TEMP_BUFFERS_SIZE = 2*9*16 }}} // = 288
1010

11+
{{{
12+
global.isCurrentContextWebGL2 = function isCurrentContextWebGL2() {
13+
if (MIN_WEBGL_VERSION >= 2) return 'true';
14+
if (MAX_WEBGL_VERSION <= 1) return 'false';
15+
return 'GL.currentContext.version >= 2';
16+
}
17+
}}}
18+
1119
var LibraryGL = {
1220

1321
// For functions such as glDrawBuffers, glInvalidateFramebuffer and glInvalidateSubFramebuffer that need to pass a short array to the WebGL API,
@@ -483,7 +491,7 @@ var LibraryGL = {
483491
break;
484492
default:
485493
#if MAX_WEBGL_VERSION >= 2
486-
if (GL.currentContext.version >= 2) {
494+
if ({{{ isCurrentContextWebGL2() }}}) {
487495
if (dataType == 0x8368 /* GL_UNSIGNED_INT_2_10_10_10_REV */ || dataType == 0x8D9F /* GL_INT_2_10_10_10_REV */) {
488496
sizeBytes = 4;
489497
break;
@@ -618,6 +626,9 @@ var LibraryGL = {
618626
} else {
619627
#endif
620628

629+
#if MIN_WEBGL_VERSION >= 2
630+
var ctx = canvas.getContext("webgl2", webGLContextAttributes);
631+
#else
621632
var ctx =
622633
#if MAX_WEBGL_VERSION >= 2
623634
(webGLContextAttributes.majorVersion > 1)
@@ -635,6 +646,7 @@ var LibraryGL = {
635646
|| canvas.getContext("experimental-webgl", webGLContextAttributes)
636647
#endif
637648
);
649+
#endif // MAX_WEBGL_VERSION >= 2
638650

639651
#if GL_PREINITIALIZED_CONTEXT
640652
}
@@ -1214,7 +1226,7 @@ var LibraryGL = {
12141226
var glVersion = GLctx.getParameter(0x1F02 /*GL_VERSION*/);
12151227
// return GLES version string corresponding to the version of the WebGL context
12161228
#if MAX_WEBGL_VERSION >= 2
1217-
if (GL.currentContext.version >= 2) glVersion = 'OpenGL ES 3.0 (' + glVersion + ')';
1229+
if ({{{ isCurrentContextWebGL2() }}}) glVersion = 'OpenGL ES 3.0 (' + glVersion + ')';
12181230
else
12191231
#endif
12201232
{
@@ -1448,7 +1460,7 @@ var LibraryGL = {
14481460
glCompressedTexImage2D__sig: 'viiiiiiii',
14491461
glCompressedTexImage2D: function(target, level, internalFormat, width, height, border, imageSize, data) {
14501462
#if MAX_WEBGL_VERSION >= 2
1451-
if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
1463+
if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
14521464
if (GLctx.currentPixelUnpackBufferBinding) {
14531465
GLctx['compressedTexImage2D'](target, level, internalFormat, width, height, border, imageSize, data);
14541466
} else {
@@ -1464,7 +1476,7 @@ var LibraryGL = {
14641476
glCompressedTexSubImage2D__sig: 'viiiiiiiii',
14651477
glCompressedTexSubImage2D: function(target, level, xoffset, yoffset, width, height, format, imageSize, data) {
14661478
#if MAX_WEBGL_VERSION >= 2
1467-
if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
1479+
if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
14681480
if (GLctx.currentPixelUnpackBufferBinding) {
14691481
GLctx['compressedTexSubImage2D'](target, level, xoffset, yoffset, width, height, format, imageSize, data);
14701482
} else {
@@ -1544,7 +1556,7 @@ var LibraryGL = {
15441556
glTexImage2D: function(target, level, internalFormat, width, height, border, format, type, pixels) {
15451557
#if MAX_WEBGL_VERSION >= 2
15461558
#if WEBGL2_BACKWARDS_COMPATIBILITY_EMULATION
1547-
if (GL.currentContext.version >= 2) {
1559+
if ({{{ isCurrentContextWebGL2() }}}) {
15481560
// WebGL 1 unsized texture internalFormats are no longer supported in WebGL 2, so patch those format
15491561
// enums to the ones that are present in WebGL 2.
15501562
if (format == 0x1902/*GL_DEPTH_COMPONENT*/ && internalFormat == 0x1902/*GL_DEPTH_COMPONENT*/ && type == 0x1405/*GL_UNSIGNED_INT*/) {
@@ -1561,7 +1573,7 @@ var LibraryGL = {
15611573
}
15621574
}
15631575
#endif
1564-
if (GL.currentContext.version >= 2) {
1576+
if ({{{ isCurrentContextWebGL2() }}}) {
15651577
// WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
15661578
if (GLctx.currentPixelUnpackBufferBinding) {
15671579
GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
@@ -1586,14 +1598,14 @@ var LibraryGL = {
15861598
glTexSubImage2D: function(target, level, xoffset, yoffset, width, height, format, type, pixels) {
15871599
#if MAX_WEBGL_VERSION >= 2
15881600
#if WEBGL2_BACKWARDS_COMPATIBILITY_EMULATION
1589-
if (GL.currentContext.version >= 2) {
1601+
if ({{{ isCurrentContextWebGL2() }}}) {
15901602
// In WebGL 1 to do half float textures, one uses the type enum GL_HALF_FLOAT_OES, but in
15911603
// WebGL 2 when half float textures were adopted to the core spec, the enum changed value
15921604
// which breaks backwards compatibility. Route old enum number to the new one.
15931605
if (type == 0x8d61/*GL_HALF_FLOAT_OES*/) type = 0x140B /*GL_HALF_FLOAT*/;
15941606
}
15951607
#endif
1596-
if (GL.currentContext.version >= 2) {
1608+
if ({{{ isCurrentContextWebGL2() }}}) {
15971609
// WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
15981610
if (GLctx.currentPixelUnpackBufferBinding) {
15991611
GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
@@ -1619,7 +1631,7 @@ var LibraryGL = {
16191631
],
16201632
glReadPixels: function(x, y, width, height, format, type, pixels) {
16211633
#if MAX_WEBGL_VERSION >= 2
1622-
if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
1634+
if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
16231635
if (GLctx.currentPixelPackBufferBinding) {
16241636
GLctx.readPixels(x, y, width, height, format, type, pixels);
16251637
} else {
@@ -1800,7 +1812,7 @@ var LibraryGL = {
18001812
#endif
18011813

18021814
#if MAX_WEBGL_VERSION >= 2
1803-
if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
1815+
if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
18041816
if (data) {
18051817
GLctx.bufferData(target, HEAPU8, usage, data, size);
18061818
} else {
@@ -1819,7 +1831,7 @@ var LibraryGL = {
18191831
glBufferSubData__sig: 'viiii',
18201832
glBufferSubData: function(target, offset, size, data) {
18211833
#if MAX_WEBGL_VERSION >= 2
1822-
if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
1834+
if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
18231835
GLctx.bufferSubData(target, offset, HEAPU8, data, size);
18241836
return;
18251837
}
@@ -2243,7 +2255,7 @@ var LibraryGL = {
22432255
#else
22442256

22452257
#if MAX_WEBGL_VERSION >= 2
2246-
if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
2258+
if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
22472259
GLctx.uniform1iv(GL.uniforms[location], HEAP32, value>>2, count);
22482260
return;
22492261
}
@@ -2286,7 +2298,7 @@ var LibraryGL = {
22862298
#else
22872299

22882300
#if MAX_WEBGL_VERSION >= 2
2289-
if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
2301+
if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
22902302
GLctx.uniform2iv(GL.uniforms[location], HEAP32, value>>2, count*2);
22912303
return;
22922304
}
@@ -2330,7 +2342,7 @@ var LibraryGL = {
23302342
#else
23312343

23322344
#if MAX_WEBGL_VERSION >= 2
2333-
if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
2345+
if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
23342346
GLctx.uniform3iv(GL.uniforms[location], HEAP32, value>>2, count*3);
23352347
return;
23362348
}
@@ -2375,7 +2387,7 @@ var LibraryGL = {
23752387
#else
23762388

23772389
#if MAX_WEBGL_VERSION >= 2
2378-
if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
2390+
if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
23792391
GLctx.uniform4iv(GL.uniforms[location], HEAP32, value>>2, count*4);
23802392
return;
23812393
}
@@ -2421,7 +2433,7 @@ var LibraryGL = {
24212433
#else
24222434

24232435
#if MAX_WEBGL_VERSION >= 2
2424-
if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
2436+
if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
24252437
GLctx.uniform1fv(GL.uniforms[location], HEAPF32, value>>2, count);
24262438
return;
24272439
}
@@ -2464,7 +2476,7 @@ var LibraryGL = {
24642476
#else
24652477

24662478
#if MAX_WEBGL_VERSION >= 2
2467-
if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
2479+
if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
24682480
GLctx.uniform2fv(GL.uniforms[location], HEAPF32, value>>2, count*2);
24692481
return;
24702482
}
@@ -2508,7 +2520,7 @@ var LibraryGL = {
25082520
#else
25092521

25102522
#if MAX_WEBGL_VERSION >= 2
2511-
if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
2523+
if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
25122524
GLctx.uniform3fv(GL.uniforms[location], HEAPF32, value>>2, count*3);
25132525
return;
25142526
}
@@ -2553,7 +2565,7 @@ var LibraryGL = {
25532565
#else
25542566

25552567
#if MAX_WEBGL_VERSION >= 2
2556-
if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
2568+
if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
25572569
GLctx.uniform4fv(GL.uniforms[location], HEAPF32, value>>2, count*4);
25582570
return;
25592571
}
@@ -2603,7 +2615,7 @@ var LibraryGL = {
26032615
#else
26042616

26052617
#if MAX_WEBGL_VERSION >= 2
2606-
if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
2618+
if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
26072619
GLctx.uniformMatrix2fv(GL.uniforms[location], !!transpose, HEAPF32, value>>2, count*4);
26082620
return;
26092621
}
@@ -2649,7 +2661,7 @@ var LibraryGL = {
26492661
#else
26502662

26512663
#if MAX_WEBGL_VERSION >= 2
2652-
if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
2664+
if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
26532665
GLctx.uniformMatrix3fv(GL.uniforms[location], !!transpose, HEAPF32, value>>2, count*9);
26542666
return;
26552667
}
@@ -2700,7 +2712,7 @@ var LibraryGL = {
27002712
#else
27012713

27022714
#if MAX_WEBGL_VERSION >= 2
2703-
if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
2715+
if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
27042716
GLctx.uniformMatrix4fv(GL.uniforms[location], !!transpose, HEAPF32, value>>2, count*16);
27052717
return;
27062718
}
@@ -2896,7 +2908,7 @@ var LibraryGL = {
28962908
var source = GL.getSource(shader, count, string, length);
28972909

28982910
#if WEBGL2_BACKWARDS_COMPATIBILITY_EMULATION
2899-
if (GL.currentContext.version >= 2) {
2911+
if ({{{ isCurrentContextWebGL2() }}}) {
29002912
// If a WebGL 1 shader happens to use GL_EXT_shader_texture_lod extension,
29012913
// it will not compile on WebGL 2, because WebGL 2 no longer supports that
29022914
// extension for WebGL 1 shaders. Therefore upgrade shaders to WebGL 2
@@ -3822,7 +3834,7 @@ var LibraryGL = {
38223834
GL.mappedBuffers[buffer] = null;
38233835

38243836
if (!(mapping.access & 0x10)) /* GL_MAP_FLUSH_EXPLICIT_BIT */
3825-
if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
3837+
if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
38263838
GLctx.bufferSubData(target, mapping.offset, HEAPU8, mapping.mem, mapping.length);
38273839
} else {
38283840
GLctx.bufferSubData(target, mapping.offset, HEAPU8.subarray(mapping.mem, mapping.mem+mapping.length));

0 commit comments

Comments
 (0)