Skip to content

Commit e5df8fc

Browse files
authored
Improve tests/minimal_webgl for teaching purposes. Improve WebGL validation MIN_WEBGL_VERSION=2 mode. (#12047)
1 parent 270c58b commit e5df8fc

File tree

3 files changed

+151
-29
lines changed

3 files changed

+151
-29
lines changed

src/library_webgl.js

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@ var LibraryGL = {
531531
var realf = 'real_' + f;
532532
glCtx[realf] = glCtx[f];
533533
var numArgs = GL.webGLFunctionLengths[f]; // On Firefox & Chrome, could do "glCtx[realf].length", but that doesn't work on Edge, which always reports 0.
534-
if (numArgs === undefined) throw 'Unexpected WebGL function ' + f;
534+
if (numArgs === undefined) console.warn('Unexpected WebGL function ' + f + ' when binding TRACE_WEBGL_CALLS');
535535
var contextHandle = glCtx.canvas.GLctxObject.handle;
536536
var threadId = (typeof _pthread_self !== 'undefined') ? _pthread_self : function() { return 1; };
537537
// Accessing 'arguments' is super slow, so to avoid overhead, statically reason the number of arguments.
@@ -548,7 +548,7 @@ var LibraryGL = {
548548
case 9: glCtx[f] = function webgl_9(a1, a2, a3, a4, a5, a6, a7, a8, a9) { var ret = glCtx[realf](a1, a2, a3, a4, a5, a6, a7, a8, a9); console.error('[Thread ' + threadId() + ', GL ctx: ' + contextHandle + ']: ' + f + '('+a1+', ' + a2 +', ' + a3 +', ' + a4 +', ' + a5 +', ' + a6 +', ' + a7 +', ' + a8 +', ' + a9 +') -> ' + ret); return ret; }; break;
549549
case 10: glCtx[f] = function webgl_10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) { var ret = glCtx[realf](a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); console.error('[Thread ' + threadId() + ', GL ctx: ' + contextHandle + ']: ' + f + '('+a1+', ' + a2 +', ' + a3 +', ' + a4 +', ' + a5 +', ' + a6 +', ' + a7 +', ' + a8 +', ' + a9 +', ' + a10 +') -> ' + ret); return ret; }; break;
550550
case 11: glCtx[f] = function webgl_11(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) { var ret = glCtx[realf](a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); console.error('[Thread ' + threadId() + ', GL ctx: ' + contextHandle + ']: ' + f + '('+a1+', ' + a2 +', ' + a3 +', ' + a4 +', ' + a5 +', ' + a6 +', ' + a7 +', ' + a8 +', ' + a9 +', ' + a10 +', ' + a11 +') -> ' + ret); return ret; }; break;
551-
default: throw 'hookWebGL failed! Unexpected length ' + glCtx[realf].length;
551+
default: console.warn('hookWebGL failed! Unexpected length ' + glCtx[realf].length);
552552
}
553553
},
554554

@@ -2246,7 +2246,10 @@ var LibraryGL = {
22462246
assert((value & 3) == 0, 'Pointer to integer data passed to glUniform1iv must be aligned to four bytes!');
22472247
#endif
22482248

2249-
#if MIN_WEBGL_VERSION == 2
2249+
#if MIN_WEBGL_VERSION >= 2
2250+
#if GL_ASSERTIONS
2251+
assert(GL.currentContext.version >= 2);
2252+
#endif
22502253
GLctx.uniform1iv(GL.uniforms[location], HEAP32, value>>2, count);
22512254
#else
22522255

@@ -2273,7 +2276,7 @@ var LibraryGL = {
22732276
#endif
22742277
}
22752278
GLctx.uniform1iv(GL.uniforms[location], view);
2276-
#endif // MIN_WEBGL_VERSION == 2
2279+
#endif // MIN_WEBGL_VERSION >= 2
22772280
},
22782281

