sdfsdfs
This commit is contained in:
341
node_modules/pixi.js/lib/rendering/batcher/shared/Batcher.js
generated
vendored
Normal file
341
node_modules/pixi.js/lib/rendering/batcher/shared/Batcher.js
generated
vendored
Normal file
@@ -0,0 +1,341 @@
|
||||
'use strict';
|
||||
|
||||
var uid = require('../../../utils/data/uid.js');
|
||||
var ViewableBuffer = require('../../../utils/data/ViewableBuffer.js');
|
||||
var fastCopy = require('../../renderers/shared/buffer/utils/fastCopy.js');
|
||||
var getAdjustedBlendModeBlend = require('../../renderers/shared/state/getAdjustedBlendModeBlend.js');
|
||||
var maxRecommendedTextures = require('../gl/utils/maxRecommendedTextures.js');
|
||||
var BatchTextureArray = require('./BatchTextureArray.js');
|
||||
|
||||
"use strict";
|
||||
class Batch {
|
||||
constructor() {
|
||||
this.renderPipeId = "batch";
|
||||
this.action = "startBatch";
|
||||
// TODO - eventually this could be useful for flagging batches as dirty and then only rebuilding those ones
|
||||
// public elementStart = 0;
|
||||
// public elementSize = 0;
|
||||
// for drawing..
|
||||
this.start = 0;
|
||||
this.size = 0;
|
||||
this.textures = new BatchTextureArray.BatchTextureArray();
|
||||
this.blendMode = "normal";
|
||||
this.canBundle = true;
|
||||
}
|
||||
destroy() {
|
||||
this.textures = null;
|
||||
this.gpuBindGroup = null;
|
||||
this.bindGroup = null;
|
||||
this.batcher = null;
|
||||
}
|
||||
}
|
||||
const batchPool = [];
|
||||
let batchPoolIndex = 0;
|
||||
function getBatchFromPool() {
|
||||
return batchPoolIndex > 0 ? batchPool[--batchPoolIndex] : new Batch();
|
||||
}
|
||||
function returnBatchToPool(batch) {
|
||||
batchPool[batchPoolIndex++] = batch;
|
||||
}
|
||||
let BATCH_TICK = 0;
|
||||
const _Batcher = class _Batcher {
|
||||
constructor(options = {}) {
|
||||
/** unique id for this batcher */
|
||||
this.uid = uid.uid("batcher");
|
||||
/** Indicates whether the batch data has been modified and needs updating. */
|
||||
this.dirty = true;
|
||||
/** The current index of the batch being processed. */
|
||||
this.batchIndex = 0;
|
||||
/** An array of all batches created during the current rendering process. */
|
||||
this.batches = [];
|
||||
this._elements = [];
|
||||
_Batcher.defaultOptions.maxTextures = _Batcher.defaultOptions.maxTextures ?? maxRecommendedTextures.getMaxTexturesPerBatch();
|
||||
options = { ..._Batcher.defaultOptions, ...options };
|
||||
const { maxTextures, attributesInitialSize, indicesInitialSize } = options;
|
||||
this.attributeBuffer = new ViewableBuffer.ViewableBuffer(attributesInitialSize * 4);
|
||||
this.indexBuffer = new Uint16Array(indicesInitialSize);
|
||||
this.maxTextures = maxTextures;
|
||||
}
|
||||
begin() {
|
||||
this.elementSize = 0;
|
||||
this.elementStart = 0;
|
||||
this.indexSize = 0;
|
||||
this.attributeSize = 0;
|
||||
for (let i = 0; i < this.batchIndex; i++) {
|
||||
returnBatchToPool(this.batches[i]);
|
||||
}
|
||||
this.batchIndex = 0;
|
||||
this._batchIndexStart = 0;
|
||||
this._batchIndexSize = 0;
|
||||
this.dirty = true;
|
||||
}
|
||||
add(batchableObject) {
|
||||
this._elements[this.elementSize++] = batchableObject;
|
||||
batchableObject._indexStart = this.indexSize;
|
||||
batchableObject._attributeStart = this.attributeSize;
|
||||
batchableObject._batcher = this;
|
||||
this.indexSize += batchableObject.indexSize;
|
||||
this.attributeSize += batchableObject.attributeSize * this.vertexSize;
|
||||
}
|
||||
checkAndUpdateTexture(batchableObject, texture) {
|
||||
const textureId = batchableObject._batch.textures.ids[texture._source.uid];
|
||||
if (!textureId && textureId !== 0)
|
||||
return false;
|
||||
batchableObject._textureId = textureId;
|
||||
batchableObject.texture = texture;
|
||||
return true;
|
||||
}
|
||||
updateElement(batchableObject) {
|
||||
this.dirty = true;
|
||||
const attributeBuffer = this.attributeBuffer;
|
||||
if (batchableObject.packAsQuad) {
|
||||
this.packQuadAttributes(
|
||||
batchableObject,
|
||||
attributeBuffer.float32View,
|
||||
attributeBuffer.uint32View,
|
||||
batchableObject._attributeStart,
|
||||
batchableObject._textureId
|
||||
);
|
||||
} else {
|
||||
this.packAttributes(
|
||||
batchableObject,
|
||||
attributeBuffer.float32View,
|
||||
attributeBuffer.uint32View,
|
||||
batchableObject._attributeStart,
|
||||
batchableObject._textureId
|
||||
);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* breaks the batcher. This happens when a batch gets too big,
|
||||
* or we need to switch to a different type of rendering (a filter for example)
|
||||
* @param instructionSet
|
||||
*/
|
||||
break(instructionSet) {
|
||||
const elements = this._elements;
|
||||
if (!elements[this.elementStart])
|
||||
return;
|
||||
let batch = getBatchFromPool();
|
||||
let textureBatch = batch.textures;
|
||||
textureBatch.clear();
|
||||
const firstElement = elements[this.elementStart];
|
||||
let blendMode = getAdjustedBlendModeBlend.getAdjustedBlendModeBlend(firstElement.blendMode, firstElement.texture._source);
|
||||
if (this.attributeSize * 4 > this.attributeBuffer.size) {
|
||||
this._resizeAttributeBuffer(this.attributeSize * 4);
|
||||
}
|
||||
if (this.indexSize > this.indexBuffer.length) {
|
||||
this._resizeIndexBuffer(this.indexSize);
|
||||
}
|
||||
const f32 = this.attributeBuffer.float32View;
|
||||
const u32 = this.attributeBuffer.uint32View;
|
||||
const indexBuffer = this.indexBuffer;
|
||||
let size = this._batchIndexSize;
|
||||
let start = this._batchIndexStart;
|
||||
let action = "startBatch";
|
||||
const maxTextures = this.maxTextures;
|
||||
for (let i = this.elementStart; i < this.elementSize; ++i) {
|
||||
const element = elements[i];
|
||||
elements[i] = null;
|
||||
const texture = element.texture;
|
||||
const source = texture._source;
|
||||
const adjustedBlendMode = getAdjustedBlendModeBlend.getAdjustedBlendModeBlend(element.blendMode, source);
|
||||
const breakRequired = blendMode !== adjustedBlendMode;
|
||||
if (source._batchTick === BATCH_TICK && !breakRequired) {
|
||||
element._textureId = source._textureBindLocation;
|
||||
size += element.indexSize;
|
||||
if (element.packAsQuad) {
|
||||
this.packQuadAttributes(
|
||||
element,
|
||||
f32,
|
||||
u32,
|
||||
element._attributeStart,
|
||||
element._textureId
|
||||
);
|
||||
this.packQuadIndex(
|
||||
indexBuffer,
|
||||
element._indexStart,
|
||||
element._attributeStart / this.vertexSize
|
||||
);
|
||||
} else {
|
||||
this.packAttributes(
|
||||
element,
|
||||
f32,
|
||||
u32,
|
||||
element._attributeStart,
|
||||
element._textureId
|
||||
);
|
||||
this.packIndex(
|
||||
element,
|
||||
indexBuffer,
|
||||
element._indexStart,
|
||||
element._attributeStart / this.vertexSize
|
||||
);
|
||||
}
|
||||
element._batch = batch;
|
||||
continue;
|
||||
}
|
||||
source._batchTick = BATCH_TICK;
|
||||
if (textureBatch.count >= maxTextures || breakRequired) {
|
||||
this._finishBatch(
|
||||
batch,
|
||||
start,
|
||||
size - start,
|
||||
textureBatch,
|
||||
blendMode,
|
||||
instructionSet,
|
||||
action
|
||||
);
|
||||
action = "renderBatch";
|
||||
start = size;
|
||||
blendMode = adjustedBlendMode;
|
||||
batch = getBatchFromPool();
|
||||
textureBatch = batch.textures;
|
||||
textureBatch.clear();
|
||||
++BATCH_TICK;
|
||||
}
|
||||
element._textureId = source._textureBindLocation = textureBatch.count;
|
||||
textureBatch.ids[source.uid] = textureBatch.count;
|
||||
textureBatch.textures[textureBatch.count++] = source;
|
||||
element._batch = batch;
|
||||
size += element.indexSize;
|
||||
if (element.packAsQuad) {
|
||||
this.packQuadAttributes(
|
||||
element,
|
||||
f32,
|
||||
u32,
|
||||
element._attributeStart,
|
||||
element._textureId
|
||||
);
|
||||
this.packQuadIndex(
|
||||
indexBuffer,
|
||||
element._indexStart,
|
||||
element._attributeStart / this.vertexSize
|
||||
);
|
||||
} else {
|
||||
this.packAttributes(
|
||||
element,
|
||||
f32,
|
||||
u32,
|
||||
element._attributeStart,
|
||||
element._textureId
|
||||
);
|
||||
this.packIndex(
|
||||
element,
|
||||
indexBuffer,
|
||||
element._indexStart,
|
||||
element._attributeStart / this.vertexSize
|
||||
);
|
||||
}
|
||||
}
|
||||
if (textureBatch.count > 0) {
|
||||
this._finishBatch(
|
||||
batch,
|
||||
start,
|
||||
size - start,
|
||||
textureBatch,
|
||||
blendMode,
|
||||
instructionSet,
|
||||
action
|
||||
);
|
||||
start = size;
|
||||
++BATCH_TICK;
|
||||
}
|
||||
this.elementStart = this.elementSize;
|
||||
this._batchIndexStart = start;
|
||||
this._batchIndexSize = size;
|
||||
}
|
||||
_finishBatch(batch, indexStart, indexSize, textureBatch, blendMode, instructionSet, action) {
|
||||
batch.gpuBindGroup = null;
|
||||
batch.bindGroup = null;
|
||||
batch.action = action;
|
||||
batch.batcher = this;
|
||||
batch.textures = textureBatch;
|
||||
batch.blendMode = blendMode;
|
||||
batch.start = indexStart;
|
||||
batch.size = indexSize;
|
||||
++BATCH_TICK;
|
||||
this.batches[this.batchIndex++] = batch;
|
||||
instructionSet.add(batch);
|
||||
}
|
||||
finish(instructionSet) {
|
||||
this.break(instructionSet);
|
||||
}
|
||||
/**
|
||||
* Resizes the attribute buffer to the given size (1 = 1 float32)
|
||||
* @param size - the size in vertices to ensure (not bytes!)
|
||||
*/
|
||||
ensureAttributeBuffer(size) {
|
||||
if (size * 4 <= this.attributeBuffer.size)
|
||||
return;
|
||||
this._resizeAttributeBuffer(size * 4);
|
||||
}
|
||||
/**
|
||||
* Resizes the index buffer to the given size (1 = 1 float32)
|
||||
* @param size - the size in vertices to ensure (not bytes!)
|
||||
*/
|
||||
ensureIndexBuffer(size) {
|
||||
if (size <= this.indexBuffer.length)
|
||||
return;
|
||||
this._resizeIndexBuffer(size);
|
||||
}
|
||||
_resizeAttributeBuffer(size) {
|
||||
const newSize = Math.max(size, this.attributeBuffer.size * 2);
|
||||
const newArrayBuffer = new ViewableBuffer.ViewableBuffer(newSize);
|
||||
fastCopy.fastCopy(this.attributeBuffer.rawBinaryData, newArrayBuffer.rawBinaryData);
|
||||
this.attributeBuffer = newArrayBuffer;
|
||||
}
|
||||
_resizeIndexBuffer(size) {
|
||||
const indexBuffer = this.indexBuffer;
|
||||
let newSize = Math.max(size, indexBuffer.length * 1.5);
|
||||
newSize += newSize % 2;
|
||||
const newIndexBuffer = newSize > 65535 ? new Uint32Array(newSize) : new Uint16Array(newSize);
|
||||
if (newIndexBuffer.BYTES_PER_ELEMENT !== indexBuffer.BYTES_PER_ELEMENT) {
|
||||
for (let i = 0; i < indexBuffer.length; i++) {
|
||||
newIndexBuffer[i] = indexBuffer[i];
|
||||
}
|
||||
} else {
|
||||
fastCopy.fastCopy(indexBuffer.buffer, newIndexBuffer.buffer);
|
||||
}
|
||||
this.indexBuffer = newIndexBuffer;
|
||||
}
|
||||
packQuadIndex(indexBuffer, index, indicesOffset) {
|
||||
indexBuffer[index] = indicesOffset + 0;
|
||||
indexBuffer[index + 1] = indicesOffset + 1;
|
||||
indexBuffer[index + 2] = indicesOffset + 2;
|
||||
indexBuffer[index + 3] = indicesOffset + 0;
|
||||
indexBuffer[index + 4] = indicesOffset + 2;
|
||||
indexBuffer[index + 5] = indicesOffset + 3;
|
||||
}
|
||||
packIndex(element, indexBuffer, index, indicesOffset) {
|
||||
const indices = element.indices;
|
||||
const size = element.indexSize;
|
||||
const indexOffset = element.indexOffset;
|
||||
const attributeOffset = element.attributeOffset;
|
||||
for (let i = 0; i < size; i++) {
|
||||
indexBuffer[index++] = indicesOffset + indices[i + indexOffset] - attributeOffset;
|
||||
}
|
||||
}
|
||||
destroy() {
|
||||
for (let i = 0; i < this.batches.length; i++) {
|
||||
returnBatchToPool(this.batches[i]);
|
||||
}
|
||||
this.batches = null;
|
||||
for (let i = 0; i < this._elements.length; i++) {
|
||||
this._elements[i]._batch = null;
|
||||
}
|
||||
this._elements = null;
|
||||
this.indexBuffer = null;
|
||||
this.attributeBuffer.destroy();
|
||||
this.attributeBuffer = null;
|
||||
}
|
||||
};
|
||||
_Batcher.defaultOptions = {
|
||||
maxTextures: null,
|
||||
attributesInitialSize: 4,
|
||||
indicesInitialSize: 6
|
||||
};
|
||||
let Batcher = _Batcher;
|
||||
|
||||
exports.Batch = Batch;
|
||||
exports.Batcher = Batcher;
|
||||
//# sourceMappingURL=Batcher.js.map
|
Reference in New Issue
Block a user