UNPKG

playcanvas

Version:

Open-source WebGL/WebGPU 3D engine for the web

80 lines (79 loc) 2.77 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); import { DynamicBuffers } from "../dynamic-buffers.js"; import { WebglDynamicBuffer } from "./webgl-dynamic-buffer.js"; class WebglDynamicBuffers extends DynamicBuffers { /** * @param {WebglGraphicsDevice} device - The graphics device. */ constructor(device) { super(device, 0, 0); /** * Free buffers available for allocation, keyed by byte size. * * @type {Map<number, WebglDynamicBuffer[]>} */ __publicField(this, "free", /* @__PURE__ */ new Map()); /** * Buffers handed out during the current frame, returned to the free pool at frame end. * * @type {WebglDynamicBuffer[]} */ __publicField(this, "used", []); } destroy() { this.used.forEach((buffer) => buffer.destroy(this.device)); this.free.forEach((buffers) => buffers.forEach((buffer) => buffer.destroy(this.device))); this.used = null; this.free = null; } /** * Allocate a whole buffer of the given size for this frame. * * @param {DynamicBufferAllocation} allocation - The allocation info to fill. * @param {number} size - The size of the allocation. */ alloc(allocation, size) { let buffer = this.free.get(size)?.pop(); if (!buffer) { buffer = new WebglDynamicBuffer(this.device, size); } this.used.push(buffer); allocation.gpuBuffer = buffer; allocation.offset = 0; allocation.storage = buffer.storage; } /** * Return the frame's buffers to the free pool. Called at the end of the frame, so it runs after * all allocations (including any made before frameStart, e.g. from app update handlers). */ onFrameEnd() { const used = this.used; for (let i = 0; i < used.length; i++) { const buffer = used[i]; let pool = this.free.get(buffer.size); if (!pool) { pool = []; this.free.set(buffer.size, pool); } pool.push(buffer); } used.length = 0; } /** * Called when the rendering context is lost. Returns any in-flight buffers to the free pool and * drops every buffer's GL handle (without deleting - the context is invalid). The buffer objects * and their CPU storage are kept, so they are reused and their GL buffers recreated on the next * upload after the context is restored. */ loseContext() { this.onFrameEnd(); this.free.forEach((buffers) => { buffers.forEach((buffer) => buffer.loseContext()); }); } } export { WebglDynamicBuffers };