Skip to content

Commit

Permalink
Pass GL context attributes by value, avoiding JS heap accesses. NFC
Browse files Browse the repository at this point in the history
  • Loading branch information
sbc100 committed Jan 29, 2024
1 parent b2fb65e commit 8e7c785
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 54 deletions.
71 changes: 35 additions & 36 deletions src/library_html5_webgl.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ var LibraryHtml5WebGL = {
// emscripten_webgl_create_context() function in JS.
emscripten_webgl_create_context_proxied__proxy: 'sync',
emscripten_webgl_create_context_proxied__deps: ['emscripten_webgl_do_create_context'],
emscripten_webgl_create_context_proxied: (target, attributes) =>
_emscripten_webgl_do_create_context(target, attributes),
emscripten_webgl_create_context_proxied: (target, powerPreference, alpha, depth, stencil, antialias, premultipliedAlpha, preserveDrawingBuffer, failIfMajorPerformanceCaveat, majorVersion, minorVersion, enableExtensionsByDefault, explicitSwapControl, proxyContextToMainThread, renderViaOffscreenBackBuffer) =>
_emscripten_webgl_do_create_context(target, powerPreference, alpha, depth, stencil, antialias, premultipliedAlpha, preserveDrawingBuffer, failIfMajorPerformanceCaveat, majorVersion, minorVersion, enableExtensionsByDefault, explicitSwapControl, proxyContextToMainThread, renderViaOffscreenBackBuffer),

// The other proxied GL commands are defined in C (guarded by the
// __EMSCRIPTEN_OFFSCREEN_FRAMEBUFFER__ definition).
Expand All @@ -51,29 +51,9 @@ var LibraryHtml5WebGL = {
#endif
'$JSEvents', '$emscripten_webgl_power_preferences', '$findEventTarget', '$findCanvasEventTarget'],
// This function performs proxying manually, depending on the style of context that is to be created.
emscripten_webgl_do_create_context: (target, attributes) => {
emscripten_webgl_do_create_context: (target, powerPreference, alpha, depth, stencil, antialias, premultipliedAlpha, preserveDrawingBuffer, failIfMajorPerformanceCaveat, majorVersion, minorVersion, enableExtensionsByDefault, explicitSwapControl, proxyContextToMainThread, renderViaOffscreenBackBuffer) => {
#if ASSERTIONS
assert(attributes);
#endif
var a = attributes >> 2;
var powerPreference = HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.powerPreference }}}>>2)];
var contextAttributes = {
'alpha': !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.alpha }}}>>2)],
'depth': !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.depth }}}>>2)],
'stencil': !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.stencil }}}>>2)],
'antialias': !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.antialias }}}>>2)],
'premultipliedAlpha': !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.premultipliedAlpha }}}>>2)],
'preserveDrawingBuffer': !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.preserveDrawingBuffer }}}>>2)],
'powerPreference': emscripten_webgl_power_preferences[powerPreference],
'failIfMajorPerformanceCaveat': !!HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.failIfMajorPerformanceCaveat }}}>>2)],
// The following are not predefined WebGL context attributes in the WebGL specification, so the property names can be minified by Closure.
majorVersion: HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.majorVersion }}}>>2)],
minorVersion: HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.minorVersion }}}>>2)],
enableExtensionsByDefault: HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.enableExtensionsByDefault }}}>>2)],
explicitSwapControl: HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.explicitSwapControl }}}>>2)],
proxyContextToMainThread: HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.proxyContextToMainThread }}}>>2)],
renderViaOffscreenBackBuffer: HEAP32[a + ({{{ C_STRUCTS.EmscriptenWebGLContextAttributes.renderViaOffscreenBackBuffer }}}>>2)]
};

var canvas = findCanvasEventTarget(target);

