Skip to content

fix(deck.gl-raster): stop leaking a WebGL vertex array per tile - #786

Merged
kylebarron merged 1 commit into
mainfrom
kyle/destroy-vertex-arrays
Oct 26, 2026
Merged

kylebarron merged 1 commit into
mainfrom
kyle/destroy-vertex-arrays

Conversation

@kylebarron

Copy link
Copy Markdown
Member

Note

This PR was written by Claude (Claude Code), not by @kylebarron.

@luma.gl/engine 9.4.2's Model.destroy() releases a model's pipeline, shaders, uniform store and geometry, but never destroys its vertex array. SimpleMeshLayer destroys its model when the layer is finalized and when it rebuilds the model, so every tile's MeshTextureLayer leaked one WebGL vertex array object for the life of the context. MeshTextureLayer now destroys the vertex array of each model it releases, until luma.gl does it itself.

Changes

  • MeshTextureLayer.finalizeState destroys the vertex arrays of the layer's models after SimpleMeshLayer destroys the models.
  • MeshTextureLayer.updateState destroys the old model's vertex array when SimpleMeshLayer replaces the model (on a new mesh, or on a render pipeline change, which the layer signals as extensionsChanged).
  • A vertex array that is already destroyed is skipped, so the workaround stays correct once luma.gl's Model.destroy() destroys it, and can then be removed.

Tests

  • New tests/mesh-layer/mesh-layer.test.ts renders the layer through deck.gl's LayerManager, with stand-in models and device since tests have no GPU.
  • It checks that the model's vertex array is destroyed when the layer is removed, that the old model's vertex array is destroyed (and the new one kept) when the mesh or the render pipeline changes, and that a vertex array Model.destroy() already destroyed isn't destroyed again.
  • 3 of the 4 new tests fail against main. The fourth (no double destroy) passes there by design and fails if the guard is removed.

Notes

  • luma.gl's Model.setBufferLayout() also replaces vertexArray without destroying the old one. deck.gl calls it only when an attribute's layout changes, so it should be rare here, and the layer can't reach that old vertex array.

Closes #765

🤖 Written by Claude Code

luma.gl's `Model.destroy()` (as of `@luma.gl/engine` 9.4.2) releases a
model's pipeline, shaders, uniform store and geometry, but never destroys
its vertex array. `SimpleMeshLayer` destroys its model when the layer is
finalized and when it rebuilds the model (on a new mesh, or on a render
pipeline change, which `MeshTextureLayer` signals as `extensionsChanged`),
so every tile ever drawn leaked one WebGL vertex array object for the life
of the context.

`MeshTextureLayer` now destroys the vertex array of each model it releases:
in `finalizeState`, and in `updateState` when `SimpleMeshLayer` replaced the
model. It skips a vertex array that is already destroyed, so it stays
correct once luma.gl destroys it itself and the workaround can be removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the fix label Oct 23, 2026
@kylebarron
kylebarron merged commit 2d62fde into main Oct 26, 2026
3 checks passed
@kylebarron
kylebarron deleted the kyle/destroy-vertex-arrays branch October 26, 2026 18:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

luma.gl Model.destroy() leaks one vertex array per tile ever drawn

1 participant