Skip to content

fix(core): manage device canvas context lifecycle#2742

Open
ibgreen-openai wants to merge 3 commits into
masterfrom
codex/device-canvas-lifecycle
Open

fix(core): manage device canvas context lifecycle#2742
ibgreen-openai wants to merge 3 commits into
masterfrom
codex/device-canvas-lifecycle

Conversation

@ibgreen-openai

Copy link
Copy Markdown
Collaborator

Summary

  • make Device own and tear down every CanvasContext and PresentationContext wrapper created through it
  • add reference-counted release for reused and repeatedly attached WebGL devices
  • add terminal device.detach() for exclusive owners that need to preserve and recover the backend handle
  • document lifecycle, reuse, attach, detach, and upgrade behavior

Motivation

This started from deck.gl #10355 and the proposed deck-side cleanup in deck.gl #10356, where dropping a CanvasContext without destroying it leaves resize, visibility, DPR, and position observers rooted after Deck finalization.

That leak is another instance in the long-running stream of canvas-related sync/async initialization, teardown, reuse, and attachment fixes across deck.gl and luma.gl. Rather than add another cleanup layer on top of the others, this PR moves as much of the lifecycle contract as possible to the root in luma.gl: the Device that creates context wrappers now owns their final teardown.

Changes

  • Device tracks managed canvas and presentation wrappers, destroys them in reverse creation order, and rejects new wrappers after final teardown.
  • CanvasSurface.destroy() unregisters itself while preserving idempotent observer shutdown.
  • WebGL, WebGPU, and Null devices register default, additional, and presentation wrappers and release backend-specific cached framebuffer/texture wrappers.
  • Reused WebGL devices retain one logical reference per successful acquisition; final destroy() performs wrapper teardown and clears the WebGL context's luma metadata.
  • Repeated webgl2Adapter.attach() calls also retain references, and attached handles are marked borrowed.
  • device.detach() requires exclusive ownership, destroys luma wrappers, clears backend association state, preserves the native handle, and returns it.
  • Owned WebGPU handles are destroyed only by final destroy(); detach() preserves them. WebGPU handle attachment remains intentionally unimplemented, but the ownership model is now defined for it.
  • Added a dedicated Device lifecycle documentation section plus release and upgrade notes.

Verification

  • nvm use
  • yarn install
  • yarn lint fix
  • yarn build
  • yarn test
  • yarn website:build
  • (cd website && yarn build)
  • pre-commit test-fast: 51 test files passed, 178 tests passed

@ibgreen-openai
ibgreen-openai marked this pull request as ready for review July 17, 2026 13:22

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f290f10712

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread modules/webgl/src/adapter/webgl-device.ts
Comment thread modules/webgl/test/adapter/resources/webgl-render-pass.spec.ts Outdated
Comment thread modules/webgpu/src/adapter/webgpu-device.ts
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.

2 participants