Signatur
Beschreibung
Die Methode getSyncParameter() fragt Zustandsinformationen eines WebGLSync-Objekts ab. Solche Sync-Objekte entstehen mit gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0) und markieren eine Stelle im GPU-Befehlsstrom. Sobald die GPU alle Befehle bis zu diesem Punkt abgearbeitet hat, wird der Fence signalisiert.
Der wichtigste Anwendungsfall ist das nicht blockierende Abfragen (Polling), ob die GPU fertig ist – etwa bevor man mit gl.getBufferSubData() Daten aus einem Pixel-Buffer-Objekt (PBO) zurückliest. Statt die Hauptschleife mit gl.finish() oder clientWaitSync() mit großem Timeout anzuhalten, prüft man in jedem Frame per getSyncParameter(sync, gl.SYNC_STATUS), ob der Status gl.SIGNALED ist.
Über pname lassen sich vier Eigenschaften abfragen:
gl.OBJECT_TYPE– immergl.SYNC_FENCEgl.SYNC_STATUS–gl.SIGNALEDodergl.UNSIGNALEDgl.SYNC_CONDITION– immergl.SYNC_GPU_COMMANDS_COMPLETEgl.SYNC_FLAGS– immer0
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $sync Pflicht | WebGLSync | Das abzufragende Sync-Objekt, erzeugt mit gl.fenceSync(). |
|
| $pname Pflicht | GLenum | Die abzufragende Eigenschaft: gl.OBJECT_TYPE, gl.SYNC_STATUS, gl.SYNC_CONDITION oder gl.SYNC_FLAGS. |
Rückgabewert
pname: gl.SYNC_FENCE, gl.SIGNALED/gl.UNSIGNALED, gl.SYNC_GPU_COMMANDS_COMPLETE oder 0. Bei Fehlern (z. B. ungültiges pname, verlorener Kontext) null.Beispiele
Status eines Fence abfragen
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2');
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
gl.flush(); // Befehle an die GPU übergeben
const status = gl.getSyncParameter(sync, gl.SYNC_STATUS);
console.log(status === gl.SIGNALED ? 'fertig' : 'noch in Arbeit');
console.log(gl.getSyncParameter(sync, gl.OBJECT_TYPE) === gl.SYNC_FENCE);
console.log(gl.getSyncParameter(sync, gl.SYNC_FLAGS));
gl.deleteSync(sync);
Nicht blockierendes Warten mit Promise
const waitForGpu = (gl, sync) => new Promise((resolve) => {
const check = () => {
if (gl.getSyncParameter(sync, gl.SYNC_STATUS) === gl.SIGNALED) {
gl.deleteSync(sync);
resolve();
} else {
requestAnimationFrame(check);
}
};
check();
});
const gl = document.createElement('canvas').getContext('webgl2');
// ... aufwendiges Rendering ...
const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
gl.flush();
await waitForGpu(gl, sync);
console.log('GPU hat alle Befehle abgearbeitet');
Asynchrones Pixel-Readback über ein PBO
const gl = document.createElement('canvas').getContext('webgl2');
const width = gl.drawingBufferWidth;
const height = gl.drawingBufferHeight;
const pbo = gl.createBuffer();
gl.bindBuffer(gl.PIXEL_PACK_BUFFER, pbo);
gl.bufferData(gl.PIXEL_PACK_BUFFER, width * height * 4, gl.STREAM_READ);
// readPixels schreibt in das PBO, blockiert also nicht
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, 0);
const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null);
gl.flush();
const poll = () => {
if (gl.getSyncParameter(sync, gl.SYNC_STATUS) !== gl.SIGNALED) {
setTimeout(poll, 4);
return;
}
gl.deleteSync(sync);
const pixels = new Uint8Array(width * height * 4);
gl.bindBuffer(gl.PIXEL_PACK_BUFFER, pbo);
gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0, pixels);
gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null);
console.log('Erstes Pixel:', pixels.slice(0, 4));
};
poll();
// Wichtig · Fallstricke
- Status ändert sich nicht innerhalb desselben Tasks: Laut WebGL-2-Spezifikation darf der Browser den Wert von
SYNC_STATUSerst aktualisieren, nachdem die Kontrolle an die Ereignisschleife zurückgegeben wurde. Eine engewhile-Schleife, die ständig abfragt, läuft deshalb endlos – immer überrequestAnimationFrameodersetTimeoutabfragen. gl.flush()nicht vergessen: Ohne Flush werden die Befehle eventuell nie an die GPU übergeben, und der Fence wird nie signalisiert.- Sync-Objekte mit
gl.deleteSync()freigeben, sonst sammeln sich Ressourcen an. - Ein ungültiges
pnameerzeugtgl.INVALID_ENUM(prüfbar mitgl.getError()), und die Methode gibtnullzurück. Bei verlorenem Kontext ebenfallsnull. - Nur im
webgl2-Kontext verfügbar, nicht in WebGL 1. Wird von allen aktuellen Browsern unterstützt (Safari ab 15).