Expand All @@ -85,30 +65,30 @@ var LibraryHtml5WebGL = {
// Create a WebGL context that is proxied to main thread if canvas was not
// found on worker, or if explicitly requested to do so.
if (ENVIRONMENT_IS_PTHREAD) {
if (contextAttributes.proxyContextToMainThread === {{{ cDefs.EMSCRIPTEN_WEBGL_CONTEXT_PROXY_ALWAYS }}} ||
(!canvas && contextAttributes.proxyContextToMainThread === {{{ cDefs.EMSCRIPTEN_WEBGL_CONTEXT_PROXY_FALLBACK }}})) {
if (proxyContextToMainThread === {{{ cDefs.EMSCRIPTEN_WEBGL_CONTEXT_PROXY_ALWAYS }}} ||
(!canvas && proxyContextToMainThread === {{{ cDefs.EMSCRIPTEN_WEBGL_CONTEXT_PROXY_FALLBACK }}})) {
// When WebGL context is being proxied via the main thread, we must
// render using an offscreen FBO render target to avoid WebGL's
// "implicit swap when callback exits" behavior. TODO: If
// OffscreenCanvas is supported, explicitSwapControl=true and still
// proxying, then this can be avoided, since OffscreenCanvas enables
// explicit swap control.
#if GL_DEBUG
if (contextAttributes.proxyContextToMainThread === {{{ cDefs.EMSCRIPTEN_WEBGL_CONTEXT_PROXY_ALWAYS }}}) {
if (proxyContextToMainThread === {{{ cDefs.EMSCRIPTEN_WEBGL_CONTEXT_PROXY_ALWAYS }}}) {
dbg('EMSCRIPTEN_WEBGL_CONTEXT_PROXY_ALWAYS enabled, proxying WebGL rendering from pthread to main thread.');
}
if (!canvas && contextAttributes.proxyContextToMainThread === {{{ cDefs.EMSCRIPTEN_WEBGL_CONTEXT_PROXY_FALLBACK }}}) {
if (!canvas && proxyContextToMainThread === {{{ cDefs.EMSCRIPTEN_WEBGL_CONTEXT_PROXY_FALLBACK }}}) {
dbg(`Specified canvas target "${targetStr}" is not an OffscreenCanvas in the current pthread, but EMSCRIPTEN_WEBGL_CONTEXT_PROXY_FALLBACK is set. Proxying WebGL rendering from pthread to main thread.`);
dbg('Performance warning: forcing renderViaOffscreenBackBuffer=true and preserveDrawingBuffer=true since proxying WebGL rendering.');
}
#endif
// We will be proxying - if OffscreenCanvas is supported, we can proxy a
// bit more efficiently by avoiding having to create an Offscreen FBO.
if (typeof OffscreenCanvas == 'undefined') {
{{{ makeSetValue('attributes', C_STRUCTS.EmscriptenWebGLContextAttributes.renderViaOffscreenBackBuffer, '1', 'i32') }}};
{{{ makeSetValue('attributes', C_STRUCTS.EmscriptenWebGLContextAttributes.preserveDrawingBuffer, '1', 'i32') }}};
renderViaOffscreenBackBuffer = 1;
preserveDrawingBuffer = 1;
}
return _emscripten_webgl_create_context_proxied(target, attributes);
return _emscripten_webgl_create_context_proxied(target, powerPreference, alpha, depth, stencil, antialias, premultipliedAlpha, preserveDrawingBuffer, failIfMajorPerformanceCaveat, majorVersion, minorVersion, enableExtensionsByDefault, explicitSwapControl, proxyContextToMainThread, renderViaOffscreenBackBuffer);
}
}
#endif
Expand All @@ -128,13 +108,13 @@ var LibraryHtml5WebGL = {
else if (typeof HTMLCanvasElement != 'undefined' && canvas instanceof HTMLCanvasElement) dbg(`emscripten_webgl_create_context: Creating an HTMLCanvasElement-based WebGL context on target "${targetStr}"`);
#endif
if (contextAttributes.explicitSwapControl) {
if (explicitSwapControl) {
var supportsOffscreenCanvas = canvas.transferControlToOffscreen || (typeof OffscreenCanvas != 'undefined' && canvas instanceof OffscreenCanvas);
if (!supportsOffscreenCanvas) {
#if OFFSCREEN_FRAMEBUFFER
if (!contextAttributes.renderViaOffscreenBackBuffer) {
contextAttributes.renderViaOffscreenBackBuffer = true;
if (!renderViaOffscreenBackBuffer) {
renderViaOffscreenBackBuffer = true;
#if GL_DEBUG
dbg('emscripten_webgl_create_context: Performance warning, OffscreenCanvas is not supported but explicitSwapControl was requested, so force-enabling renderViaOffscreenBackBuffer=true to allow explicit swapping!');
#endif
Expand Down Expand Up @@ -169,14 +149,14 @@ var LibraryHtml5WebGL = {
}
#else // !OFFSCREENCANVAS_SUPPORT
#if OFFSCREEN_FRAMEBUFFER
if (contextAttributes.explicitSwapControl && !contextAttributes.renderViaOffscreenBackBuffer) {
contextAttributes.renderViaOffscreenBackBuffer = true;
if (explicitSwapControl && !renderViaOffscreenBackBuffer) {
renderViaOffscreenBackBuffer = true;
#if GL_DEBUG
dbg('emscripten_webgl_create_context: Performance warning, not building with OffscreenCanvas support enabled but explicitSwapControl was requested, so force-enabling renderViaOffscreenBackBuffer=true to allow explicit swapping!');
#endif
}
#else
if (contextAttributes.explicitSwapControl) {
if (explicitSwapControl) {
#if GL_DEBUG
dbg('emscripten_webgl_create_context failed: explicitSwapControl is not supported, please rebuild with -sOFFSCREENCANVAS_SUPPORT to enable targeting the experimental OffscreenCanvas specification, or rebuild with -sOFFSCREEN_FRAMEBUFFER to emulate explicitSwapControl in the absence of OffscreenCanvas support!');
#endif
Expand All @@ -186,6 +166,25 @@ var LibraryHtml5WebGL = {
#endif // ~!OFFSCREENCANVAS_SUPPORT
var contextAttributes = {
'alpha': alpha,
'depth': depth,
'stencil': stencil,
'antialias': antialias,
'premultipliedAlpha': premultipliedAlpha,
'preserveDrawingBuffer': preserveDrawingBuffer,
'powerPreference': emscripten_webgl_power_preferences[powerPreference],
'failIfMajorPerformanceCaveat': failIfMajorPerformanceCaveat,
// The following are not predefined WebGL context attributes in the WebGL
// specification, so the property names can be minified by Closure.
majorVersion: majorVersion,
minorVersion: minorVersion,
enableExtensionsByDefault: enableExtensionsByDefault,
explicitSwapControl: explicitSwapControl,
proxyContextToMainThread: proxyContextToMainThread,
renderViaOffscreenBackBuffer: renderViaOffscreenBackBuffer,
};
var contextHandle = GL.createContext(canvas, contextAttributes);
return contextHandle;
},
Expand Down
9 changes: 7 additions & 2 deletions system/lib/gl/webgl1.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,20 @@ static inline pthread_t GetCurrentTargetThread() {
return GetOwningThread(emscripten_webgl_get_current_context());
}

EMSCRIPTEN_WEBGL_CONTEXT_HANDLE emscripten_webgl_create_context(const char *target, const EmscriptenWebGLContextAttributes *attributes) {
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE emscripten_webgl_create_context(const char *target, const EmscriptenWebGLContextAttributes *attr) {
GL_FUNCTION_TRACE();
if (!attributes) {
emscripten_err("emscripten_webgl_create_context: attributes pointer is null!");
return 0;
}
pthread_once(&tlsInit, InitWebGLTls);

return emscripten_webgl_do_create_context(target, attributes);
return emscripten_webgl_do_create_context(target, attr.powerPreference,
attr.alpha, depth, attr.stencil, attr.antialias, attr.premultipliedAlpha,
attr.preserveDrawingBuffer, attr.failIfMajorPerformanceCaveat,
attr.majorVersion, attr.minorVersion, attr.enableExtensionsByDefault,
attr.explicitSwapControl, attr.proxyContextToMainThread,
attr.renderViaOffscreenBackBuffer);
}

EMSCRIPTEN_RESULT emscripten_webgl_make_context_current(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context) {
Expand Down
8 changes: 4 additions & 4 deletions test/code_size/hello_webgl2_wasm.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.html": 569,
"a.html.gz": 379,
"a.js": 4593,
"a.js.gz": 2369,
"a.js": 4510,
"a.js.gz": 2337,
"a.wasm": 10451,
"a.wasm.gz": 6724,
"total": 15613,
"total_gz": 9472
"total": 15530,
"total_gz": 9440
}
8 changes: 4 additions & 4 deletions test/code_size/hello_webgl2_wasm2js.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.html": 567,
"a.html.gz": 379,
"a.js": 17937,
"a.js.gz": 8074,
"a.js": 17854,
"a.js.gz": 8061,
"a.mem": 3123,
"a.mem.gz": 2693,
"total": 21627,
"total_gz": 11146
"total": 21544,
"total_gz": 11133
}
8 changes: 4 additions & 4 deletions test/code_size/hello_webgl_wasm.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.html": 569,
"a.html.gz": 379,
"a.js": 4080,
"a.js.gz": 2198,
"a.js": 3996,
"a.js.gz": 2166,
"a.wasm": 10451,
"a.wasm.gz": 6724,
"total": 15100,
"total_gz": 9301
"total": 15016,
"total_gz": 9269
}
8 changes: 4 additions & 4 deletions test/code_size/hello_webgl_wasm2js.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.html": 567,
"a.html.gz": 379,
"a.js": 17415,
"a.js.gz": 7891,
"a.js": 17331,
"a.js.gz": 7868,
"a.mem": 3123,
"a.mem.gz": 2693,
"total": 21105,
"total_gz": 10963
"total": 21021,
"total_gz": 10940
}

0 comments on commit 8e7c785

Please sign in to comment.