Start · Sprachen · JavaScript · Referenz · WebGL2RenderingContext.waitSync()

WebGL2RenderingContext.waitSync()

Methode

Kehrt sofort zurück und weist den GL-Server an, nachfolgende Befehle erst auszuführen, wenn das angegebene <code>WebGLSync</code>-Objekt signalisiert wurde.

seit JavaScript WebGL 2.0 – Baseline: alle modernen Browser (seit Kategorie: webapi

Signatur

WebGL2RenderingContext.prototype.waitSync(sync, flags, timeout)

Beschreibung

waitSync() fügt eine serverseitige Wartebedingung in den GL-Befehlsstrom ein. Der JavaScript-Aufruf blockiert nicht: Die Methode kehrt sofort zurück, aber die GPU bzw. der GL-Server führt alle danach abgesetzten Befehle erst aus, wenn das mit fenceSync() erzeugte Sync-Objekt signalisiert ist.

Anders als clientWaitSync(), das den aufrufenden Thread (höchstens bis zum Timeout) warten lässt und den Sync-Status abfragt, synchronisiert waitSync() nur die Befehlsreihenfolge auf der GPU-Seite. In klassischem OpenGL ist das vor allem für die Synchronisation zwischen mehreren Kontexten mit geteilten Ressourcen gedacht. Da WebGL-Kontexte keine Objekte miteinander teilen und Befehle innerhalb eines Kontextes ohnehin der Reihe nach ausgeführt werden, ist der praktische Nutzen in WebGL gering – der Aufruf ist hauptsächlich aus Gründen der API-Vollständigkeit vorhanden.

Die Parameter sind fest vorgegeben: flags muss 0 sein und timeout muss gl.TIMEOUT_IGNORED sein. Andere Werte erzeugen den Fehler gl.INVALID_VALUE. Für echte CPU/GPU-Synchronisation (z. B. asynchrones Zurücklesen von Pixeln) verwendet man stattdessen clientWaitSync() oder getSyncParameter() mit Polling.

Parameter

Name Typ Default Beschreibung
$sync Pflicht WebGLSync Das Sync-Objekt, auf dessen Signalisierung gewartet werden soll, erzeugt mit gl.fenceSync().
$flags Pflicht GLbitfield (number) 0 Reserviert; muss 0 sein.
$timeout Pflicht GLint64 (number) gl.TIMEOUT_IGNORED Muss gl.TIMEOUT_IGNORED (-1) sein; ein echtes Timeout wird nicht unterstützt.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined). Fehler werden über gl.getError() gemeldet.

Beispiele

Grundlegender Aufruf nach fenceSync()

const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2');

// Zeichenbefehle absetzen ...
gl.clearColor(0.1, 0.2, 0.3, 1);
gl.clear(gl.COLOR_BUFFER_BIT);

// Fence einfügen und GPU-seitig darauf warten lassen
const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
gl.waitSync(sync, 0, gl.TIMEOUT_IGNORED);

// Folgebefehle laufen erst nach Signalisierung des Fence
gl.clear(gl.COLOR_BUFFER_BIT);

gl.deleteSync(sync);
console.log(gl.getError() === gl.NO_ERROR);
true

Falsche Parameter erzeugen INVALID_VALUE

const gl = document.createElement('canvas').getContext('webgl2');
const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);

// timeout muss TIMEOUT_IGNORED sein
gl.waitSync(sync, 0, 1000);
console.log(gl.getError() === gl.INVALID_VALUE);

gl.deleteSync(sync);
true

Vergleich: CPU-seitiges Warten per Polling statt waitSync()

const gl = document.createElement('canvas').getContext('webgl2');

const waitForGpu = (gl) => new Promise((resolve) => {
  const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
  gl.flush();
  const check = () => {
    const status = gl.clientWaitSync(sync, 0, 0);
    if (status === gl.ALREADY_SIGNALED || status === gl.CONDITION_SATISFIED) {
      gl.deleteSync(sync);
      resolve();
    } else {
      setTimeout(check, 1);
    }
  };
  check();
});

await waitForGpu(gl);
console.log('GPU-Befehle abgeschlossen');
GPU-Befehle abgeschlossen

// Wichtig · Fallstricke

  • Blockiert JavaScript nicht: waitSync() garantiert nicht, dass die GPU-Arbeit fertig ist, wenn der Aufruf zurückkehrt. Für CPU-seitige Synchronisation clientWaitSync() bzw. getSyncParameter(sync, gl.SYNC_STATUS) verwenden.
  • flags muss 0 und timeout muss gl.TIMEOUT_IGNORED sein, sonst INVALID_VALUE. Ein ungültiges oder gelöschtes Sync-Objekt führt zu INVALID_OPERATION.
  • Da WebGL-Kontexte keine Ressourcen teilen, ist der Aufruf in der Praxis meist wirkungslos; im Normalfall ist er verzichtbar.
  • Sync-Objekte nach Gebrauch mit deleteSync() freigeben, um Ressourcenlecks zu vermeiden.
  • Nur in WebGL 2 verfügbar (getContext('webgl2')); in allen aktuellen Browsern unterstützt, nicht aber in WebGL 1.