subagent transcript
session 18e25685 · workflow wf_23df5b1c
delegated task
You are an adversarial verifier for a FreeCAD-wasm code review. A reviewer claims: SEVERITY: info CATEGORY: assessment-summary FILE: /home/magik6k/lca
▸ Magik
You are an adversarial verifier for a FreeCAD-wasm code review. A reviewer claims:
SEVERITY: info
CATEGORY: assessment-summary
FILE: /home/magik6k/lcad-wasm/freecad-port/FreeCAD/src/3rdParty/coin/src/glue/gl.cpp
SUMMARY: The wasm GL glue is correct in its three focus areas and is plausibly sufficient for the FreeCAD viewport geometry subset, with known gaps (no textures, no offscreen/FBO).
DETAIL/EVIDENCE: getprocaddress routing (gl.cpp:609-651): correct. emscripten_GetProcAddress is tried first and, because the link uses -sGL_ENABLE_GET_PROC_ADDRESS=1 and -sFULL_ES3=1 (Main/CMakeLists.txt:145,149), it resolves the real WebGL2/GLES3 entry points (glActiveTexture, glGenVertexArrays, glVertexAttribPointer, glDrawArrays, glBindBuffer, glGetStringi, etc.) as real wasm table function pointers. Legacy GLES1/fixed-function names (glVertexPointer, glMatrixMode, glMultiTexCoord*, glClientActiveTexture) are NOT in emscripten's FULL_ES3 table, so emscripten_GetProcAddress returns NULL for them and control falls through to fcWasmResolveGL (WasmGLFixedFunc.cpp:508), which supplies the emulated implementations. Ordering is right; there is no case where a legacy name is shadowed by a null-returning emscripten stub. Declaration 'extern void * emscripten_GetProcAddress(const char *)' matches emscripten's real C signature. GLES version parse (gl.cpp:730-739): correct. For 'OpenGL ES 3.0 (WebGL 2.0 ...)' the added scan-to-first-digit yields major=3 minor=0 (verified by hand-tracing the subsequent dot/space logic). This satisfies cc_glglue_glversion_matches_at_least(1,3,0) so the multitexture path is enabled and backed by the emulated (no-op) stubs. eglBindAPI (gl_egl.cpp:100-105,233,314): correct — binds EGL_OPENGL_ES_API on wasm instead of desktop EGL_OPENGL_API. fcWasmSyncGLContext in actualRedraw (QuarterWidget.cpp:1006) correctly re-syncs emscripten's GLctx global to Qt's current context before Coin renders. Signature/indirect-call hazards: Coin invokes resolved pointers through its COIN_PFN* typedefs; the emscripten-provided GLES3 functions and the fcWasmResolveGL C functions all have signatures matching the standard GL prototypes Coin's typedefs derive from, so wasm indirect-call type checks pass. Sufficient for on-screen lit/flat triangles, lines, points via immediate mode + client vertex arrays + VBOs. Not sufficient for: textured materials/text (glTexImage/texcoords are no-ops), display lists (glGenLists returns 0; relies on Coin's VBO fallback), offscreen rendering (EGL platform entry points stubbed to return 0), and EXT-suffixed FBO resolution.
RECOMMENDATION: Accept the glue for basic geometry rendering. Track the texture/offscreen/display-list gaps separately as they will block textured surfaces, annotation text, and SoOffscreenRenderer.
Independently verify by reading the actual file(s) and running git/grep as needed (repo at /home/magik6k/lcad-wasm/freecad-port/FreeCAD, toolchain at /opt/toolchains, deploy at /home/magik6k/lcad-wasm/freecad-port/deploy-gui). Default to REFUTED if you cannot confirm the evidence. Adjust severity to what the evidence actually supports.
Fable
thinking
I should check the actual files to verify what's being claimed.
Fable
⚙ Read {"file_path": "/home/magik6k/lcad-wasm/freecad-port/FreeCAD/src/3rdParty/coin/src/glue/gl.cpp", "offset": 590, "limit": 80}
Fable
⚙ Read {"file_path": "/home/magik6k/lcad-wasm/freecad-port/FreeCAD/src/3rdParty/coin/src/glue/gl.cpp", "offset": 710, "limit": 50}
Fable
thinking
I'm tracing through the version parsing logic for an OpenGL ES string, specifically how it handles "OpenGL ES 3.0 (WebGL 2.0 ...)". The code scans to the first digit, then uses strchr to find the decimal point, null-terminates at that position to isolate the major version number, and converts it to an integer.
For the minor version, it searches for both a dot and a space in the remaining string, using whichever comes first as the termination point. In this case the space after "0" comes before the dot in "2.0", so it terminates there, giving us major=3 and minor=0. Now I need to verify this same logic works across the other files mentioned.
Fable
⚙ Bash {"command": "sed -n '140,152p' /home/magik6k/lcad-wasm/freecad-port/FreeCAD/src/Main/CMakeLists.txt", "description": "Check CMakeLists GL flags"}
Fable
⚙ Bash {"command": "grep -rn \"GL_ENABLE_GET_PROC_ADDRESS\\|FULL_ES3\\|FULL_ES2\\|USE_WEBGL2\\|MAX_WEBGL_VERSION\\|MIN_WEBGL_VERSION\" /home/magik6k/lcad-wasm/freecad-port/FreeCAD/src/Main/CMakeLists.txt /home/magik6k/lcad-wasm/freecad-port/FreeCA…
Fable
⚙ Bash {"command": "sed -n '500,540p' /home/magik6k/lcad-wasm/freecad-port/FreeCAD/src/Gui/WasmGLFixedFunc.cpp", "description": "Check fcWasmResolveGL"}
Fable
thinking
I'm verifying the specific line numbers the reviewer cited—confirming that FULL_ES3=1 and GL_ENABLE_GET_PROC_ADDRESS=1 appear in CMakeLists around lines 145 and 149, and that fcWasmResolveGL is located in WasmGLFixedFunc.cpp around line 508.
The reviewer's claim checks out: emscripten handles functions like glActiveTexture and glGenVertexArrays, but glVertexPointer, glMatrixMode, glMultiTexCoord*, and glClientActiveTexture are missing from emscripten's table and are indeed present in fcWasmResolveGL. Now I need to examine gl_eql.cpp and QuarterWidget.cpp to see how these functions are being used.
Fable
⚙ Bash {"command": "grep -n \"fcWasmResolveGL\" /home/magik6k/lcad-wasm/freecad-port/FreeCAD/src/Gui/WasmGLFixedFunc.cpp; echo \"---egl---\"; sed -n '95,110p;228,240p;308,320p' /home/magik6k/lcad-wasm/freecad-port/FreeCAD/src/3rdParty/coin/src/glu…
Fable
⚙ Bash {"command": "grep -n \"fcWasmSyncGLContext\\|actualRedraw\" /home/magik6k/lcad-wasm/freecad-port/FreeCAD/src/Gui/Quarter/QuarterWidget.cpp", "description": "Check QuarterWidget sync"}
Fable
thinking
I've confirmed all the key evidence points: the fcWasmResolveGL function at line 508, the EGL_OPENGL_ES_API macro usage in gl_egl.cpp across the specified lines, and the fcWasmSyncGLContext call in QuarterWidget.cpp's actualRedraw method. Now I'm verifying the specific line numbers the reviewer mentioned for the eglBindAPI macro definition and its usage.
Fable
⚙ Bash {"command": "grep -rn \"fcWasmSyncGLContext\" /home/magik6k/lcad-wasm/freecad-port/FreeCAD/src/Gui/*.cpp | head; echo \"---impl---\"; grep -rn \"GLctx\\|emscripten_webgl_make_context_current\\|emscripten_webgl_get_current_context\" /home/ma…
Fable
thinking
All the evidence checks out—the reviewer's assessment is accurate, the version parsing is correct, and this is an info-level summary confirming the focus areas are sound despite some known gaps. The verdict is confirmed, though I should note this isn't actually a bug finding.
Fable
All cited evidence verified against the actual files:
- gl.cpp:609-651 — getprocaddress routing: emscripten_GetProcAddress tried first, falls through to fcWasmResolveGL, then legacy resolvers. Confirmed exactly as described, including the `extern void * emscripten_GetProcAddress(const char *)` C declaration.
- gl.cpp:730-739 — scan-to-first-digit version fix. Hand-traced "OpenGL ES 3.0 (WebGL 2.0 ...)": after skip → "3.0 (WebGL 2.0 ...)", major=atoi("3")=3, then spaceptr<dotptr picks the space, minor=atoi("0")=0. major=3/minor=0 confirmed.
- Main/CMakeLists.txt:145,149 — `-sFULL_ES3=1` and `-sGL_ENABLE_GET_PROC_ADDRESS=1` present (also MAX_WEBGL_VERSION=2). Confirmed.
- WasmGLFixedFunc.cpp:508 — fcWasmResolveGL table contains exactly the legacy names claimed (glClientActiveTexture, glMultiTexCoord*, glMatrixMode, glVertexPointer, client-state, matrix calls). Confirmed; glActiveTexture is NOT in the table (comes from emscripten), consistent with the claim.
- gl_egl.cpp:100-105 defines FC_WASM_EGL_API = EGL_OPENGL_ES_API under `__EMSCRIPTEN__`; used in eglBindAPI at the init and offscreen-create sites. Confirmed.
- QuarterWidget.cpp:1006 — fcWasmSyncGLContext() called in actualRedraw(); impl at WasmGLFixedFunc.cpp:224 → ffSyncContext() which re-syncs GLctx. Confirmed.
The gap list (no textures/texcoords no-op, glGenLists→0, EGL platform entry points stubbed to 0, offscreen unsupported) is corroborated by the EGL stubs returning 0 in WasmGLFixedFunc.cpp. The assessment is accurate and the severity (info, assessment-summary) is appropriate.
Fable
⚙ StructuredOutput {"verdict": "CONFIRMED", "reason": "Every cited line was independently verified. gl.cpp:609-651 routes through emscripten_GetProcAddress first then fcWasmResolveGL with correct ordering and matching C signature. The gl.cpp:730-739 scan-to-f…