22792282
glUniform2iv__sig: 'viii',
@@ -2286,7 +2289,10 @@ var LibraryGL = {
22862289
assert((value & 3) == 0, 'Pointer to integer data passed to glUniform2iv must be aligned to four bytes!');
22872290
#endif
22882291

2289-
#if MIN_WEBGL_VERSION == 2
2292+
#if MIN_WEBGL_VERSION >= 2
2293+
#if GL_ASSERTIONS
2294+
assert(GL.currentContext.version >= 2);
2295+
#endif
22902296
GLctx.uniform2iv(GL.uniforms[location], HEAP32, value>>2, count*2);
22912297
#else
22922298

@@ -2314,7 +2320,7 @@ var LibraryGL = {
23142320
#endif
23152321
}
23162322
GLctx.uniform2iv(GL.uniforms[location], view);
2317-
#endif // MIN_WEBGL_VERSION == 2
2323+
#endif // MIN_WEBGL_VERSION >= 2
23182324
},
23192325

23202326
glUniform3iv__sig: 'viii',
@@ -2327,7 +2333,10 @@ var LibraryGL = {
23272333
assert((value & 3) == 0, 'Pointer to integer data passed to glUniform3iv must be aligned to four bytes!');
23282334
#endif
23292335

2330-
#if MIN_WEBGL_VERSION == 2
2336+
#if MIN_WEBGL_VERSION >= 2
2337+
#if GL_ASSERTIONS
2338+
assert(GL.currentContext.version >= 2);
2339+
#endif
23312340
GLctx.uniform3iv(GL.uniforms[location], HEAP32, value>>2, count*3);
23322341
#else
23332342

@@ -2356,7 +2365,7 @@ var LibraryGL = {
23562365
#endif
23572366
}
23582367
GLctx.uniform3iv(GL.uniforms[location], view);
2359-
#endif // MIN_WEBGL_VERSION == 2
2368+
#endif // MIN_WEBGL_VERSION >= 2
23602369
},
23612370

23622371
glUniform4iv__sig: 'viii',
@@ -2369,7 +2378,10 @@ var LibraryGL = {
23692378
assert((value & 3) == 0, 'Pointer to integer data passed to glUniform4iv must be aligned to four bytes!');
23702379
#endif
23712380

2372-
#if MIN_WEBGL_VERSION == 2
2381+
#if MIN_WEBGL_VERSION >= 2
2382+
#if GL_ASSERTIONS
2383+
assert(GL.currentContext.version >= 2);
2384+
#endif
23732385
GLctx.uniform4iv(GL.uniforms[location], HEAP32, value>>2, count*4);
23742386
#else
23752387

@@ -2399,7 +2411,7 @@ var LibraryGL = {
23992411
#endif
24002412
}
24012413
GLctx.uniform4iv(GL.uniforms[location], view);
2402-
#endif // MIN_WEBGL_VERSION == 2
2414+
#endif // MIN_WEBGL_VERSION >= 2
24032415
},
24042416

24052417
glUniform1fv__sig: 'viii',
@@ -2412,7 +2424,10 @@ var LibraryGL = {
24122424
assert((value & 3) == 0, 'Pointer to float data passed to glUniform1fv must be aligned to four bytes!');
24132425
#endif
24142426

2415-
#if MIN_WEBGL_VERSION == 2
2427+
#if MIN_WEBGL_VERSION >= 2
2428+
#if GL_ASSERTIONS
2429+
assert(GL.currentContext.version >= 2);
2430+
#endif
24162431
GLctx.uniform1fv(GL.uniforms[location], HEAPF32, value>>2, count);
24172432
#else
24182433

@@ -2439,7 +2454,7 @@ var LibraryGL = {
24392454
#endif
24402455
}
24412456
GLctx.uniform1fv(GL.uniforms[location], view);
2442-
#endif // MIN_WEBGL_VERSION == 2
2457+
#endif // MIN_WEBGL_VERSION >= 2
24432458
},
24442459

24452460
glUniform2fv__sig: 'viii',
@@ -2452,7 +2467,10 @@ var LibraryGL = {
24522467
assert((value & 3) == 0, 'Pointer to float data passed to glUniform2fv must be aligned to four bytes!');
24532468
#endif
24542469

2455-
#if MIN_WEBGL_VERSION == 2
2470+
#if MIN_WEBGL_VERSION >= 2
2471+
#if GL_ASSERTIONS
2472+
assert(GL.currentContext.version >= 2);
2473+
#endif
24562474
GLctx.uniform2fv(GL.uniforms[location], HEAPF32, value>>2, count*2);
24572475
#else
24582476

@@ -2480,7 +2498,7 @@ var LibraryGL = {
24802498
#endif
24812499
}
24822500
GLctx.uniform2fv(GL.uniforms[location], view);
2483-
#endif // MIN_WEBGL_VERSION == 2
2501+
#endif // MIN_WEBGL_VERSION >= 2
24842502
},
24852503

24862504
glUniform3fv__sig: 'viii',
@@ -2493,7 +2511,10 @@ var LibraryGL = {
24932511
assert((value & 3) == 0, 'Pointer to float data passed to glUniform3fv must be aligned to four bytes!' + value);
24942512
#endif
24952513

2496-
#if MIN_WEBGL_VERSION == 2
2514+
#if MIN_WEBGL_VERSION >= 2
2515+
#if GL_ASSERTIONS
2516+
assert(GL.currentContext.version >= 2);
2517+
#endif
24972518
GLctx.uniform3fv(GL.uniforms[location], HEAPF32, value>>2, count*3);
24982519
#else
24992520

@@ -2522,7 +2543,7 @@ var LibraryGL = {
25222543
#endif
25232544
}
25242545
GLctx.uniform3fv(GL.uniforms[location], view);
2525-
#endif // MIN_WEBGL_VERSION == 2
2546+
#endif // MIN_WEBGL_VERSION >= 2
25262547
},
25272548

25282549
glUniform4fv__sig: 'viii',
@@ -2535,7 +2556,10 @@ var LibraryGL = {
25352556
assert((value & 3) == 0, 'Pointer to float data passed to glUniform4fv must be aligned to four bytes!');
25362557
#endif
25372558

2538-
#if MIN_WEBGL_VERSION == 2
2559+
#if MIN_WEBGL_VERSION >= 2
2560+
#if GL_ASSERTIONS
2561+
assert(GL.currentContext.version >= 2);
2562+
#endif
25392563
GLctx.uniform4fv(GL.uniforms[location], HEAPF32, value>>2, count*4);
25402564
#else
25412565

@@ -2569,7 +2593,7 @@ var LibraryGL = {
25692593
#endif
25702594
}
25712595
GLctx.uniform4fv(GL.uniforms[location], view);
2572-
#endif // MIN_WEBGL_VERSION == 2
2596+
#endif // MIN_WEBGL_VERSION >= 2
25732597
},
25742598

25752599
glUniformMatrix2fv__sig: 'viiii',
@@ -2582,7 +2606,10 @@ var LibraryGL = {
25822606
assert((value & 3) == 0, 'Pointer to float data passed to glUniformMatrix2fv must be aligned to four bytes!');
25832607
#endif
25842608

2585-
#if MIN_WEBGL_VERSION == 2
2609+
#if MIN_WEBGL_VERSION >= 2
2610+
#if GL_ASSERTIONS
2611+
assert(GL.currentContext.version >= 2);
2612+
#endif
25862613
GLctx.uniformMatrix2fv(GL.uniforms[location], !!transpose, HEAPF32, value>>2, count*4);
25872614
#else
25882615

@@ -2612,7 +2639,7 @@ var LibraryGL = {
26122639
#endif
26132640
}
26142641
GLctx.uniformMatrix2fv(GL.uniforms[location], !!transpose, view);
2615-
#endif // MIN_WEBGL_VERSION == 2
2642+
#endif // MIN_WEBGL_VERSION >= 2
26162643
},
26172644

