You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Drop the WebGL 1 rendering path and make the WebGL renderer WebGL 2-only (with the existing Canvas2D fallback unchanged), then adopt the WebGL2-only features that path unlocks — Vertex Array Objects (VAOs) first, as the concrete perf win.
Motivation
Two parts, kept distinct because they matter differently:
1. Dropping WebGL 1 by itself is ~0 runtime gain — it's an enabler + cleanup, not a speedup.
The ~9 WebGLVersion > 1 branches are per-flush / per-init, constant for a session, and perfectly branch-predicted — never in the per-vertex hot loop. Deleting them makes no existing WebGL 2 draw faster. The value of removing WebGL 1 is: smaller bundle, fewer code paths to test, removal of degraded fallbacks (Uint16 index coercion, NPOT-repeat guards, extension probing), and — most importantly — it lets us assume WebGL2-only features without guards.
2. The actual perf comes from what WebGL2-only unlocks — VAOs above all.
melonJS currently uses no VAOs (no createVertexArray / bindVertexArray). The batcher calls setVertexAttributes — i.e. N× enableVertexAttribArray + vertexAttribPointer — on every flush (src/video/webgl/batchers/batcher.js). A dense scene flushes ~10–20+ times/frame, so that attribute re-specification is paid repeatedly. With a VAO the layout is set up once and each flush becomes a single bindVertexArray — a real per-draw CPU saving. VAOs are core in WebGL 2 but only an unreliable extension on WebGL 1, so committing to WebGL2-only makes adopting them clean.
Remove the WebGLVersion > 1 branches and their WebGL1 else-paths (renderer, quad_batcher, batcher, material_batcher): the offset/length bufferData form, NPOT-repeat guards, Uint16 index coercion fallback, OES_element_index_uint assumptions, etc.
Keep Canvas2D fallback fully working (it already exists).
B. Adopt VAOs (the perf item)
Create one VAO per batcher (or per shader/attribute-layout), set the vertex attribute layout once, and bindVertexArray per flush instead of re-calling setVertexAttributes.
Handle context loss/restore (VAOs are GPU objects — recreate on ONCONTEXT_RESTORED).
Verify the shared-vertex-buffer rebinding in setBatcher still holds with VAOs.
C. (Follow-on, optional in this ticket or separate) other WebGL2-only wins now unblocked
Drops the WebGL-1-only device tier. WebGL 2 is ~96–98% globally; the Canvas2D fallback still covers the truly ancient, so the net is "WebGL 2 or Canvas2D." The 3D mesh path is already best-on-WebGL-2 (WebGL 1 3D is degraded today), so impact is mostly 2D on very old hardware that already falls back to Canvas2D.
Breaking-ish: anything relying on a WebGL 1 context specifically. Call it out in the changelog; gate behind a major/minor as appropriate.
All WebGLVersion > 1 branches removed; single code path remains.
Batchers use a VAO: setVertexAttributes is called once per layout, not per flush (verifiable via a GL spy — vertexAttribPointer count per frame drops from O(flushes×attribs) to O(layouts)).
VAOs recreated correctly after context loss/restore.
No visual regression across the full suite; FPS/draw-time on the night-city stress scene improves measurably (per-flush attribute setup eliminated).
Summary
Drop the WebGL 1 rendering path and make the WebGL renderer WebGL 2-only (with the existing Canvas2D fallback unchanged), then adopt the WebGL2-only features that path unlocks — Vertex Array Objects (VAOs) first, as the concrete perf win.
Motivation
Two parts, kept distinct because they matter differently:
1. Dropping WebGL 1 by itself is ~0 runtime gain — it's an enabler + cleanup, not a speedup.
The ~9
WebGLVersion > 1branches are per-flush / per-init, constant for a session, and perfectly branch-predicted — never in the per-vertex hot loop. Deleting them makes no existing WebGL 2 draw faster. The value of removing WebGL 1 is: smaller bundle, fewer code paths to test, removal of degraded fallbacks (Uint16 index coercion, NPOT-repeat guards, extension probing), and — most importantly — it lets us assume WebGL2-only features without guards.2. The actual perf comes from what WebGL2-only unlocks — VAOs above all.
melonJS currently uses no VAOs (no
createVertexArray/bindVertexArray). The batcher callssetVertexAttributes— i.e. N×enableVertexAttribArray+vertexAttribPointer— on every flush (src/video/webgl/batchers/batcher.js). A dense scene flushes ~10–20+ times/frame, so that attribute re-specification is paid repeatedly. With a VAO the layout is set up once and each flush becomes a singlebindVertexArray— a real per-draw CPU saving. VAOs are core in WebGL 2 but only an unreliable extension on WebGL 1, so committing to WebGL2-only makes adopting them clean.Scope
A. Make the WebGL renderer WebGL2-only
webgl2context; if unavailable, fall back to Canvas2D (drop the WebGL1 middle tier). UpdateWebGLVersionhandling / the misconfiguration-throws path (Camera3d should fail loudly when used with the Canvas renderer #1479) accordingly.WebGLVersion > 1branches and their WebGL1 else-paths (renderer,quad_batcher,batcher,material_batcher): the offset/lengthbufferDataform, NPOT-repeat guards, Uint16 index coercion fallback,OES_element_index_uintassumptions, etc.B. Adopt VAOs (the perf item)
bindVertexArrayper flush instead of re-callingsetVertexAttributes.ONCONTEXT_RESTORED).setBatcherstill holds with VAOs.C. (Follow-on, optional in this ticket or separate) other WebGL2-only wins now unblocked
texStorage2Dimmutable textures + sized internal formatsblitFramebufferfor FBO antialiasingANGLE_instanced_arraysdanceCost / risk
Acceptance criteria
webgl2context; missing → Canvas2D (with the existing loud signal whenrenderer: video.WEBGLwas explicitly requested, per Camera3d should fail loudly when used with the Canvas renderer #1479).WebGLVersion > 1branches removed; single code path remains.setVertexAttributesis called once per layout, not per flush (verifiable via a GL spy —vertexAttribPointercount per frame drops from O(flushes×attribs) to O(layouts)).References
src/video/webgl/webgl_renderer.js(context creation,WebGLVersion)src/video/webgl/batchers/batcher.js(flush,setVertexAttributesper flush — the VAO target)src/video/webgl/batchers/{quad,material,mesh,lit_mesh}_batcher.jssrc/video/webgl/glshader.js(setVertexAttributes)src/video/buffer/*,src/video/webgl/buffer/index.js