Skip to content

feat(webgl): add disableVertexArrayObject setting to toggle VAOs#77

Merged
chiefcll merged 1 commit into
mainfrom
webgl-disable-vao-setting
Jun 8, 2026
Merged

feat(webgl): add disableVertexArrayObject setting to toggle VAOs#77
chiefcll merged 1 commit into
mainfrom
webgl-disable-vao-setting

Conversation

@chiefcll

@chiefcll chiefcll commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a RendererMainSettings.disableVertexArrayObject option (default false) that forces the per-draw attribute-binding path even when VAOs are available. It's a diagnostic / benchmarking switch for A/B-ing the VAO optimization on real hardware — no effect on the Canvas renderer.

new RendererMain({ disableVertexArrayObject: true /* … */ }, 'app');

The example harness reads ?novao=true and feeds the setting, so the ?debug=true overlay shows the difference live on a device.

Plumbing

Mirrors forceWebGL2: RendererMain settings → StageCoreRendererOptionsWebGlRendererWebGlContextWrapper, where it gates canUseVertexArrayObject. isWebGl2 still reflects the real context — the flag only controls VAO usage, and the create/bind/delete methods stay capability-based (they're never reached when the gate is off).

Verified on real hardware behavior

stress-multi-texture on WebGL1, same scene (~303 draws), toggling novao:

Metric VAO on VAO off
status VAO:on VAO:off
GL calls/interval 108,361 276,506 (2.55×)
vertexAttribPointer 0 73,924
enableVertexAttribArray 0 73,924
bindVertexArray 18,178 0
drawElements 18,178 18,481

73,924 / 18,481 ≈ 4 confirms 4 vertexAttribPointer + 4 enableVertexAttribArray per draw return when VAOs are off — the 8 attribute calls/draw the VAO collapses into one bindVertexArray.

Testing

  • pnpm build, pnpm lint clean; pnpm test 314/314 — added WebGlContextWrapper.test.ts (mock-GL unit test) covering: VAOs enabled with the OES extension, disabled without it, and forced off by the flag even when supported.
  • Browser-verified the ?novao=true overlay A/B above.

Why it's useful

On a draw-call-bound device (e.g. a TV where per-draw GL cost is ~100µs), this lets you measure the VAO FPS delta directly — run a draw-call-heavy scene with and without novao and read it off the overlay. On a fill-bound / vsync-capped setup the GL-call count drops ~2.5× but FPS won't move, which the toggle also makes obvious.

🤖 Generated with Claude Code

Adds a RendererMainSettings.disableVertexArrayObject option (default false)
that forces the per-draw attribute-binding path even when VAOs are available.
It's a diagnostic/benchmarking switch for A/B-ing the VAO optimization on a
target device; no effect on the Canvas renderer.

Plumbed like forceWebGL2: RendererMain settings -> Stage -> CoreRendererOptions
-> WebGlRenderer -> WebGlContextWrapper, where it gates canUseVertexArrayObject
(isWebGl2 still reflects the real context). The example harness reads
`?novao=true` and feeds the setting, so the debug overlay can show the
difference live.

Verified on stress-multi-texture (WebGL1): toggling novao flips VAO:on->off,
vertexAttribPointer/enableVertexAttribArray jump from 0 to ~4x the draw count
each, bindVertexArray drops to 0, and total GL calls per interval rise ~2.5x.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chiefcll
chiefcll merged commit 20d8696 into main Jun 8, 2026
1 check passed
@chiefcll
chiefcll deleted the webgl-disable-vao-setting branch June 8, 2026 20:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant