Associate data and data views with buffers.

This commit is contained in:
Ben Richards 2024-05-31 21:08:32 +12:00
parent d9c483e684
commit ff71ee8419
5 changed files with 91 additions and 50 deletions

View file

@ -202,6 +202,15 @@ var BatchHandler = new Class({
this.vertexBufferLayout
]);
/**
* The number of bytes per instance, used to determine how much of the vertex buffer to upload.
*
* @name Phaser.Renderer.WebGL.RenderNodes.BatchHandler#bytesPerInstance
* @type {number}
* @since 3.90.0
*/
this.bytesPerInstance = this.vertexBufferLayout.layout.stride * this.verticesPerInstance;
/**
* The number of floats per instance, used to determine how much of the vertex buffer to update.
*
@ -209,7 +218,7 @@ var BatchHandler = new Class({
* @type {number}
* @since 3.90.0
*/
this.floatsPerInstance = this.vertexBufferLayout.layout.stride * this.verticesPerInstance / Float32Array.BYTES_PER_ELEMENT;
this.floatsPerInstance = this.bytesPerInstance / Float32Array.BYTES_PER_ELEMENT;
/**
* The current batch entry being filled with textures.
@ -331,12 +340,12 @@ var BatchHandler = new Class({
* @since 3.90.0
* @private
* @param {number} instances - The number of instances to define.
* @return {Uint16Array} The index buffer data.
* @return {ArrayBuffer} The index buffer data.
*/
_generateElementIndices: function (instances)
{
// This is meaningless and should be overridden by subclasses.
return new Uint16Array(instances);
// This is empty and should be overridden by subclasses.
return new ArrayBuffer(instances * this.bytesPerInstance);
},
/**

View file

@ -316,8 +316,9 @@ var LightBatchHandler = new Class({
// Update the vertex buffer.
var vertexOffset32 = this.instanceCount * this.floatsPerInstance;
var vertexViewF32 = this.vertexBufferLayout.viewFloat32;
var vertexViewU32 = this.vertexBufferLayout.viewUint32;
var vertexBuffer = this.vertexBufferLayout.buffer;
var vertexViewF32 = vertexBuffer.viewF32;
var vertexViewU32 = vertexBuffer.viewU32;
// Top-left
vertexViewF32[vertexOffset32++] = x0;

View file

@ -89,11 +89,12 @@ var QuadBatchHandler = new Class({
* @since 3.90.0
* @private
* @param {number} instances - The number of instances to define.
* @return {Uint16Array} The index buffer data.
* @return {ArrayBuffer} The index buffer data.
*/
_generateElementIndices: function (instances)
{
var indices = new Uint16Array(instances * 6);
var buffer = new ArrayBuffer(instances * 6 * 2);
var indices = new Uint16Array(buffer);
var offset = 0;
for (var i = 0; i < instances; i++)
{
@ -105,7 +106,7 @@ var QuadBatchHandler = new Class({
indices[offset++] = index + 3;
indices[offset++] = index + 3;
}
return indices;
return buffer;
},
/**
@ -226,13 +227,11 @@ var QuadBatchHandler = new Class({
// Update vertex buffers.
if (this.instanceCount < this.instancesPerBatch)
{
// We use a subarray to avoid copying the buffer, but still
// control the length.
vertexBuffer.update(this.vertexBufferLayout.viewFloat32.subarray(0, this.instanceCount * this.floatsPerInstance));
vertexBuffer.update(this.instanceCount * this.bytesPerInstance);
}
else
{
vertexBuffer.update(this.vertexBufferLayout.data);
vertexBuffer.update();
}
var subBatches = this.batchEntries.length;
@ -325,8 +324,9 @@ var QuadBatchHandler = new Class({
// Update the vertex buffer.
var vertexOffset32 = this.instanceCount * this.floatsPerInstance;
var vertexViewF32 = this.vertexBufferLayout.viewFloat32;
var vertexViewU32 = this.vertexBufferLayout.viewUint32;
var vertexBuffer = this.vertexBufferLayout.buffer;
var vertexViewF32 = vertexBuffer.viewF32;
var vertexViewU32 = vertexBuffer.viewU32;
// Top-left
vertexViewF32[vertexOffset32++] = x0;

View file

@ -21,7 +21,7 @@ var Class = require('../../../utils/Class');
* @since 3.80.0
*
* @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - The WebGLRenderer instance that owns this wrapper.
* @param {ArrayBuffer|number} initialDataOrSize - Either an ArrayBuffer of data, or the size of the buffer to create.
* @param {ArrayBuffer} dataBuffer - An ArrayBuffer of data to store. The buffer will be permanently associated with this data.
* @param {GLenum} bufferType - The type of the buffer being created.
* @param {GLenum} bufferUsage - The usage of the buffer being created. gl.DYNAMIC_DRAW, gl.STATIC_DRAW or gl.STREAM_DRAW.
*/
@ -29,7 +29,7 @@ var WebGLBufferWrapper = new Class({
initialize:
function WebGLBufferWrapper (renderer, initialDataOrSize, bufferType, bufferUsage)
function WebGLBufferWrapper (renderer, dataBuffer, bufferType, bufferUsage)
{
/**
* The WebGLRenderer instance that owns this wrapper.
@ -55,15 +55,51 @@ var WebGLBufferWrapper = new Class({
this.webGLBuffer = null;
/**
* The initial data or size of the buffer.
* The data associated with the buffer.
*
* Note that this will be used to recreate the buffer if the WebGL context is lost.
*
* @name Phaser.Renderer.WebGL.Wrappers.WebGLBufferWrapper#initialDataOrSize
* @type {ArrayBuffer|number}
* @since 3.80.0
* @name Phaser.Renderer.WebGL.Wrappers.WebGLBufferWrapper#dataBuffer
* @type {ArrayBuffer}
* @since 3.90.0
*/
this.initialDataOrSize = initialDataOrSize;
this.dataBuffer = dataBuffer;
/**
* A Float32Array view of the dataBuffer.
*
* @name Phaser.Renderer.WebGL.Wrappers.WebGLBufferWrapper#viewF32
* @type {Float32Array}
* @since 3.90.0
*/
this.viewF32 = new Float32Array(dataBuffer);
/**
* A Uint8Array view of the dataBuffer.
*
* @name Phaser.Renderer.WebGL.Wrappers.WebGLBufferWrapper#viewU8
* @type {Uint8Array}
* @since 3.90.0
*/
this.viewU8 = new Uint8Array(dataBuffer);
/**
* A Uint16Array view of the dataBuffer.
*
* @name Phaser.Renderer.WebGL.Wrappers.WebGLBufferWrapper#viewU16
* @type {Uint16Array}
* @since 3.90.0
*/
this.viewU16 = new Uint16Array(dataBuffer);
/**
* A Uint32Array view of the dataBuffer.
*
* @name Phaser.Renderer.WebGL.Wrappers.WebGLBufferWrapper#viewU32
* @type {Uint32Array}
* @since 3.90.0
*/
this.viewU32 = new Uint32Array(dataBuffer);
/**
* The type of the buffer.
@ -97,11 +133,6 @@ var WebGLBufferWrapper = new Class({
*/
createResource: function ()
{
if (this.initialDataOrSize === null)
{
return;
}
var gl = this.renderer.gl;
var bufferType = this.bufferType;
@ -110,7 +141,7 @@ var WebGLBufferWrapper = new Class({
this.webGLBuffer = webGLBuffer;
this.bind();
gl.bufferData(bufferType, this.initialDataOrSize, this.bufferUsage);
gl.bufferData(bufferType, this.dataBuffer, this.bufferUsage);
this.bind(true);
},
@ -144,13 +175,15 @@ var WebGLBufferWrapper = new Class({
/**
* Updates the data in this WebGLBufferWrapper.
* The dataBuffer must contain the new data to be uploaded to the GPU.
* Data will preserve its range from dataBuffer to the WebGLBuffer.
*
* @method Phaser.Renderer.WebGL.Wrappers.WebGLBufferWrapper#update
* @since 3.90.0
* @param {ArrayBuffer} data - The new data to update the buffer with.
* @param {number} [bytes] - The number of bytes to update in the buffer. If not specified, the entire buffer will be updated.
* @param {number} [offset=0] - The offset into the buffer to start updating data at.
*/
update: function (data, offset)
update: function (bytes, offset)
{
var gl = this.renderer.gl;
@ -161,7 +194,23 @@ var WebGLBufferWrapper = new Class({
offset = 0;
}
gl.bufferSubData(this.bufferType, offset, data);
if (bytes === undefined)
{
gl.bufferSubData(
this.bufferType,
offset,
this.dataBuffer
);
}
else
{
gl.bufferSubData(
this.bufferType,
offset,
this.viewU8.subarray(offset, offset + bytes)
);
}
},
/**
@ -174,7 +223,7 @@ var WebGLBufferWrapper = new Class({
{
this.renderer.gl.deleteBuffer(this.webGLBuffer);
this.webGLBuffer = null;
this.initialDataOrSize = null;
this.dataBuffer = null;
this.renderer = null;
}
});

View file

@ -63,24 +63,6 @@ var WebGLVertexBufferLayoutWrapper = new Class({
*/
this.data = new ArrayBuffer(layout.stride * layout.count);
/**
* A Float32Array view of the ArrayBuffer.
*
* @name Phaser.Renderer.WebGL.Wrappers.WebGLVertexBufferLayoutWrapper#viewFloat32
* @type {Float32Array}
* @since 3.90.0
*/
this.viewFloat32 = new Float32Array(this.data);
/**
* A Uint32Array view of the ArrayBuffer.
*
* @name Phaser.Renderer.WebGL.Wrappers.WebGLVertexBufferLayoutWrapper#viewUint32
* @type {Uint32Array}
* @since 3.90.0
*/
this.viewUint32 = new Uint32Array(this.data);
/**
* The WebGLBuffer that this layout is based on.
*