Skip to content

Fix webgpu vtktexture cache invalidation#3557

Open
PaulHax wants to merge 3 commits into
Kitware:masterfrom
PaulHax:webgpu-vtktexture-cache-invalidation
Open

Fix webgpu vtktexture cache invalidation#3557
PaulHax wants to merge 3 commits into
Kitware:masterfrom
PaulHax:webgpu-vtktexture-cache-invalidation

Conversation

@PaulHax

@PaulHax PaulHax commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Context

PR #3547 (e072af2) fixed the stale-texture cache for getTextureForImageData: the shared _fillRequest helper derives the cache hash from the scalar array mtime alone, so writing scalars in place and signaling with imageData.modified() kept returning the stale GPU texture.

The sibling entry point getTextureForVTKTexture has the identical clobber: it seeds the hash with the vtkTexture mtime, but for imageData-backed textures _fillRequest overwrites it. Streaming new pixels into a texture draped over geometry (actor.addTexture(...)), a background, or a skybox silently keeps rendering the old image unless scalars.modified() is called directly — the OpenGL backend refreshes in all of these cases.

Results

  • imageData-backed vtkTextures refresh when scalars are updated in place and the change is signaled through imageData.modified() or texture.modified() alone (before: the WebGPU view kept the stale texture until scalars.modified(); WebGL updated).
  • Non-imageData texture sources (image, jsImageData, imageBitmap, canvas) are unaffected — their hash already used the texture mtime.
  • Failing texture-cache assertions now report their message instead of a stack overflow: expect(...).toBe(vtkTexture) made the reporter serialize the circular device–texture graph through toJSON()/getState() until RangeError: Maximum call stack size exceeded masked the actual failure.
  • Device-level WebGPU tests no longer need try/finally cleanup: createWebGPUTestDevice destroys its device when the test finishes, pass or fail.

Changes

  • WebGPU/TextureManager: getTextureForVTKTexture hashes cache entries on the newest of the texture, imageData, and scalar array mtimes, mirroring e072af2.

  • New regression test TextureManager/test/testVTKTextureCacheInvalidation.js.

  • TextureManager/test/testImageDataTextureCacheInvalidation.js: compare cached texture identities as booleans so assertion failures stay readable.

  • Testing/testUtils.js: createWebGPUTestDevice registers onTestFinished(() => handle.destroy()); removed per-test device cleanup from the device-level tests (destroying a device destroys every resource created from it).

  • No public API changes.

  • Documentation and TypeScript definitions were updated to match those changes

PR and Code Checklist

  • semantic-release commit messages
  • Run npm run reformat to have correctly formatted code

Testing

WEBGPU=1 npx vitest run \
  Sources/Rendering/WebGPU/TextureManager \
  Sources/Rendering/WebGPU/Texture/test/testWriteSubImageData.js

The new regression test fails without the fix (imageData.modified() alone must invalidate the cached texture: expected true to be false). Note the WebGPU tests are skipped unless WEBGPU=1 is set, so CI does not exercise them yet.

  • This change adds or fixes unit tests
  • Tested environment:
    • vtk.js: master (ca498ee)
    • OS: Linux (WSL2 Ubuntu 24.04)
    • Browser: Chromium (Playwright, headless)

PaulHax added 3 commits July 16, 2026 13:42
…geData mtimes

getTextureForVTKTexture seeds the cache hash with the vtkTexture mtime, but
for imageData-backed textures _fillRequest overwrites it with the scalar
array mtime alone, so updating scalars in place and signaling through
imageData.modified() or srcTexture.modified() kept returning the stale
texture. Hash on the newest of the texture, imageData, and scalar array
mtimes, mirroring the getTextureForImageData fix (e072af2).
When a texture-identity assertion fails, passing the vtk textures to
expect() makes the reporter serialize them through toJSON()/getState(),
which recurses the circular device-texture graph until a stack overflow
masks the assertion message. Compare identities as booleans so failures
report the intended message.
createWebGPUTestDevice now registers an onTestFinished callback that
destroys the device handle whether the test passes or fails, so callers
no longer need try/finally cleanup. Destroying the device also destroys
every resource created from it, covering the per-texture destroy calls.
@PaulHax PaulHax changed the title webgpu vtktexture cache invalidation Fix webgpu vtktexture cache invalidation Jul 16, 2026
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