Skip to main content

Render Backends

A render backend is the named rendering implementation a planar Generic Viewport mounts data through. Cornerstone ships two concrete backends, 'gpu' (VTK/WebGL) and 'cpu', plus the 'auto' preference that resolves to one of them from the capability detection performed at init() (WebGL availability, texture-format probes, and the deprecated useCPURendering flag).

Backends are addressed by plain wire strings. The Enums.RenderBackends constants object maps readable names to those strings (RenderBackends.GPU === 'gpu') and, unlike a TypeScript enum, grows at runtime as extension backends register themselves.

Selecting A Backend​

The backend used for a mounted dataset is resolved with this precedence:

  1. The per-mount renderBackend option on setDisplaySets() / addDisplaySet(). A concrete backend pins that dataset; 'auto' resolves from capability detection even when the global backend is pinned.
  2. The global configuration at rendering.planar.renderBackend, set at init() or changed at runtime with setRenderBackend().
  3. The 'auto' resolution: CPU when no usable WebGL context was detected, GPU otherwise.

setRenderBackend(backend, reason?) live-switches all mounted viewports in place — viewport ids, mounted data, cameras, presentation state, and tool annotations are preserved; only the render paths are rebuilt. It emits RENDER_BACKEND_CHANGED on the eventTarget. Cornerstone never switches backends on its own: applications listening to degradation events (WEBGL_CONTEXT_LOST, RENDER_PATH_ERROR) are expected to call it, typically after prompting the user.

getRenderBackend() returns the configured preference; getEffectiveRenderBackend() returns the resolved concrete backend.

Registering A Custom Backend​

Experimental

Registered custom backends are not fully functional yet, and the registration API is intentionally incomplete. registerRenderBackend() currently captures the wiring the planar viewport needs to select and mount a backend, but it is intended to grow additional parameters describing the backend-specific changes and behaviours it registers — for example participation in the 'auto' capability resolution, backend-owned canvas/surface creation instead of drawing to an existing surface, and per-backend context-loss/degradation handling. Expect the RegisterRenderBackendOptions shape to change.

registerRenderBackend() follows the same extensible-enum model as registerViewportType: the backend id becomes a valid value for setRenderBackend(), the global rendering.planar.renderBackend configuration, and per-mount renderBackend options.

import {
registerRenderBackend,
setRenderBackend,
Enums,
} from '@cornerstonejs/core';

registerRenderBackend({
name: 'WEBGPU',
backend: 'myOrg:webgpu',
renderModes: {
image: {
id: 'myOrg:webgpuImage',
createDefinition: () => new WebGPUImageSlicePath(),
},
volume: {
id: 'myOrg:webgpuVolume',
createDefinition: () => new WebGPUVolumeSlicePath(),
},
},
});

setRenderBackend(Enums.RenderBackends.WEBGPU);

The definition carries the semantic wiring the viewport needs today:

  • backend — the wire id, e.g. 'myOrg:webgpu'. Prefix custom ids with an organization namespace; 'auto' is reserved.
  • renderModes — the render mode the backend resolves to per dataset kind, co-locating each mode's wire id with the createDefinition factory for the planar render path definition that implements it (see Render Paths for what a path implements). The factory is called once per viewport (each planar viewport owns its render path resolver), so it must return a fresh definition instance on every call. image is required and its id must differ from volume's; omit volume when the backend cannot render volume-backed datasets, in which case selecting it for such a dataset fails with a descriptive error.
  • surface — which existing composited canvas the backend's render modes draw to, 'vtk' (default) or 'cpu'. Custom backends cannot yet register their own surface; this is one of the planned extension points noted above.
  • name — optional constant name added to Enums.RenderBackends, e.g. RenderBackends.WEBGPU.

TypeScript Augmentation​

The backend string type stays open through two augmentable interfaces in @cornerstonejs/core. Augment them in your extension's .d.ts to get the new wire string and constant name into completions and checks:

declare module '@cornerstonejs/core' {
interface RenderBackendRegistry {
'myOrg:webgpu': 'myOrg:webgpu';
}
interface RenderBackendConstants {
readonly WEBGPU: 'myOrg:webgpu';
}
}

RenderBackendRegistry feeds the RenderBackendValue string union accepted by setRenderBackend() and renderBackend options; RenderBackendConstants types the properties of Enums.RenderBackends.