UNPKG

@pixi/core

Version:
113 lines (112 loc) 4.36 kB
import { ExtensionType, extensions } from "@pixi/extensions"; import { GLBuffer } from "./GLBuffer.mjs"; class BufferSystem { /** * @param {PIXI.Renderer} renderer - The renderer this System works for. */ constructor(renderer) { this.renderer = renderer, this.managedBuffers = {}, this.boundBufferBases = {}; } /** * @ignore */ destroy() { this.renderer = null; } /** Sets up the renderer context and necessary buffers. */ contextChange() { this.disposeAll(!0), this.gl = this.renderer.gl, this.CONTEXT_UID = this.renderer.CONTEXT_UID; } /** * This binds specified buffer. On first run, it will create the webGL buffers for the context too * @param buffer - the buffer to bind to the renderer */ bind(buffer) { const { gl, CONTEXT_UID } = this, glBuffer = buffer._glBuffers[CONTEXT_UID] || this.createGLBuffer(buffer); gl.bindBuffer(buffer.type, glBuffer.buffer); } unbind(type) { const { gl } = this; gl.bindBuffer(type, null); } /** * Binds an uniform buffer to at the given index. * * A cache is used so a buffer will not be bound again if already bound. * @param buffer - the buffer to bind * @param index - the base index to bind it to. */ bindBufferBase(buffer, index) { const { gl, CONTEXT_UID } = this; if (this.boundBufferBases[index] !== buffer) { const glBuffer = buffer._glBuffers[CONTEXT_UID] || this.createGLBuffer(buffer); this.boundBufferBases[index] = buffer, gl.bindBufferBase(gl.UNIFORM_BUFFER, index, glBuffer.buffer); } } /** * Binds a buffer whilst also binding its range. * This will make the buffer start from the offset supplied rather than 0 when it is read. * @param buffer - the buffer to bind * @param index - the base index to bind at, defaults to 0 * @param offset - the offset to bind at (this is blocks of 256). 0 = 0, 1 = 256, 2 = 512 etc */ bindBufferRange(buffer, index, offset) { const { gl, CONTEXT_UID } = this; offset = offset || 0; const glBuffer = buffer._glBuffers[CONTEXT_UID] || this.createGLBuffer(buffer); gl.bindBufferRange(gl.UNIFORM_BUFFER, index || 0, glBuffer.buffer, offset * 256, 256); } /** * Will ensure the data in the buffer is uploaded to the GPU. * @param {PIXI.Buffer} buffer - the buffer to update */ update(buffer) { const { gl, CONTEXT_UID } = this, glBuffer = buffer._glBuffers[CONTEXT_UID] || this.createGLBuffer(buffer); if (buffer._updateID !== glBuffer.updateID) if (glBuffer.updateID = buffer._updateID, gl.bindBuffer(buffer.type, glBuffer.buffer), glBuffer.byteLength >= buffer.data.byteLength) gl.bufferSubData(buffer.type, 0, buffer.data); else { const drawType = buffer.static ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW; glBuffer.byteLength = buffer.data.byteLength, gl.bufferData(buffer.type, buffer.data, drawType); } } /** * Disposes buffer * @param {PIXI.Buffer} buffer - buffer with data * @param {boolean} [contextLost=false] - If context was lost, we suppress deleteVertexArray */ dispose(buffer, contextLost) { if (!this.managedBuffers[buffer.id]) return; delete this.managedBuffers[buffer.id]; const glBuffer = buffer._glBuffers[this.CONTEXT_UID], gl = this.gl; buffer.disposeRunner.remove(this), glBuffer && (contextLost || gl.deleteBuffer(glBuffer.buffer), delete buffer._glBuffers[this.CONTEXT_UID]); } /** * dispose all WebGL resources of all managed buffers * @param {boolean} [contextLost=false] - If context was lost, we suppress `gl.delete` calls */ disposeAll(contextLost) { const all = Object.keys(this.managedBuffers); for (let i = 0; i < all.length; i++) this.dispose(this.managedBuffers[all[i]], contextLost); } /** * creates and attaches a GLBuffer object tied to the current context. * @param buffer * @protected */ createGLBuffer(buffer) { const { CONTEXT_UID, gl } = this; return buffer._glBuffers[CONTEXT_UID] = new GLBuffer(gl.createBuffer()), this.managedBuffers[buffer.id] = buffer, buffer.disposeRunner.add(this), buffer._glBuffers[CONTEXT_UID]; } } BufferSystem.extension = { type: ExtensionType.RendererSystem, name: "buffer" }; extensions.add(BufferSystem); export { BufferSystem }; //# sourceMappingURL=BufferSystem.mjs.map