Start · Sprachen · JavaScript · Referenz · WebGLRenderingContext.isContextLost()

WebGLRenderingContext.isContextLost()

Methode

Gibt <code>true</code> zurück, wenn der WebGL-Kontext verloren gegangen ist und neu aufgebaut werden muss, bevor weiter gerendert werden kann.

seit JavaScript Baseline: alle modernen Browser (WebGL 1 und WebGL Kategorie: webapi

Signatur

WebGLRenderingContext.prototype.isContextLost()

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

Typ
boolean
Beschreibung
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);
true

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();
Kontext verloren: true Kontext wiederhergestellt: true

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);
Vorher: false Nachher: true Wiederhergestellt: true

// Wichtig · Fallstricke

  • Ohne preventDefault() keine Wiederherstellung: Wird im Handler für webglcontextlost nicht event.preventDefault() aufgerufen, stellt der Browser den Kontext nie wieder her. isContextLost() liefert dann dauerhaft true.
  • 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 clearColor oder viewport sind zurückgesetzt.
  • Die Wiederherstellung läuft immer asynchron. Unmittelbar nach restoreContext() gibt isContextLost() noch true zurü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. OffscreenCanvas löst dieselben Events aus.