Start · Sprachen · JavaScript · Referenz · WEBGL_lose_context.loseContext()

WEBGL_lose_context.loseContext()

Methode

Simuliert den Verlust des WebGL-Kontexts, damit sich Code zum Behandeln von Kontextverlust und Wiederherstellung gezielt testen lässt.

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

Signatur

WEBGL_lose_context.prototype.loseContext()

Beschreibung

loseContext() ist eine Methode der Erweiterung WEBGL_lose_context. Sie versetzt einen WebGLRenderingContext oder WebGL2RenderingContext künstlich in den Zustand „Kontext verloren“. Echte Kontextverluste kommen in der Praxis vor, etwa bei einem Absturz des GPU-Treibers, wenn das Betriebssystem den Grafikspeicher freigibt oder wenn der Browser bei zu vielen aktiven Kontexten alte Kontexte schließt. Mit dieser Methode lässt sich dieser Fall zuverlässig nachstellen.

Nach dem Aufruf löst das Canvas das Ereignis webglcontextlost aus. Alle WebGL-Ressourcen werden ungültig, also Texturen, Buffer, Shader, Programme und Framebuffer. gl.isContextLost() liefert dann true. Nur wenn im Handler von webglcontextlost die Methode event.preventDefault() aufgerufen wurde, kann der Kontext später wiederhergestellt werden. Das geschieht mit restoreContext() und löst das Ereignis webglcontextrestored aus.

Typische Einsatzgebiete:

  • Automatisierte Tests der Wiederherstellungslogik: Ressourcen neu anlegen und die Render-Schleife neu starten.
  • Gezieltes Freigeben der GPU-Ressourcen eines Canvas, das nicht mehr gebraucht wird, zum Beispiel beim Unmount einer Komponente in einer Single-Page-App.

Rückgabewert

Typ
undefined
Beschreibung
Kein Rückgabewert. Der Kontextverlust wird über das Ereignis webglcontextlost am Canvas gemeldet. Dieses Ereignis wird asynchron ausgelöst.

Beispiele

Kontextverlust simulieren und wiederherstellen

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

canvas.addEventListener('webglcontextlost', (event) => {
  event.preventDefault(); // nötig, damit eine Wiederherstellung möglich ist
  console.log('Kontext verloren:', gl.isContextLost());
  // Wiederherstellung nach einer Sekunde anstoßen
  setTimeout(() => ext.restoreContext(), 1000);
});

canvas.addEventListener('webglcontextrestored', () => {
  console.log('Kontext wiederhergestellt:', !gl.isContextLost());
  // Hier alle Shader, Buffer und Texturen neu anlegen
});

ext.loseContext();
Kontext verloren: true Kontext wiederhergestellt: true

Wiederherstellungslogik einer Render-Schleife testen

const canvas = document.createElement('canvas');
document.body.append(canvas);
const gl = canvas.getContext('webgl2');
let frameId = null;

const initResources = () => {
  // Shader kompilieren, Buffer anlegen usw.
  gl.clearColor(0.1, 0.4, 0.8, 1);
};

const render = () => {
  gl.clear(gl.COLOR_BUFFER_BIT);
  frameId = requestAnimationFrame(render);
};

canvas.addEventListener('webglcontextlost', (e) => {
  e.preventDefault();
  cancelAnimationFrame(frameId);
  console.log('Render-Schleife gestoppt');
});

canvas.addEventListener('webglcontextrestored', () => {
  initResources();
  render();
  console.log('Render-Schleife neu gestartet');
});

initResources();
render();

// Testfall: Verlust erzwingen, danach wiederherstellen
const ext = gl.getExtension('WEBGL_lose_context');
ext?.loseContext();
setTimeout(() => ext?.restoreContext(), 500);
Render-Schleife gestoppt Render-Schleife neu gestartet

GPU-Ressourcen beim Entfernen eines Canvas freigeben

const destroyWebGLCanvas = (canvas) => {
  const gl = canvas.getContext('webgl') ?? canvas.getContext('webgl2');
  gl?.getExtension('WEBGL_lose_context')?.loseContext();
  canvas.width = canvas.height = 1; // Speicher des Drawing-Buffers verkleinern
  canvas.remove();
};

const canvas = document.querySelector('#preview');
destroyWebGLCanvas(canvas);
console.log('Canvas entfernt, Kontext freigegeben');
Canvas entfernt, Kontext freigegeben

// Wichtig · Fallstricke

  • Kein preventDefault(), keine Wiederherstellung: Wird event.preventDefault() im Handler von webglcontextlost nicht aufgerufen, bleibt der Kontext dauerhaft verloren. Ein späteres restoreContext() hat dann keine Wirkung.
  • Erweiterungsobjekt vorher speichern: Solange der Kontext verloren ist, liefert getExtension() den Wert null. Speichere das Objekt deshalb, bevor du loseContext() aufrufst.
  • Fehler bei doppeltem Aufruf: Ist der Kontext bereits verloren, erzeugt ein erneuter Aufruf von loseContext() den WebGL-Fehler INVALID_OPERATION. Diesen Fehler kannst du mit gl.getError() abfragen.
  • Ressourcen neu anlegen: Alle WebGL-Objekte von vor dem Verlust sind danach ungültig. Nach webglcontextrestored müssen Shader, Programme, Buffer und Texturen vollständig neu erzeugt werden.
  • Ereignisse kommen asynchron: Das Ereignis webglcontextlost wird nicht synchron während des Aufrufs ausgelöst.
  • Kompatibilität: Die Erweiterung wird von allen modernen Browsern für WebGL 1 und WebGL 2 unterstützt. Prüfe trotzdem, ob getExtension() ein Objekt zurückgibt, zum Beispiel mit optionaler Verkettung (?.).