playcanvas
Version:
Open-source WebGL/WebGPU 3D engine for the web
135 lines (134 loc) • 4.74 kB
JavaScript
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 { Debug } from "../../core/debug.js";
import { TRACEID_VRAM_VB } from "../../core/constants.js";
import { BUFFER_STATIC } from "./constants.js";
let id = 0;
class VertexBuffer {
/**
* Create a new VertexBuffer instance.
*
* @param {GraphicsDevice} graphicsDevice - The graphics device used to manage this vertex
* buffer.
* @param {VertexFormat} format - The vertex format of this vertex buffer.
* @param {number} numVertices - The number of vertices that this vertex buffer will hold.
* @param {object} [options] - Object for passing optional arguments.
* @param {number} [options.usage] - The usage type of the vertex buffer (see BUFFER_*).
* Defaults to BUFFER_STATIC.
* @param {ArrayBuffer} [options.data] - Initial data.
* @param {boolean} [options.storage] - Defines if the vertex buffer can be used as a storage
* buffer by a compute shader. Defaults to false. Only supported on WebGPU.
*/
constructor(graphicsDevice, format, numVertices, options) {
__publicField(this, "usage", BUFFER_STATIC);
Debug.assert(arguments.length <= 4 && (!options || typeof options === "object"), "incorrect arguments");
this.usage = options?.usage ?? BUFFER_STATIC;
this.device = graphicsDevice;
this.format = format;
this.numVertices = numVertices;
this.id = id++;
this.impl = graphicsDevice.createVertexBufferImpl(this, format, options);
this.numBytes = format.verticesByteSize ? format.verticesByteSize : format.size * numVertices;
this.adjustVramSizeTracking(graphicsDevice._vram, this.numBytes);
const initialData = options?.data;
if (initialData) {
this.setData(initialData);
} else {
this.storage = new ArrayBuffer(this.numBytes);
}
this.device.buffers.add(this);
}
/**
* Frees resources associated with this vertex buffer.
*/
destroy() {
const device = this.device;
device.buffers.delete(this);
if (this.impl.initialized) {
this.impl.destroy(device);
this.adjustVramSizeTracking(device._vram, -this.storage.byteLength);
}
}
adjustVramSizeTracking(vram, size) {
Debug.trace(TRACEID_VRAM_VB, `${this.id} size: ${size} vram.vb: ${vram.vb} => ${vram.vb + size}`);
vram.vb += size;
}
/**
* Called when the rendering context was lost. It releases all context related resources.
*
* @ignore
*/
loseContext() {
this.impl.loseContext();
}
/**
* Called when the rendering context is restored. Recreates the GPU buffer and uploads from
* {@link VertexBuffer#lock|lock} storage.
*
* @ignore
*/
restoreContext() {
this.unlock();
}
/**
* Returns the data format of the specified vertex buffer.
*
* @returns {VertexFormat} The data format of the specified vertex buffer.
*/
getFormat() {
return this.format;
}
/**
* Returns the usage type of the specified vertex buffer. This indicates whether the buffer can
* be modified once and used many times {@link BUFFER_STATIC}, modified repeatedly and used
* many times {@link BUFFER_DYNAMIC} or modified once and used at most a few times
* {@link BUFFER_STREAM}.
*
* @returns {number} The usage type of the vertex buffer (see BUFFER_*).
*/
getUsage() {
return this.usage;
}
/**
* Returns the number of vertices stored in the specified vertex buffer.
*
* @returns {number} The number of vertices stored in the vertex buffer.
*/
getNumVertices() {
return this.numVertices;
}
/**
* Returns a mapped memory block representing the content of the vertex buffer.
*
* @returns {ArrayBuffer} An array containing the byte data stored in the vertex buffer.
*/
lock() {
return this.storage;
}
/**
* Notifies the graphics engine that the client side copy of the vertex buffer's memory can be
* returned to the control of the graphics driver.
*/
unlock() {
this.impl.unlock(this);
}
/**
* Copies data into vertex buffer's memory.
*
* @param {ArrayBuffer} [data] - Source data to copy.
* @returns {boolean} True if function finished successfully, false otherwise.
*/
setData(data) {
if (data.byteLength !== this.numBytes) {
Debug.error(`VertexBuffer: wrong initial data size: expected ${this.numBytes}, got ${data.byteLength}`);
return false;
}
this.storage = data;
this.unlock();
return true;
}
}
export {
VertexBuffer
};