26182645
glUniformMatrix3fv__sig: 'viiii',
@@ -2625,7 +2652,10 @@ var LibraryGL = {
26252652
assert((value & 3) == 0, 'Pointer to float data passed to glUniformMatrix3fv must be aligned to four bytes!');
26262653
#endif
26272654

2628-
#if MIN_WEBGL_VERSION == 2
2655+
#if MIN_WEBGL_VERSION >= 2
2656+
#if GL_ASSERTIONS
2657+
assert(GL.currentContext.version >= 2);
2658+
#endif
26292659
GLctx.uniformMatrix3fv(GL.uniforms[location], !!transpose, HEAPF32, value>>2, count*9);
26302660
#else
26312661

@@ -2660,7 +2690,7 @@ var LibraryGL = {
26602690
#endif
26612691
}
26622692
GLctx.uniformMatrix3fv(GL.uniforms[location], !!transpose, view);
2663-
#endif // MIN_WEBGL_VERSION == 2
2693+
#endif // MIN_WEBGL_VERSION >= 2
26642694
},
26652695

26662696
glUniformMatrix4fv__sig: 'viiii',
@@ -2673,7 +2703,10 @@ var LibraryGL = {
26732703
assert((value & 3) == 0, 'Pointer to float data passed to glUniformMatrix4fv must be aligned to four bytes!');
26742704
#endif
26752705

2676-
#if MIN_WEBGL_VERSION == 2
2706+
#if MIN_WEBGL_VERSION >= 2
2707+
#if GL_ASSERTIONS
2708+
assert(GL.currentContext.version >= 2);
2709+
#endif
26772710
GLctx.uniformMatrix4fv(GL.uniforms[location], !!transpose, HEAPF32, value>>2, count*16);
26782711
#else
26792712

@@ -2719,7 +2752,7 @@ var LibraryGL = {
27192752
#endif
27202753
}
27212754
GLctx.uniformMatrix4fv(GL.uniforms[location], !!transpose, view);
2722-
#endif // MIN_WEBGL_VERSION == 2
2755+
#endif // MIN_WEBGL_VERSION >= 2
27232756
},
27242757

27252758
glBindBuffer__sig: 'vii',

