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

WebGL2RenderingContext.deleteQuery()

Methode

Löscht ein <code>WebGLQuery</code>-Objekt und gibt die zugehörigen GPU-Ressourcen frei.

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

Signatur

WebGL2RenderingContext.prototype.deleteQuery(query)

Beschreibung

Die Methode deleteQuery() des WebGL2RenderingContext gibt ein Abfrageobjekt (WebGLQuery) frei, das vorher mit createQuery() erzeugt wurde. Abfrageobjekte nutzt man für asynchrone GPU-Abfragen, etwa für Occlusion Queries (ANY_SAMPLES_PASSED, ANY_SAMPLES_PASSED_CONSERVATIVE) oder Transform-Feedback-Zählungen (TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN).

Rufe deleteQuery() auf, sobald du eine Abfrage nicht mehr brauchst – zum Beispiel beim Entfernen eines Objekts aus der Szene, beim Aufräumen eines Renderers oder wenn du eine Query-Pool-Struktur verkleinerst. Der Garbage Collector gibt GPU-Ressourcen zwar irgendwann frei, das geschieht aber nicht zuverlässig und nicht zeitnah.

Nach dem Löschen ist das Objekt ungültig: isQuery(query) liefert false, und wer es erneut mit beginQuery() oder getQueryParameter() verwendet, löst einen WebGL-Fehler aus. Ist die Abfrage gerade aktiv (zwischen beginQuery() und endQuery()), wird sie beim Löschen vom Ziel gelöst.

Parameter

Name Typ Default Beschreibung
$query Pflicht WebGLQuery | null Das zu löschende Abfrageobjekt. Bei null oder einem bereits gelöschten Objekt passiert nichts.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined).

Beispiele

Query erzeugen, nutzen und löschen

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

const query = gl.createQuery();
gl.beginQuery(gl.ANY_SAMPLES_PASSED, query);
// ... Zeichenbefehle, z. B. gl.drawArrays(...)
gl.endQuery(gl.ANY_SAMPLES_PASSED);

// Später, wenn nicht mehr benötigt:
gl.deleteQuery(query);
console.log(gl.isQuery(query));
false

Occlusion Query asynchron auswerten und danach aufräumen

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

gl.beginQuery(gl.ANY_SAMPLES_PASSED_CONSERVATIVE, query);
// Bounding-Box des Objekts zeichnen ...
gl.endQuery(gl.ANY_SAMPLES_PASSED_CONSERVATIVE);

const poll = () => {
  const ready = gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE);
  if (!ready) {
    requestAnimationFrame(poll); // Ergebnis frühestens im nächsten Frame
    return;
  }
  const visible = gl.getQueryParameter(query, gl.QUERY_RESULT);
  console.log('Sichtbar:', visible);
  gl.deleteQuery(query); // Ressource freigeben
};
requestAnimationFrame(poll);
Sichtbar: false

Query-Pool beim Zerstören eines Renderers leeren

class QueryPool {
  constructor(gl, size) {
    this.gl = gl;
    this.queries = Array.from({ length: size }, () => gl.createQuery());
  }
  dispose() {
    for (const q of this.queries) this.gl.deleteQuery(q);
    this.queries = [];
  }
}

const gl = document.createElement('canvas').getContext('webgl2');
const pool = new QueryPool(gl, 8);
pool.dispose();
console.log(pool.queries.length);

// Wichtig · Fallstricke

  • Nur WebGL 2: Im WebGL-1-Kontext gibt es deleteQuery() nicht; dort bietet die Erweiterung EXT_disjoint_timer_query deleteQueryEXT(). Zeitmessungen in WebGL 2 laufen über EXT_disjoint_timer_query_webgl2 (Ziel TIME_ELAPSED_EXT), gelöscht wird trotzdem mit deleteQuery().
  • Eine gelöschte Query danach weiterzuverwenden erzeugt INVALID_OPERATION. Setze deine Referenz nach dem Löschen am besten auf null.
  • Lösche eine Query nicht, solange du noch auf ihr Ergebnis wartest – sonst geht es verloren.
  • Geht der Kontext verloren (webglcontextlost), sind alle Queries ohnehin ungültig; ein Aufruf von deleteQuery() schadet dann nicht, bewirkt aber auch nichts.
  • Du kannst Query-Objekte wiederverwenden, statt sie in jedem Frame neu anzulegen und zu löschen – das ist schneller.