Signatur
Beschreibung
WebGL-Aufrufe wie drawArrays() oder clear() werden nicht sofort auf der GPU ausgeführt. Der Browser sammelt sie in Befehls-Puffern und schickt sie in Blöcken an den Grafiktreiber weiter. flush() veranlasst, dass alle bisher gesammelten Befehle ohne weitere Verzögerung übergeben werden. Die Methode wartet aber nicht, bis die GPU fertig ist. Sie kehrt sofort zurück.
Normalerweise brauchen Sie flush() nicht. Wenn ein Frame endet und der Browser das Canvas darstellt, wird ohnehin geleert. Sinnvoll ist ein expliziter Aufruf in Sonderfällen:
- Sie haben viele Befehle abgesetzt und warten danach länger, etwa auf ein
setTimeoutoder ein Netzwerk-Ergebnis, ohne dass der Frame endet. - Sie nutzen in WebGL 2 Sync-Objekte (
fenceSync()) oder asynchrone Abfragen. Diese können nur signalisiert werden, wenn die Befehle wirklich an die GPU gegangen sind. - Sie arbeiten in einem Worker mit
OffscreenCanvasohne regelmäßige Frame-Grenzen.
Im Gegensatz dazu blockiert finish(), bis alle Befehle vollständig ausgeführt sind. Das kostet viel Leistung. flush() ist die günstige, nicht blockierende Variante.
Rückgabewert
undefined).Beispiele
Einfacher Aufruf nach dem Zeichnen
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
gl.clearColor(0.1, 0.2, 0.3, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
// Befehle sofort an die GPU übergeben, ohne zu warten
gl.flush();
console.log('Befehle übergeben');
WebGL 2: Fence-Sync nicht blockierend abfragen
const gl = document.querySelector('canvas').getContext('webgl2');
// ... aufwendiges Rendering in einen Framebuffer ...
gl.clear(gl.COLOR_BUFFER_BIT);
const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
// Ohne flush() wird der Fence womöglich nie signalisiert
gl.flush();
const waitForGpu = () => new Promise((resolve) => {
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();
console.log('GPU ist fertig – jetzt readPixels ohne Stall möglich');
Rendering in einem Worker mit OffscreenCanvas
// worker.js
self.onmessage = ({ data }) => {
const gl = data.canvas.getContext('webgl');
gl.clearColor(1, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// Arbeit anstoßen, bevor der Worker auf die nächste Nachricht wartet
gl.flush();
self.postMessage('gerendert');
};
// Wichtig · Fallstricke
- Keine Synchronisation:
flush()garantiert nicht, dass die Befehle beim Rückkehren schon ausgeführt sind. Um auf das Ende zu warten, nutzen Siefinish()(blockiert) oder besser in WebGL 2fenceSync()zusammen mitclientWaitSync(). - Leistung: Wenn Sie
flush()in jedem Draw-Call oder mehrmals pro Frame aufrufen, erzeugt das unnötigen Aufwand im Treiber und kann die Bildrate senken. Im normalenrequestAnimationFrame-Ablauf ist die Methode überflüssig. - Verlorener Kontext: Ist der Kontext verloren (
webglcontextlost), bewirkt der Aufruf nichts. - Kompatibilität: Die Methode wird von allen modernen Browsern unterstützt und steht auch auf
WebGL2RenderingContextzur Verfügung.