UNPKG

@cornerstonejs/core

Version:
209 lines (208 loc) • 7.61 kB
import { getRenderingEngines } from './RenderingEngine/getRenderingEngine.js'; let csRenderInitialized = false; import deepMerge from './utilities/deepMerge.js'; import CentralizedWebWorkerManager from './webWorkerManager/webWorkerManager.js'; import { getRenderingCapabilities } from './utilities/renderingCapabilities.js'; import triggerEvent from './utilities/triggerEvent.js'; import eventTarget from './eventTarget.js'; import { Events, RenderBackends, RenderingEngineModeEnum } from './enums/index.js'; import { isRegisteredRenderBackend } from './RenderingEngine/helpers/renderBackendRegistry.js'; const defaultConfig = { isMobile: false, rendering: { useCPURendering: false, preferSizeOverAccuracy: false, useLegacyCameraFOV: false, strictZSpacingForVolumeViewport: true, renderingEngineMode: RenderingEngineModeEnum.ContextPool, webGlContextCount: 7, planar: { renderBackend: RenderBackends.Auto, cpuVolume: { useViewportSamplingForLinear: true, volumeModifiedThrottleMs: 5000, }, }, volumeRendering: { sampleDistanceMultiplier: 1, }, }, debug: { statsOverlay: false, }, peerImport: (moduleId) => null, }; let config = { ...defaultConfig, rendering: { ...defaultConfig.rendering }, }; let webWorkerManager = null; function _hasNorm16TextureSupport() { const capabilities = getRenderingCapabilities(); return capabilities.norm16 && capabilities.norm16Linear; } function isIOS() { if (/iPad|iPhone|iPod/.test(navigator.platform)) { return true; } else { return (navigator.maxTouchPoints && navigator.maxTouchPoints > 2 && navigator.platform.includes('MacIntel')); } } function init(configuration = config) { if (csRenderInitialized) { return csRenderInitialized; } config = deepMerge(defaultConfig, configuration); if (config.isMobile) { config.rendering.webGlContextCount = 1; } if (isIOS()) { if (configuration.rendering?.preferSizeOverAccuracy) { config.rendering.preferSizeOverAccuracy = true; } else if (!_hasNorm16TextureSupport()) { console.log('norm16 texture not supported, you can turn on the preferSizeOverAccuracy flag to use native data type, but be aware of the inaccuracy of the rendering in high bits'); } } const capabilities = getRenderingCapabilities(); if (!capabilities.webgl) { console.log('CornerstoneRender: GPU not detected, using CPU rendering'); config.rendering.useCPURendering = true; } else { console.log('CornerstoneRender: using GPU rendering'); if (capabilities.softwareRasterizer) { console.log(`CornerstoneRender: software rasterizer detected (${capabilities.renderer}), GPU rendering may be slow`); } } csRenderInitialized = true; if (!webWorkerManager) { webWorkerManager = new CentralizedWebWorkerManager(); } return csRenderInitialized; } function getCanUseNorm16Texture() { return _hasNorm16TextureSupport(); } function getRenderBackend() { return config.rendering.planar?.renderBackend ?? RenderBackends.Auto; } function resolveAutoRenderBackend() { return config.rendering.useCPURendering ? RenderBackends.CPU : RenderBackends.GPU; } const warnedUnregisteredBackends = new Set(); function getEffectiveRenderBackend(override) { const backend = override ?? getRenderBackend(); if (backend !== RenderBackends.Auto) { if (isRegisteredRenderBackend(backend)) { return backend; } if (!warnedUnregisteredBackends.has(backend)) { warnedUnregisteredBackends.add(backend); console.warn(`[getEffectiveRenderBackend] Unregistered render backend "${backend}"; ` + `falling back to 'auto'. Register custom backends with registerRenderBackend().`); } } return resolveAutoRenderBackend(); } function setRenderBackend(backend, reason) { if (backend !== RenderBackends.Auto && !isRegisteredRenderBackend(backend)) { throw new Error(`[setRenderBackend] Invalid render backend: ${String(backend)}. ` + `Register custom backends with registerRenderBackend() before selecting them.`); } const previous = getRenderBackend(); if (previous === backend) { return; } config.rendering.planar = { ...config.rendering.planar, renderBackend: backend, }; _updateRenderingPipelinesForAllViewports(); triggerEvent(eventTarget, Events.RENDER_BACKEND_CHANGED, { previous, current: backend, effectiveBackend: getEffectiveRenderBackend(), reason, }); } function setUseCPURendering(status, updateViewports = true) { const previousEffective = getEffectiveRenderBackend(); config.rendering.useCPURendering = status; csRenderInitialized = true; if (updateViewports) { _updateRenderingPipelinesForAllViewports(); } _notifyEffectiveBackendChange(previousEffective, 'setUseCPURendering'); } function setPreferSizeOverAccuracy(status) { config.rendering.preferSizeOverAccuracy = status; csRenderInitialized = true; _updateRenderingPipelinesForAllViewports(); } function canRenderFloatTextures() { const capabilities = getRenderingCapabilities(); if (capabilities.webgl2) { return capabilities.floatLinear; } return !isIOS(); } function resetUseCPURendering() { const previousEffective = getEffectiveRenderBackend(); config.rendering.useCPURendering = !getRenderingCapabilities().webgl; _updateRenderingPipelinesForAllViewports(); _notifyEffectiveBackendChange(previousEffective, 'resetUseCPURendering'); } function getShouldUseCPURendering() { return config.rendering.useCPURendering; } function getUseGenericViewport() { return config.rendering.useGenericViewport === true; } function isCornerstoneInitialized() { return csRenderInitialized; } function resetInitialization() { csRenderInitialized = false; } function getConfiguration() { return config; } function setConfiguration(c) { config = c; _updateRenderingPipelinesForAllViewports(); } function _updateRenderingPipelinesForAllViewports() { getRenderingEngines().forEach((engine) => { engine.getViewports().forEach((viewport) => { viewport.updateRenderingPipeline?.(); }); }); } function _notifyEffectiveBackendChange(previousEffective, reason) { const effectiveBackend = getEffectiveRenderBackend(); if (previousEffective === effectiveBackend) { return; } triggerEvent(eventTarget, Events.RENDER_BACKEND_CHANGED, { previous: previousEffective, current: effectiveBackend, effectiveBackend, reason, }); } function getWebWorkerManager() { if (!webWorkerManager) { webWorkerManager = new CentralizedWebWorkerManager(); } return webWorkerManager; } async function peerImport(moduleId) { return config.peerImport(moduleId); } export { init, getShouldUseCPURendering, getUseGenericViewport, isCornerstoneInitialized, setUseCPURendering, setPreferSizeOverAccuracy, resetUseCPURendering, getRenderBackend, setRenderBackend, getEffectiveRenderBackend, resolveAutoRenderBackend, getConfiguration, setConfiguration, getWebWorkerManager, canRenderFloatTextures, peerImport, resetInitialization, getCanUseNorm16Texture, };