tests/minimal_webgl/CMakeLists.txt

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
cmake_minimum_required(VERSION 2.8)
2+
3+
# Default to release build if not specified
4+
if(NOT CMAKE_BUILD_TYPE)
5+
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
6+
endif()
7+
8+
project(minimal_webgl)
9+
10+
macro(append_linker_flags FLAGS)
11+
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAGS}")
12+
endmacro()
13+
14+
if (EMSCRIPTEN)
15+
set(CMAKE_EXECUTABLE_SUFFIX ".html")
16+
17+
# Link in the JS library file for support code
18+
append_linker_flags("--js-library ${CMAKE_CURRENT_LIST_DIR}/library_js.js")
19+
20+
# Link in to WebGL/GLES system library
21+
append_linker_flags("-lGL")
22+
23+
# Enable Closure compiler for aggressive JS size minification
24+
append_linker_flags("--closure 1")
25+
26+
# When marshalling C UTF-8 strings across the JS<->Wasm language boundary, favor smallest generated code size
27+
# rather than performance
28+
append_linker_flags("-s TEXTDECODER=2")
29+
30+
# Enable aggressive MINIMAL_RUNTIME mode.
31+
append_linker_flags("-s MINIMAL_RUNTIME=2")
32+
33+
# Require WebGL 2 support in target browser, for smallest generated code size. (pass -s MIN_WEBGL_VERSION=1 to dual-target WebGL 1 and WebGL 2)
34+
append_linker_flags("-s MIN_WEBGL_VERSION=2 -s MAX_WEBGL_VERSION=2")
35+
36+
# Tell the example code in webgl.c that we are only targeting WebGL 2.
37+
add_definitions(-DMAX_WEBGL_VERSION=2)
38+
39+
# The generated build output is only to be expected to be run in a web browser, never in a native CLI shell, or in a web worker.
40+
append_linker_flags("-s ENVIRONMENT=web")
41+
42+
# Choose the oldest browser versions that should be supported. The higher minimum bar you choose, the less
43+
# emulation code may be present for old browser quirks.
44+
append_linker_flags("-s MIN_FIREFOX_VERSION=70")
45+
append_linker_flags("-s MIN_SAFARI_VERSION=130000")
46+
append_linker_flags("-s MIN_IE_VERSION=0x7FFFFFFF") # Do not support Internet Explorer at all (this is the Emscripten default, shown here for posterity)
47+
append_linker_flags("-s MIN_EDGE_VERSION=79") # Require Chromium-based Edge browser
48+
append_linker_flags("-s MIN_CHROME_VERSION=80")
49+
50+
# Fine tuning for code size: do not generate code to abort program execution on malloc() failures, that will
51+
# not be interesting here.
52+
append_linker_flags("-s ABORTING_MALLOC=0")
53+
54+
# Reduce WebGL code size: We do not need GLES2 emulation for automatic GL extension enabling
55+
append_linker_flags("-s GL_SUPPORT_AUTOMATIC_ENABLE_EXTENSIONS=0")
56+
57+
# Reduce WebGL code size: We do not need GLES2 emulation for GL extension names
58+
append_linker_flags("-s GL_EXTENSIONS_IN_PREFIXED_FORMAT=0")
59+
60+
# Reduce WebGL code size: No need to specify the GL_VENDOR/GL_RENDERER etc. fields in format required by GLES2 spec.
61+
append_linker_flags("-s GL_EMULATE_GLES_VERSION_STRING_FORMAT=0")
62+
63+
# Reduce WebGL code size at the expense of performance (this only has an effect in WebGL 1, practically a no-op here)
64+
append_linker_flags("-s GL_POOL_TEMP_BUFFERS=0")
65+
66+
# Reduce WebGL code size: WebGL bindings layer should not keep track of certain WebGL
67+
# errors that are only meaningful for C/C++ applications. (good to enable for release when glGetError() is not used, but disable in debug)
68+
append_linker_flags("-s GL_TRACK_ERRORS=0")
69+
70+
# Reduce WebGL code size: do not emit code for extensions that we might not need.
71+
append_linker_flags("-s GL_SUPPORT_SIMPLE_ENABLE_EXTENSIONS=0")
72+
73+
# Optimization flag to optimize aggressively for size. (other options -Os, -O3, -O2, -O1, -O0)
74+
append_linker_flags("-Oz")
75+
76+
# Reduce code size: We do not need libc errno field support in our build output.
77+
append_linker_flags("-s SUPPORT_ERRNO=0")
78+
79+
# Reduce code size: We do not need native POSIX filesystem emulation support (Emscripten FS/MEMFS)
80+
append_linker_flags("-s FILESYSTEM=0")
81+
endif()
82+
83+
file(GLOB_RECURSE sources *.cpp *.c *.h)
84+
add_executable(minimal_webgl ${sources})
85+
86+
file(GLOB_RECURSE assets *.png)
87+
foreach(asset ${assets})
88+
file(COPY "${asset}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/")
89+
endforeach()

tests/minimal_webgl/webgl.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
#include <GLES2/gl2.h>
2-
#include <emscripten.h>
3-
#include <emscripten/html5.h>
4-
#include <string.h>
5-
#include <assert.h>
1+
#include <emscripten.h> // For emscripten_get_device_pixel_ratio()
2+
#include <emscripten/html5.h> // For Emscripten HTML5 WebGL context creation API
3+
#include <webgl/webgl1.h> // For Emscripten WebGL API headers (see also webgl/webgl1_ext.h and webgl/webgl2.h)
4+
#include <string.h> // For NULL and strcmp()
5+
#include <assert.h> // For assert()
66

77
void upload_unicode_char_to_texture(int unicodeChar, int charSize, int applyShadow);
88
void load_texture_from_url(GLuint texture, const char *url, int *outWidth, int *outHeight);

0 commit comments

Comments
 (0)