Skip to content

Conversation

@Sanchit2662
Copy link

Summary

This PR fixes a critical WebGL lifecycle issue where shader programs and textures were never explicitly released from GPU memory when a sketch was destroyed. As a result, applications that repeatedly create and remove WebGL sketches (e.g. hot-reload editors, instance-mode apps, long-running installations) experienced unbounded GPU memory growth.

The fix introduces explicit dispose() methods for WebGL-backed resources and registers a renderer-level cleanup hook that is automatically invoked when sketch.remove() is called.


Impact

Before

  • WebGL shaders, programs, and textures remain allocated after remove()
  • GPU memory grows unboundedly in multi-sketch or hot-reload scenarios
  • No user-level workaround is possible

After

  • All WebGL shader and texture resources are explicitly released
  • GPU memory remains stable across repeated sketch creation/destruction
  • Instance-mode and long-running WebGL sketches behave reliably

Changes

1. p5.Shader.dispose()

Adds an explicit teardown path for shader GPU resources.

dispose() {
  if (!this._gl || !this._glProgram) return;

  this._gl.detachShader(this._glProgram, this._vertShader);
  this._gl.detachShader(this._glProgram, this._fragShader);
  this._gl.deleteShader(this._vertShader);
  this._gl.deleteShader(this._fragShader);
  this._gl.deleteProgram(this._glProgram);

  this._glProgram = null;
}
  • Properly detaches shaders before deletion
  • Deletes both shader objects and the linked program
  • Guards against double deletion or uninitialized shaders

2. p5.Texture.dispose()

Ensures GPU textures are freed when no longer needed.

dispose() {
  if (this.glTex && !this.isFramebufferTexture) {
    this._renderer.GL.deleteTexture(this.glTex);
    this.glTex = null;
  }
}
  • Releases GPU texture memory
  • Skips framebuffer-managed textures to avoid double-freeing

3. Renderer-level cleanup hook (p5.RendererGL)

Introduces a centralized cleanup method that disposes all WebGL resources owned by the renderer.

Key resources cleaned:

  • Default and user shaders
  • Cached textures (this.textures)
  • Filter shaders and filter layers
  • Framebuffers and retained-mode buffers
  • Empty texture singleton

The cleanup is automatically invoked on sketch teardown:

this._pInst.registerMethod(
  'remove',
  this._cleanupWebGLResources.bind(this)
);

PR Checklist

Add dispose() methods to p5.Shader and p5.Texture classes and register
cleanup hook in p5.RendererGL to free GPU resources when remove() is called.

Signed-off-by: Sanchit2662 <[email protected]>
@Sanchit2662
Copy link
Author

Hi @davepagurek,
This PR fixes a WebGL lifecycle issue where shader programs and textures weren’t being released when a sketch was removed, which could lead to unbounded GPU memory growth in long-running or hot-reload scenarios. The update adds explicit cleanup for WebGL resources and ensures everything is properly disposed on sketch.remove().

Whenever you have time, I’d appreciate a review. Thanks!

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