Shared WebGL context render window#3453
Conversation
93f4a3a to
5e23b91
Compare
|
@sedghi do you have an opnion on this ? |
ca02f1f to
8ed472d
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds a shared-WebGL2-context rendering path to vtk.js, enabling vtk.js to render into an externally owned WebGL2RenderingContext (e.g., MapLibre custom layers) rather than always creating/managing its own canvas/context.
Changes:
- Added
manageCanvas(defaulttrue) tovtkOpenGLRenderWindowto allow opting out of canvas resizing/styling when the canvas is externally owned. - Introduced
vtkSharedRenderWindow.createFromContext(canvas, gl)plusvtkSharedRendererto support shared-context rendering while keeping overrides local to the shared render-window instance. - Added SharedRenderWindow unit tests (GL state reset, host framebuffer rendering, host survival) and a MapLibre shared-context example.
Reviewed changes
Copilot reviewed 9 out of 13 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| Sources/Rendering/SceneGraph/ViewNodeFactory/index.js | Switches override lookup to support prototype-inherited mappings (in), enabling per-instance override chains. |
| Sources/Rendering/OpenGL/ViewNodeFactory/index.js | Makes OpenGL view-node mappings inheritable per factory instance via Object.create(CLASS_MAPPING) and adds instance-local registerOverride. |
| Sources/Rendering/OpenGL/RenderWindow/index.js | Adds manageCanvas gating for canvas size/display updates and blocks resize-based screenshot capture when canvas management is disabled. |
| Sources/Rendering/OpenGL/RenderWindow/index.d.ts | Exposes manageCanvas in initial values and adds getManageCanvas / setManageCanvas. |
| Sources/Rendering/OpenGL/SharedRenderWindow/index.js | New shared-context render window with GL-state reset, size sync from drawing buffer, and render-callback integration. |
| Sources/Rendering/OpenGL/SharedRenderWindow/index.d.ts | Type definitions for vtkSharedRenderWindow API (renderShared, callbacks, autoClear controls, createFromContext). |
| Sources/Rendering/OpenGL/SharedRenderer/index.js | New renderer variant that respects shared-window autoClear behavior and uses tiled viewport/scissor. |
| Sources/Rendering/OpenGL/SharedRenderer/index.d.ts | Type definitions for vtkSharedRenderer. |
| Sources/Rendering/OpenGL/SharedRenderWindow/test/testSharedRenderWindow.js | Baseline image test + validation that shared renderer override remains local + WebGL1 rejection + manageCanvas behavior. |
| Sources/Rendering/OpenGL/SharedRenderWindow/test/testSharedRenderWindowGLState.js | Tests that renderShared() resets GL state and renders into a currently bound host framebuffer. |
| Sources/Rendering/OpenGL/SharedRenderWindow/test/testSharedRenderWindowHostSurvival.js | Tests host rendering can resume after renderShared() when host state is rebound. |
| Examples/Rendering/SharedContext/index.js | MapLibre terrain example demonstrating shared-context depth-tested interleaving. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
c19dc9c to
5d1f87a
Compare
|
|
||
| function getDefaultDrawBuffers(gl) { | ||
| const framebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING); | ||
| return framebuffer ? [gl.COLOR_ATTACHMENT0] : [gl.BACK]; |
There was a problem hiding this comment.
This is an assumption here. If the external application has bound multiple FBO attachments, assuming attachment 0 might be wrong.
There was a problem hiding this comment.
Updated to query DRAW_BUFFER0 to gl.MAX_DRAW_BUFFERS and respect the host's actual draw-buffer state, with [COLOR_ATTACHMENT0] as a fallback when every slot is NONE.
dc92777 to
db65e08
Compare
Move registerOverride from extend() into the main function body for both ViewNodeFactory and SharedRenderWindow.
Gate the screenshot-path canvas display toggle on manageCanvas, matching the existing guard at line 164 so externally owned canvases are never restyled. In getDefaultDrawBuffers, query the host's actual DRAW_BUFFER0..N state when an FBO is bound rather than assuming COLOR_ATTACHMENT0. Falls back to [COLOR_ATTACHMENT0] when all slots are NONE so callers that left the default state untouched still get a valid render target.
The SharedRenderWindow tests and type defs predated the Vite/Vitest tooling migration on master. Adapt them so the PR builds and tests cleanly on current master: - migrate the 3 test files from the removed tape harness to Vitest: test.onlyIfWebGL -> it.skipIf(__VTK_TEST_NO_WEBGL__), t.ok/notOk/equal/deepEqual/throws -> expect assertions, drop t.end() (the image-comparison test returns its promise) - update compareImages() to its current (no tape arg) signature - createSharedWindow helper no longer takes a tape handle - reformat index.d.ts with oxfmt (interface extends clause)
db65e08 to
adf58ff
Compare
Are folks intersted in putting this in the vtk.js repo? Its an uncommon use case. We could get away with simply doing something to keep
vtkOpenGLRenderWindowfrom resizing the canvas and put SharedRenderWindow in another repo/package.Context
This PR adds an OpenGL shared-context rendering path for vtk.js so it can render into a
WebGL2RenderingContextowned by another library, instead of always creating and managing its own canvas/context.The immediate use case is interleaving vtk.js content with host renderers such as MapLibre custom layers, including depth-tested rendering into the host scene. vtk.js also needs an explicit way to opt out of canvas DOM management when the canvas is externally owned.
Results
Before this change:
vtkOpenGLRenderWindowassumed ownership of the canvas and could resize/restyle it.After this change:
WebGL2context throughvtkSharedRenderWindow.createFromContext(canvas, gl).Changes
Added
manageCanvastovtkOpenGLRenderWindow(defaulttrue) so externally owned canvases can opt out of vtk.js canvas sizing/styling.Added
vtkSharedRenderWindowfor rendering into an externally providedWebGL2RenderingContext.Added
vtkSharedRendererfor the shared-context rendering path.Scoped the vtkSharedRenderer override to the shared render-window instance rather than changing the global OpenGL view-node factory. This avoids leaking shared-context behavior into unrelated normal OpenGL render windows.
Added a MapLibre example showing shared-context rendering on terrain.
Documentation and TypeScript definitions were updated to match those changes
PR and Code Checklist
npm run reformatto have correctly formatted codeTesting
npm run example -- SharedContext