対応・安全性
WebGLコンテキスト消失への備え
WebGLコンテキストは、GPUやドライバ、メモリ、ブラウザ判断などにより実行中に失われる場合があります。DotLCD Cameraでは、コンテキスト消失時に描画を止め、状態を保持し、復旧後にGPU資源を作り直すか、Canvas 2Dへ切り替える設計が必要です。
基本情報
- 分類
- 対応・安全性
- この記事で扱うこと
- WebGLコンテキストは、GPUやドライバ、メモリ、ブラウザ判断などにより実行中に失われる場合があります。DotLCD Cameraでは、コンテキスト消失時に描画を止め、状態を保持し、復旧後にGPU資源を作り直すか、Canvas 2Dへ切り替える設計が必要です。
- 参照確認日
- 2026-07-24
結論と対象読者
WebGLコンテキストは、GPUやドライバ、メモリ、ブラウザ判断などにより実行中に失われる場合があります。DotLCD Cameraでは、コンテキスト消失時に描画を止め、状態を保持し、復旧後にGPU資源を作り直すか、Canvas 2Dへ切り替える設計が必要です。
この記事は、WebGL2を主描画経路にする実装者と、長時間利用やスマートフォンで黒画面になる問題へ備えたい人向けです。
30秒要約
webglcontextlostは描画バッファが失われたときに発生します。
- テクスチャ、シェーダー、バッファなどのGPU資源は作り直す前提で管理します。
- JavaScript側のプリセットや入力状態はGPU資源と分離して保持します。
- 復旧中は描画ループを止め、利用者へ状態を表示します。
- 復旧できない場合はCanvas 2Dフォールバックを使います。
概要と背景
WebGLでは、画像、シェーダー、頂点バッファ、フレームバッファなどをGPU側へ作成します。これらは通常のJavaScriptオブジェクトと同じ寿命で永続するとは限りません。
コンテキストが失われると、WebGLの描画結果やGPU資源は利用できなくなります。その状態で通常どおり描画を続けると、黒画面、例外の連続、無駄な処理が発生する可能性があります。
DotLCDでは、論理解像度、4階調閾値、パレット、ディザー設定、残像係数、シードなどをGPU外の状態として保持します。これにより、復旧時に同じ設定から資源を再構築できます。
特徴・できること
消失を検知できる
Canvasへwebglcontextlostイベントを登録し、描画停止と復旧待ちへ移行できます。このイベントは通常の親要素へバブリングしないため、対象Canvasへ直接登録します。
復旧時に再初期化できる
webglcontextrestored後は、シェーダー、プログラム、テクスチャ、バッファ、Uniform設定などを再作成します。失われる前のWebGLオブジェクトをそのまま再利用しません。
Canvas 2Dへ切り替えられる
復旧が繰り返し失敗する場合や、端末負荷が高い場合は、同じ論理設定をCanvas 2D経路へ渡します。
現在の位置付けと利用上の前提
webglcontextlostとwebglcontextrestoredはWebGLの標準イベントです。ただし、復旧が必ず成功するとは限りません。
実装では、次の状態を分けます。
- 通常描画中
- コンテキスト消失
- 復旧処理中
- 復旧成功
- Canvas 2Dへ切替
- 描画停止
WEBGL_lose_context拡張を利用できる環境では、開発時に意図的な消失と復旧を試験できます。これはテスト用であり、本番で消失を起こすための機能ではありません。
近い対象との比較
| 対象 | 対応 |
|---|
| 一時的なフレーム低下 | 品質やFPSを下げる |
| WebGLコンテキスト消失 | GPU資源を破棄扱いにして再構築 |
| カメラ停止 | MediaStreamTrackを停止 |
| ページ非表示 | 描画ループを一時停止 |
| 復旧不能 | Canvas 2Dへ切替または停止 |
確認/試行の条件と注意点
WEBGL_lose_contextで意図的にコンテキストを失わせます。
- 消失時に描画ループが止まるか確認します。
- UI操作やプリセット値が失われないか確認します。
- 復旧後にシェーダーとテクスチャが再作成されるか確認します。
- 残像バッファを復元するか、初期化するかを決めます。
- 復旧失敗時にCanvas 2Dへ切り替わるか確認します。
- 消失と復旧を複数回繰り返し、イベントリスナーやGPU資源が増殖しないか確認します。
復旧中に古いWebGLオブジェクトへアクセスし続けないことが重要です。アプリ状態とGPU状態を分離しておくと、フォールバックにも再現性にも有利です。
参考リンク
- MDN: webglcontextlost event
- https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/webglcontextlost_event
- MDN: webglcontextrestored event
- https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/webglcontextrestored_event
- MDN: WEBGL_lose_context
- https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context
← DotLCD Cameraの一覧へ戻る
追加調査で押さえる実務ポイント
webglcontextlostは、browserがWebGL rendering contextを失ったときにcanvasへ発生するeventです。GPU reset、driver、memory pressure、tab lifecycleなどが原因になり得ます。DotLCD Cameraでは、描画loopを停止し、JavaScript側のcamera・palette・dither・preset状態を保持し、webglcontextrestored後にshader、texture、buffer、framebufferをすべて再作成します。復旧不能ならCanvas 2Dへ切り替えます。
最初に実装すること
canvas.addEventListener("webglcontextlost", (event) => {
event.preventDefault();
stopRenderLoop();
state.contextLost = true;
showStatus("GPU描画を復旧しています");
});
canvas.addEventListener("webglcontextrestored", () => {
rebuildGpuResources();
state.contextLost = false;
startRenderLoop();
});
preventDefault()を呼ばないと復旧が試みられない場合があります。
失われるもの
- shader
- program
- texture
- buffer
- vertex array
- framebuffer
- renderbuffer
- query
- sampler
古いWebGL objectを再利用しません。
保持するもの
- camera constraints
- logical resolution
- palette
- threshold
- dither
- afterimage
- seed
- UI values
- selected preset
- export settings
GPU resourceとapplication stateを分離します。
状態遷移
running
-> context-lost
-> restoring
-> running
-> fallback-2d
-> stopped
event中にresource作成を試みず、restored後に再初期化します。
Cameraとの分離
WebGL contextが失われてもMediaStreamが必ず停止するわけではありません。camera track、video element、GPU texture uploadを別々に管理します。
Render loop
requestAnimationFrameを停止し、復旧後に二重起動しないようloop IDを管理します。listenerの重複登録も防ぎます。
開発時の強制test
const ext = gl.getExtension("WEBGL_lose_context");
ext?.loseContext();
setTimeout(() => {
ext?.restoreContext();
}, 1000);
test用extensionです。本番機能として使いません。
復旧test
- contextを強制消失。
- loop停止。
- UI保持。
- camera保持。
- GPU resource再作成。
- frame表示。
- 複数回繰り返す。
- memory leak確認。
- Canvas 2D fallback。
- export中断処理。
Canvas 2D fallback
品質・速度が下がっても、camera previewと基本filterを継続できる設計にします。WebGLとCanvas 2Dで同じapplication stateを共有します。
復旧を諦める条件
- 短時間に複数回消失
- resource作成error
- shader compile失敗
- memory不足
- browser background制約
- camera track終了
次に読む
参考リンク