Signatur
Beschreibung
Ein WebGL-Kontext kann jederzeit verloren gehen, etwa wenn der Grafiktreiber abstürzt oder zurückgesetzt wird, das Betriebssystem GPU-Ressourcen freigibt, ein mobiles Gerät in den Ruhezustand wechselt oder der Browser zu viele aktive WebGL-Kontexte hat. Danach sind alle GPU-Ressourcen wie Texturen, Puffer, Shader und Programme ungültig.
isContextLost() fragt diesen Zustand ab. Die Methode liefert true, solange der Kontext verloren ist, und wieder false, sobald er wiederhergestellt wurde. Während der Kontext verloren ist, bewirken die meisten WebGL-Aufrufe nichts und geben null, 0 oder false zurück. getError() meldet dann einmalig CONTEXT_LOST_WEBGL.
In der Praxis reagiert man auf Kontextverluste über die Events webglcontextlost und webglcontextrestored am <canvas>. isContextLost() braucht man ergänzend für Prüfungen an bestimmten Stellen: bevor man eine Fehlermeldung ausgibt (zum Beispiel wenn das Kompilieren eines Shaders scheinbar fehlschlägt), in der Render-Schleife oder in Tests.
Rückgabewert
true, wenn der Kontext verloren ist, sonst false.Beispiele
Shader-Fehler von Kontextverlust unterscheiden
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
const compileShader = (type, source) => {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
// Ohne Kontext liefert getShaderParameter immer false, das ist aber kein echter Fehler
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS) && !gl.isContextLost()) {
console.error('Shader-Fehler:', gl.getShaderInfoLog(shader));
return null;
}
return shader;
};
const vs = compileShader(gl.VERTEX_SHADER, 'void main() { gl_Position = vec4(0.0); }');
console.log(vs !== null);
Render-Schleife mit Events und isContextLost()
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
let frameId = 0;
const initResources = () => {
// Hier Shader, Puffer und Texturen neu anlegen
gl.clearColor(0.1, 0.2, 0.3, 1);
};
const render = () => {
if (gl.isContextLost()) return; // Schleife anhalten
gl.clear(gl.COLOR_BUFFER_BIT);
frameId = requestAnimationFrame(render);
};
canvas.addEventListener('webglcontextlost', (event) => {
event.preventDefault(); // nötig, damit der Kontext wiederhergestellt werden kann
cancelAnimationFrame(frameId);
console.log('Kontext verloren:', gl.isContextLost());
});
canvas.addEventListener('webglcontextrestored', () => {
console.log('Kontext wiederhergestellt:', !gl.isContextLost());
initResources();
render();
});
initResources();
render();
Kontextverlust mit WEBGL_lose_context simulieren
const gl = document.createElement('canvas').getContext('webgl');
const ext = gl.getExtension('WEBGL_lose_context');
gl.canvas.addEventListener('webglcontextlost', (e) => e.preventDefault());
console.log('Vorher:', gl.isContextLost());
ext.loseContext();
console.log('Nachher:', gl.isContextLost());
// Später wiederherstellen (asynchron)
setTimeout(() => {
ext.restoreContext();
gl.canvas.addEventListener('webglcontextrestored', () => {
console.log('Wiederhergestellt:', !gl.isContextLost());
});
}, 500);
// Wichtig · Fallstricke
- Ohne
preventDefault()keine Wiederherstellung: Wird im Handler fürwebglcontextlostnichtevent.preventDefault()aufgerufen, stellt der Browser den Kontext nie wieder her.isContextLost()liefert dann dauerhafttrue. - Nach der Wiederherstellung sind alle alten WebGL-Objekte ungültig, also Texturen, Puffer, Programme und Framebuffer. Sie müssen neu angelegt werden, und auch Zustände wie
clearColoroderviewportsind zurückgesetzt. - Die Wiederherstellung läuft immer asynchron. Unmittelbar nach
restoreContext()gibtisContextLost()nochtruezurück. - Browser begrenzen die Zahl gleichzeitig aktiver Kontexte (oft etwa 16). Wird die Grenze überschritten, verliert der älteste Kontext seine Verbindung. Nicht mehr benötigte Kontexte gibt man mit
WEBGL_lose_context.loseContext()frei. - Die Methode gibt es auch bei
WebGL2RenderingContext, und sie wird in allen modernen Browsern unterstützt.OffscreenCanvaslöst dieselben Events aus.