跳到主要内容

上下文生命周期

<canvas> 上的 GPU 上下文是 单例且排他。创建参数、丢失、WebGPU device 死亡,全部是产品路径,不是初始化边角。

1. WebGL2 创建

export type GlOptions = {
alpha?: boolean;
antialias?: boolean;
depth?: boolean;
preserveDrawingBuffer?: boolean;
powerPreference?: WebGLPowerPreference;
failIfMajorPerformanceCaveat?: boolean;
premultipliedAlpha?: boolean;
};

export function getWebGL2(
canvas: HTMLCanvasElement,
options: GlOptions = {},
): WebGL2RenderingContext | null {
return canvas.getContext("webgl2", {
alpha: options.alpha ?? true,
antialias: options.antialias ?? false,
depth: options.depth ?? true,
preserveDrawingBuffer: options.preserveDrawingBuffer ?? false,
powerPreference: options.powerPreference ?? "high-performance",
failIfMajorPerformanceCaveat: options.failIfMajorPerformanceCaveat ?? true,
premultipliedAlpha: options.premultipliedAlpha ?? true,
});
}
选项生产默认不要默认打开的原因
antialiasfalse隐式 MSAA,移动端带宽;需要时 FBO 自己做
preserveDrawingBufferfalse合成后保留缓冲,吃显存
failIfMajorPerformanceCaveattrue否则软件实现会假装成功
alpha按是否要透到 DOM 决定不透明场景应 false,少一层混合

第一次调用锁定选项。第二次改 antialias 不会生效,仍返回旧上下文。

getContext("2d") / getContext("webgpu") 在已有 webgl2 的元素上返回 null。2D UI 和 GL 场景用 两张 canvas 叠,见 与 2D 叠层

2. WebGPU 创建

export async function getWebGPU(canvas: HTMLCanvasElement): Promise<{
device: GPUDevice;
context: GPUCanvasContext;
format: GPUTextureFormat;
} | null> {
if (!navigator.gpu) return null;
const adapter = await navigator.gpu.requestAdapter({
powerPreference: "high-performance",
});
if (!adapter) return null;
const device = await adapter.requestDevice();
const context = canvas.getContext("webgpu");
if (!context) return null;
const format = navigator.gpu.getPreferredCanvasFormat();
context.configure({
device,
format,
alphaMode: "premultiplied",
});
return { device, context, format };
}
  • 必须是安全上下文(HTTPS 或 localhost)。
  • requestAdapter()null 是常态(Linux、旧 Android、策略禁用)。降级 WebGL2,不要抛给用户「浏览器太旧」了事。
  • configure 会把画布清成透明黑。resize 后要重新 configure 或重建 canvas 纹理,见 05。
  • navigator.gpu 在 Worker 里走 self.navigator(有实现的环境)。

核对日期时的覆盖面:Chrome / Edge 桌面可用;Safari 26 与 iOS 26 起;Firefox 已覆盖 Windows 与 macOS Apple Silicon。Android / Linux 仍要当二等公民。见 WebGPU 适配与降级

3. 丢失

WebGL:听 webglcontextlostevent.preventDefault() 才能恢复)和 webglcontextrestored。恢复后 所有 buffer / texture / program / VAO 句柄无效,必须按资源表重建。测试用 WEBGL_lose_context.loseContext()

WebGPU:device.lost 是 Promise,resolve 后 device 不可用。重新 requestAdapterrequestDeviceconfigure。不要缓存旧 GPUBuffer

4. 失败形态

症状原因
想叠 2D 文字,getContext("2d") 为 null已经要过 webgl2
截图全透明未 preserve 且读回跨帧
iOS 切后台回来白屏丢失后还在 useProgram(旧句柄)
WebGPU 示例在 HTTP 局域网挂了非安全上下文
configure 后画面闪黑resize 时重复 configure 没立刻重绘

权威资料

核对日期:2026-08-26