Signatur
Beschreibung
restoreContext() gehört zur WebGL-Erweiterung WEBGL_lose_context. Die Methode stellt einen Kontext wieder her, der vorher mit loseContext() künstlich verloren wurde. Danach löst der Browser auf dem <canvas> das Ereignis webglcontextrestored aus.
Die Methode ist vor allem ein Werkzeug zum Testen. In der Praxis kann ein WebGL-Kontext jederzeit verloren gehen, zum Beispiel durch einen Absturz des GPU-Treibers, durch Energiesparmodi auf Mobilgeräten oder weil zu viele Kontexte gleichzeitig offen sind. Mit loseContext() und restoreContext() lässt sich dieser Ablauf gezielt nachstellen. So prüfen Sie, ob Ihre Anwendung alle GPU-Ressourcen korrekt neu anlegt: Shader, Programme, Puffer, Texturen und Framebuffer.
Wichtig: Durch die Wiederherstellung wird kein alter Zustand zurückgebracht. Alle WebGL-Objekte, die vor dem Verlust existierten, sind ungültig. Der Handler für webglcontextrestored muss sie komplett neu erzeugen. Damit eine Wiederherstellung überhaupt möglich ist, muss außerdem im Handler für webglcontextlost die Methode event.preventDefault() aufgerufen werden.
Rückgabewert
undefined). Die Wiederherstellung läuft asynchron ab und wird über das Ereignis webglcontextrestored gemeldet.Beispiele
Kontextverlust und Wiederherstellung simulieren
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
const ext = gl.getExtension('WEBGL_lose_context');
canvas.addEventListener('webglcontextlost', (event) => {
event.preventDefault(); // Voraussetzung für die Wiederherstellung
console.log('Kontext verloren:', gl.isContextLost());
});
canvas.addEventListener('webglcontextrestored', () => {
console.log('Kontext wiederhergestellt:', !gl.isContextLost());
});
ext.loseContext();
// Kurz warten, dann wiederherstellen
setTimeout(() => ext.restoreContext(), 1000);
Ressourcen nach der Wiederherstellung neu anlegen
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
let program = null;
let buffer = null;
const initResources = () => {
const vs = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vs, 'attribute vec2 p; void main(){ gl_Position = vec4(p, 0.0, 1.0); }');
gl.compileShader(vs);
const fs = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fs, 'precision mediump float; void main(){ gl_FragColor = vec4(1.0, 0.5, 0.0, 1.0); }');
gl.compileShader(fs);
program = gl.createProgram();
gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.linkProgram(program);
buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0.8, -0.8, -0.8, 0.8, -0.8]), gl.STATIC_DRAW);
};
const draw = () => {
if (gl.isContextLost()) return;
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(program);
const loc = gl.getAttribLocation(program, 'p');
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.enableVertexAttribArray(loc);
gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, 3);
};
canvas.addEventListener('webglcontextlost', (e) => e.preventDefault());
canvas.addEventListener('webglcontextrestored', () => {
initResources(); // alte Objekte sind ungültig
draw();
console.log('Szene neu aufgebaut');
});
initResources();
draw();
Testhilfe als Promise-basierte Funktion
const simulateContextLoss = (canvas, gl) => new Promise((resolve, reject) => {
const ext = gl.getExtension('WEBGL_lose_context');
if (!ext) return reject(new Error('WEBGL_lose_context nicht verfügbar'));
canvas.addEventListener('webglcontextlost', (e) => {
e.preventDefault();
ext.restoreContext();
}, { once: true });
canvas.addEventListener('webglcontextrestored', () => resolve(), { once: true });
ext.loseContext();
});
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2');
await simulateContextLoss(canvas, gl);
console.log('Test bestanden, Kontext aktiv:', !gl.isContextLost());
// Wichtig · Fallstricke
- Nur nach
loseContext(): Ist der Kontext nicht verloren, erzeugtrestoreContext()den FehlerINVALID_OPERATION(abrufbar übergl.getError()). Das gilt auch, wenn der Verlust nicht durch die Erweiterung simuliert wurde. preventDefault()ist Pflicht: Rufen Sieevent.preventDefault()im Handler fürwebglcontextlostnicht auf, wird der Kontext nie wiederhergestellt.- Asynchron: Die Wiederherstellung ist nicht sofort abgeschlossen, wenn der Aufruf zurückkehrt. Zeichnen Sie erst im Handler für
webglcontextrestoredwieder. - Kein Zustand bleibt erhalten: Alle alten
WebGLBuffer-,WebGLTexture-,WebGLProgram- und weiteren Objekte sind ungültig. Auch Erweiterungen müssen mitgetExtension()neu angefordert werden. Das ErweiterungsobjektWEBGL_lose_contextselbst bleibt benutzbar. - Kompatibilität: Die Methode wird von allen modernen Browsern unterstützt, sowohl mit WebGL 1 als auch mit WebGL 2. Prüfen Sie trotzdem immer, ob
getExtension()nichtnullzurückgibt. - Gedacht für Tests und Fehlersuche. Im Produktivcode sollten Sie echten Kontextverlust nicht auslösen, aber immer darauf reagieren können.