Skip to content

WebGL2-only: drop WebGL1 path, adopt VAOs (per-flush attribute setup → bindVertexArray) #1509

Description

@obiot

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 > 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.

Scope

A. Make the WebGL renderer WebGL2-only

  • Request a webgl2 context; if unavailable, fall back to Canvas2D (drop the WebGL1 middle tier). Update WebGLVersion handling / the misconfiguration-throws path (Camera3d should fail loudly when used with the Canvas renderer #1479) accordingly.
  • 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

Cost / risk

  • 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.

Acceptance criteria

  • WebGL renderer creates only a webgl2 context; missing → Canvas2D (with the existing loud signal when renderer: video.WEBGL was explicitly requested, per Camera3d should fail loudly when used with the Canvas renderer #1479).
  • 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).

References

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions