Start · Sprachen · JavaScript · Referenz · WebGLContextEvent

WebGLContextEvent

Schnittstelle

Ereignis-Schnittstelle der WebGL API, die bei Statusänderungen des WebGL-Rendering-Kontextes ausgelöst wird, etwa bei Kontextverlust oder -wiederherstellung.

seit JavaScript Baseline: alle modernen Browser (WebGL 1.0) Kategorie: webapi

Signatur

interface WebGLContextEvent extends Event

Beschreibung

WebGLContextEvent ist Teil der WebGL API und beschreibt Ereignisse, die ein <canvas>-Element auslöst, wenn sich der Zustand seines WebGL-Rendering-Kontextes ändert. Die Schnittstelle erbt von Event und ergänzt nur eine Eigenschaft: statusMessage, einen String mit zusätzlichen, meist plattformabhängigen Informationen zur Ursache.

Es gibt drei Ereignistypen:

  • webglcontextlost: Der Kontext ist verloren gegangen, z. B. nach einem GPU-Reset, einem Treiber-Update, zu vielen aktiven Kontexten oder weil das Betriebssystem Grafikspeicher zurückgefordert hat.
  • webglcontextrestored: Der Browser hat den Kontext wiederhergestellt. Allerdings nur, wenn im webglcontextlost-Handler event.preventDefault() aufgerufen wurde.
  • webglcontextcreationerror: canvas.getContext("webgl") konnte keinen Kontext erzeugen. statusMessage nennt dann oft den Grund.

Robuste WebGL-Anwendungen sollten diese Ereignisse immer behandeln. Nach einem Kontextverlust sind alle GPU-Ressourcen ungültig, also Texturen, Puffer, Shader, Programme und Framebuffer. Sie müssen nach webglcontextrestored komplett neu angelegt werden. Die Render-Schleife sollte außerdem angehalten werden, solange der Kontext fehlt.

Den Konstruktor new WebGLContextEvent(type, options) braucht man selten direkt. Er ist vor allem für Tests nützlich, um Kontextereignisse zu simulieren. Für echte Verlust-Tests eignet sich die Erweiterung WEBGL_lose_context besser.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Name des Ereignisses (nur im Konstruktor): "webglcontextlost", "webglcontextrestored" oder "webglcontextcreationerror".
$options object {} Optionales Objekt (nur im Konstruktor) mit den Feldern von EventInit (bubbles, cancelable, composed) sowie statusMessage (string, Standard "").
$statusMessage string "" Nur lesbare Instanz-Eigenschaft mit zusätzlichen Informationen zum Ereignis. Der Inhalt hängt von Browser und Plattform ab und ist oft leer.

Rückgabewert

Typ
WebGLContextEvent
Beschreibung
Der Konstruktor gibt ein neues WebGLContextEvent-Objekt zurück. In Event-Handlern erhält man die Instanz als Argument.

Beispiele

Kontextverlust und Wiederherstellung sauber behandeln

const canvas = document.querySelector('#scene');
let gl = canvas.getContext('webgl');
let frameId = null;
let resources = null;

const initResources = (gl) => {
  // Shader, Puffer und Texturen hier (neu) anlegen
  const buffer = gl.createBuffer();
  return { buffer };
};

const render = () => {
  gl.clearColor(0.1, 0.2, 0.3, 1);
  gl.clear(gl.COLOR_BUFFER_BIT);
  frameId = requestAnimationFrame(render);
};

canvas.addEventListener('webglcontextlost', (event) => {
  event.preventDefault(); // nötig, damit eine Wiederherstellung möglich ist
  cancelAnimationFrame(frameId);
  resources = null;
  console.warn('Kontext verloren:', event.statusMessage || '(keine Details)');
});

canvas.addEventListener('webglcontextrestored', () => {
  console.log('Kontext wiederhergestellt');
  resources = initResources(gl); // alle GPU-Ressourcen neu erzeugen
  render();
});

resources = initResources(gl);
render();
Kontext verloren: (keine Details) Kontext wiederhergestellt

Fehlerursache bei fehlgeschlagener Kontexterzeugung ermitteln

const canvas = document.createElement('canvas');
let reason = '';

const onError = (event) => {
  reason = event.statusMessage;
};

canvas.addEventListener('webglcontextcreationerror', onError, { once: true });
const gl = canvas.getContext('webgl2') ?? canvas.getContext('webgl');

if (!gl) {
  console.error(`WebGL nicht verfügbar: ${reason || 'unbekannter Grund'}`);
} else {
  console.log('WebGL-Version:', gl.getParameter(gl.VERSION));
}
WebGL-Version: WebGL 2.0 (OpenGL ES 3.0 Chromium)

Kontextverlust mit WEBGL_lose_context testen

const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
const ext = gl.getExtension('WEBGL_lose_context');

canvas.onwebglcontextlost = (event) => {
  event.preventDefault();
  console.log(event instanceof WebGLContextEvent, event.type);
  // nach 1 Sekunde wiederherstellen
  setTimeout(() => ext.restoreContext(), 1000);
};

canvas.onwebglcontextrestored = (event) => {
  console.log(event.type, gl.isContextLost());
};

ext?.loseContext();
true webglcontextlost webglcontextrestored false

Ereignis manuell erzeugen (z. B. für Unit-Tests)

const event = new WebGLContextEvent('webglcontextlost', {
  cancelable: true,
  statusMessage: 'Simulierter GPU-Reset'
});

console.log(event.type, event.statusMessage, event.cancelable);
webglcontextlost Simulierter GPU-Reset true

// Wichtig · Fallstricke

  • Ohne preventDefault() keine Wiederherstellung: Wird im webglcontextlost-Handler nicht event.preventDefault() aufgerufen, stellt der Browser den Kontext nie wieder her, und webglcontextrestored tritt nicht auf.
  • Alle Ressourcen sind ungültig: Nach einem Verlust sind alle WebGLBuffer-, WebGLTexture-, WebGLProgram- und ähnlichen Objekte unbrauchbar. Das Kontextobjekt gl selbst bleibt dieselbe Instanz. Die Ressourcen darin müssen aber neu erzeugt werden. Aufrufe während des Verlusts werden stillschweigend ignoriert; gl.getError() gibt CONTEXT_LOST_WEBGL zurück.
  • statusMessage ist unzuverlässig: Der Inhalt ist nicht standardisiert und oft leer. Er eignet sich für Logs, aber nicht für Programmlogik.
  • Handler vor getContext() registrieren: webglcontextcreationerror wird synchron während getContext() ausgelöst. Ein Listener, der erst danach registriert wird, verpasst das Ereignis.
  • Häufiger als gedacht: Auf Mobilgeräten treten Kontextverluste regelmäßig auf, etwa wenn ein Tab in den Hintergrund geht. Das gilt auch, wenn zu viele WebGL-Kontexte gleichzeitig aktiv sind. Browser begrenzen die Anzahl, typischerweise auf etwa 16.
  • Kompatibilität: In allen modernen Browsern verfügbar, auch in Workern mit OffscreenCanvas. Die Ereignisse gelten gleichermaßen für WebGL 1 und WebGL 2.