Signatur
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 imwebglcontextlost-Handlerevent.preventDefault()aufgerufen wurde.webglcontextcreationerror:canvas.getContext("webgl")konnte keinen Kontext erzeugen.statusMessagenennt 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
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();
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));
}
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();
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);
// Wichtig · Fallstricke
- Ohne
preventDefault()keine Wiederherstellung: Wird imwebglcontextlost-Handler nichtevent.preventDefault()aufgerufen, stellt der Browser den Kontext nie wieder her, undwebglcontextrestoredtritt nicht auf. - Alle Ressourcen sind ungültig: Nach einem Verlust sind alle
WebGLBuffer-,WebGLTexture-,WebGLProgram- und ähnlichen Objekte unbrauchbar. Das Kontextobjektglselbst bleibt dieselbe Instanz. Die Ressourcen darin müssen aber neu erzeugt werden. Aufrufe während des Verlusts werden stillschweigend ignoriert;gl.getError()gibtCONTEXT_LOST_WEBGLzurück. statusMessageist 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:webglcontextcreationerrorwird synchron währendgetContext()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.