UNPKG

@cornerstonejs/core

Version:
124 lines (123 loc) 3.75 kB
import { getSupportedTextureFormats } from './textureSupport.js'; export const RENDERING_CAPABILITIES_PROBE_VERSION = 1; const STORAGE_KEY = 'cornerstone3D.renderingCapabilities'; const SOFTWARE_RASTERIZER_PATTERN = /swiftshader|llvmpipe|softpipe|software|microsoft basic render/i; const NO_GPU_FORMATS = { norm16: false, norm16Linear: false, float: false, floatLinear: false, halfFloat: false, halfFloatLinear: false, }; let cachedCapabilities = null; function getWebGLContextInfo() { const info = { webgl: false, webgl2: false, maxTextureSize: 0, renderer: '', }; if (typeof document === 'undefined') { return info; } try { const canvas = document.createElement('canvas'); const gl2 = canvas.getContext('webgl2'); const gl = gl2 || canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); if (!gl) { return info; } info.webgl = true; info.webgl2 = !!gl2; info.maxTextureSize = Number(gl.getParameter(gl.MAX_TEXTURE_SIZE)) || 0; const debugInfo = gl.getExtension('WEBGL_debug_renderer_info'); const renderer = debugInfo ? gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) : gl.getParameter(gl.RENDERER); info.renderer = typeof renderer === 'string' ? renderer : ''; const loseContext = gl.getExtension('WEBGL_lose_context'); if (loseContext) { loseContext.loseContext(); } } catch { } return info; } function readCachedFormats(renderer, webgl2) { try { const raw = window.localStorage?.getItem(STORAGE_KEY); if (!raw) { return null; } const parsed = JSON.parse(raw); if (parsed?.probeVersion !== RENDERING_CAPABILITIES_PROBE_VERSION || parsed?.renderer !== renderer || parsed?.webgl2 !== webgl2 || typeof parsed?.formats !== 'object' || parsed?.formats === null) { return null; } return { ...NO_GPU_FORMATS, ...parsed.formats }; } catch { return null; } } function writeCachedFormats(renderer, webgl2, formats) { try { const payload = { probeVersion: RENDERING_CAPABILITIES_PROBE_VERSION, renderer, webgl2, formats, }; window.localStorage?.setItem(STORAGE_KEY, JSON.stringify(payload)); } catch { } } export function detectRenderingCapabilities({ useCache = true, } = {}) { const contextInfo = getWebGLContextInfo(); if (!contextInfo.webgl) { return { ...contextInfo, ...NO_GPU_FORMATS, softwareRasterizer: false, }; } let formats = useCache ? readCachedFormats(contextInfo.renderer, contextInfo.webgl2) : null; if (!formats) { const probed = getSupportedTextureFormats(); if (probed) { writeCachedFormats(contextInfo.renderer, contextInfo.webgl2, probed); } formats = probed ?? { ...NO_GPU_FORMATS }; } return { ...contextInfo, ...formats, softwareRasterizer: SOFTWARE_RASTERIZER_PATTERN.test(contextInfo.renderer), }; } export function getRenderingCapabilities() { if (!cachedCapabilities) { cachedCapabilities = detectRenderingCapabilities(); } return cachedCapabilities; } export function resetRenderingCapabilities({ clearStorage = false, } = {}) { cachedCapabilities = null; if (clearStorage) { try { window.localStorage?.removeItem(STORAGE_KEY); } catch { } } }