Single render loop + isolated draw overlay
Tiles and points are composited in WebGL2. ROI interaction runs in a separate overlay canvas to keep input handling deterministic and simple.
Runtime layout
React
└─ WsiViewerCanvas
├─ WebGL Canvas (WsiTileRenderer: pan/zoom/rotate)
│ ├─ Tile pass
│ └─ Point pass
└─ DrawLayer Canvas (ROI input + preview + labels)
Tile pipeline
tier = floor(maxTierZoom + log2(zoom)).Runtime resilience (WS-7)
webglcontextlost.webglcontextrestored, shader programs and GPU buffers/textures are recreated.onContextLost, onContextRestored, onTileError expose runtime fault signals to host apps.Point pipeline
Float32Array positions + Uint16Array palette indices, plus optional fillModes/drawIndices.fillModes.clipMode.computeRoiPointGroups / onRoiPointGroups.ROI acceleration modes
`sync`
Main-thread polygon filtering. Useful for debugging and baseline checks.
`worker`
Dedicated worker thread ROI filtering to avoid UI stalls. Current recommended default.
`hybrid-webgpu`
Experimental path: WebGPU bbox prefilter + exact polygon test, then draw-bridge via drawIndices for indexed point rendering.
Observability
onStats/onClipStats plus built-in debugOverlay provide runtime profiling signals and fast regression checks.
Draw pipeline
Ctrl/Cmd + drag rotate (rotationDeg).DrawResult (intent: "roi" | "patch" | "brush").WebGPU expansion path (compute-focused)
ROI culling
Started with bbox prefilter compute pass, then exact polygon phase.
LOD aggregation
Low-zoom density aggregation and binning on GPU.
Term histogram
ROI-level term counts and positivity stats in parallel.
Interop
Pack compute output for direct WebGL buffer upload.
worker as the production-safe default until measured wins are confirmed.
Open-source docs contract
src/index.ts exports are updated in the same PR.onStats, onClipStats).