@cornerstonejs/core
Version:
Cornerstone3D Core
124 lines (123 loc) • 3.75 kB
JavaScript
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 {
}
}
}