subagent transcript

session 18e25685 · workflow wf_23df5b1c
delegated task
You are an adversarial verifier for a FreeCAD-wasm code review. A reviewer claims: SEVERITY: medium CATEGORY: feature-gap FILE: src/Gui/WasmGLFixedFun
▸ Magik
You are an adversarial verifier for a FreeCAD-wasm code review. A reviewer claims: SEVERITY: medium CATEGORY: feature-gap FILE: src/Gui/WasmGLFixedFunc.cpp SUMMARY: SoMarkerSet markers do not render and point size is fixed, because glBitmap/glDrawPixels are no-ops and glPointSize is ignored (shader hardcodes uPointSize=3.0). DETAIL/EVIDENCE: Coin's SoMarkerSet draws markers as bitmaps (glBitmap no-op line 480) or as points; glPointSize is a no-op (line 489) and the shader uses a constant uPointSize=3.0 (lines 129,423). Vertex/edge selection markers, datum points and mesh point clouds either disappear (bitmap path) or are locked to a 3px square (point path). Marker highlight/selection cues on a box (its vertices) will be absent or wrong-sized. FIX: route glPointSize into uPointSize, and implement bitmap markers as point-sprite/instanced quads if markers are needed. RECOMMENDATION: (none) 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'll check the file at those specific lines to confirm what's being claimed.
Fable
⚙ Read {"file_path": "/home/magik6k/lcad-wasm/freecad-port/FreeCAD/src/Gui/WasmGLFixedFunc.cpp", "offset": 100, "limit": 60}
tool result
100	      g.linkProgram(p);
101	      if(!g.getProgramParameter(p,g.LINK_STATUS)) console.error('ff link',g.getProgramInfoLog(p));
102	      this.prog=p;
103	      this.loc={ mvp:g.getUniformLocation(p,'uMVP'), nm:g.getUniformLocation(p,'uNormalMat'),
104	        color:g.getUniformLocation(p,'uColor'), useCol:g.getUniformLocation(p,'uUseColorArray'),
105	        lit:g.getUniformLocation(p,'uLighting'), ldir:g.getUniformLocation(p,'uLightDir'),
106	        psize:g.getUniformLocation(p,'uPointSize  …[truncated]
Fable
⚙ Read {"file_path": "/home/magik6k/lcad-wasm/freecad-port/FreeCAD/src/Gui/WasmGLFixedFunc.cpp", "offset": 400, "limit": 110}
tool result
400	    else ffPassDrawArrays(mode, first, count);
401	}
402	void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices){
403	    ensure();
404	    if (ffFixedFuncActive()) ff_setup_and_draw(mode, count, type, (GLintptr)indices, 0, 1);
405	    else ffPassDrawElements(mode, count, type, (GLintptr)indices);
406	}
407	
408	/* ---- immediate mode ---- */
409	EM_JS(void, ffBegin, (GLenum mode), { const F=globalThis.__ff; F.imm={mode, verts:[], nrms:[], cols:[]}; })
410	EM_JS(voi  …[truncated]
Fable
thinking
I'm seeing a pattern here—glBitmap and glDrawPixels are both no-ops, and glPointSize is too, but the point size is being hardcoded to 3.0 in the uniform. The psize location exists at line 106, so I need to check how the vertex shader actually uses uPointSize and gl_PointSize to understand what's happening.
Fable
⚙ Read {"file_path": "/home/magik6k/lcad-wasm/freecad-port/FreeCAD/src/Gui/WasmGLFixedFunc.cpp", "offset": 60, "limit": 40}
tool result
60	    color: [1,1,1,1],
61	    normal: [0,0,1],
62	    lighting: false,
63	    lightDir: [0.3,0.3,1.0],
64	    arrays: { // enabled + pointer specs
65	      vertex:{on:false,size:3,type:0x1406,stride:0,ptr:0,vbo:0},
66	      normal:{on:false,size:3,type:0x1406,stride:0,ptr:0,vbo:0},
67	      color: {on:false,size:4,type:0x1406,stride:0,ptr:0,vbo:0},
68	    },
69	    arrayBuffer: 0,
70	    prog: null, loc: null,
71	    posVBO: null, nrmVBO: null, colVBO: null, idxVBO: null,
72	    imm: null, //   …[truncated]
Fable
thinking
I've confirmed the core technical claims: glBitmap and glDrawPixels are indeed no-ops in the codebase, and glPointSize is also a no-op since the shader hardcodes the point size to 3.0, making any value passed to glPointSize irrelevant.

Now I'm thinking through how this affects actual rendering in FreeCAD. SoMarkerSet relies on glBitmap for drawing markers like navigation cube elements and sketch point indicators, so those won't render at all. Meanwhile, vertex rendering uses SoPointSet/SoBrepPointSet which goes through the GL_POINTS path and does render, but stays locked at that fixed 3-pixel size regardless of what the user sets. The evidence strongly supports the claim—it's a legitimate f  …
Fable
All evidence confirmed by reading the file: - Line 480 `glBitmap(...){ }` — no-op ✓ - Line 481 `glDrawPixels(...){ }` — no-op ✓ - Line 489 `glPointSize(GLfloat){ }` — no-op ✓ - Lines 129 and 423: `g.uniform1f(F.loc.psize, 3.0);` — hardcoded constant in both the array-draw path and the immediate-mode path ✓ - Shader (lines 80, 84): `gl_PointSize = uPointSize;` — driven solely by the uniform, which is never fed from `glPointSize` The technical facts are all accurate. Coin's SoMarkerSet renders markers via `glBitmap` (which is a no-op here, so bitmap markers vanish) or as `GL_POINTS`, whose size is locked to 3px because `glPointSize` is ignored and the shader uniform is a constant. This is a genuine feature/fidelity gap, not a crash or memory-safety issue. Severity assessment: the point-size lock is cosmetic/minor, and the marker path is a moderate visual-fidelity gap (selection/highlight cues, datum points may be absent or wrong-sized). Medium is a defensible ceiling; the impact is entirely cosmetic/visual rather than correctness or stability, so medium is at the high end but supportable.
Fable
⚙ StructuredOutput {"verdict": "CONFIRMED", "reason": "Verified all cited evidence in src/Gui/WasmGLFixedFunc.cpp. glBitmap (line 480), glDrawPixels (line 481) and glPointSize (line 489) are all empty no-ops. The fixed-function shader sets gl_PointSize = uPoi…
tool result
Structured output provided successfully