{"version":3,"file":"BatchRenderer.mjs","sources":["../../src/batch/BatchRenderer.ts"],"sourcesContent":["import { Color } from '@pixi/color';\nimport { ENV } from '@pixi/constants';\nimport { extensions, ExtensionType } from '@pixi/extensions';\nimport { settings } from '@pixi/settings';\nimport { deprecation, log2, nextPow2, premultiplyBlendMode } from '@pixi/utils';\nimport { ViewableBuffer } from '../geometry/ViewableBuffer';\nimport { checkMaxIfStatementsInShader } from '../shader/utils/checkMaxIfStatementsInShader';\nimport { State } from '../state/State';\nimport { BaseTexture } from '../textures/BaseTexture';\nimport { BatchDrawCall } from './BatchDrawCall';\nimport { BatchGeometry } from './BatchGeometry';\nimport { BatchShaderGenerator } from './BatchShaderGenerator';\nimport { BatchTextureArray } from './BatchTextureArray';\nimport { canUploadSameBuffer } from './canUploadSameBuffer';\nimport { maxRecommendedTextures } from './maxRecommendedTextures';\nimport { ObjectRenderer } from './ObjectRenderer';\nimport defaultFragment from './texture.frag';\nimport defaultVertex from './texture.vert';\n\nimport type { BLEND_MODES } from '@pixi/constants';\nimport type { ExtensionMetadata } from '@pixi/extensions';\nimport type { Renderer } from '../Renderer';\nimport type { Shader } from '../shader/Shader';\nimport type { Texture } from '../textures/Texture';\n\n/**\n * Interface for elements like Sprite, Mesh etc. for batching.\n * @memberof PIXI\n */\nexport interface IBatchableElement\n{\n    _texture: Texture;\n    vertexData: Float32Array;\n    indices: Uint16Array | Uint32Array | Array<number>;\n    uvs: Float32Array;\n    worldAlpha: number;\n    _tintRGB: number;\n    blendMode: BLEND_MODES;\n}\n\n/**\n * Renderer dedicated to drawing and batching sprites.\n *\n * This is the default batch renderer. It buffers objects\n * with texture-based geometries and renders them in\n * batches. It uploads multiple textures to the GPU to\n * reduce to the number of draw calls.\n * @memberof PIXI\n */\nexport class BatchRenderer extends ObjectRenderer\n{\n    /**\n     * The maximum textures that this device supports.\n     * @static\n     * @default 32\n     */\n    public static get defaultMaxTextures(): number\n    {\n        this._defaultMaxTextures = this._defaultMaxTextures ?? maxRecommendedTextures(32);\n\n        return this._defaultMaxTextures;\n    }\n    public static set defaultMaxTextures(value: number)\n    {\n        this._defaultMaxTextures = value;\n    }\n\n    /** @ignore */\n    private static _defaultMaxTextures: number;\n\n    /**\n     * The default sprite batch size.\n     *\n     * The default aims to balance desktop and mobile devices.\n     * @static\n     */\n    public static defaultBatchSize = 4096;\n\n    /**\n     * Can we upload the same buffer in a single frame?\n     * @static\n     */\n    public static get canUploadSameBuffer(): boolean\n    {\n        this._canUploadSameBuffer = this._canUploadSameBuffer ?? canUploadSameBuffer();\n\n        return this._canUploadSameBuffer;\n    }\n    public static set canUploadSameBuffer(value: boolean)\n    {\n        this._canUploadSameBuffer = value;\n    }\n\n    /** @ignore */\n    private static _canUploadSameBuffer: boolean;\n\n    /** @ignore */\n    static extension: ExtensionMetadata = {\n        name: 'batch',\n        type: ExtensionType.RendererPlugin,\n    };\n\n    /** The WebGL state in which this renderer will work. */\n    public readonly state: State;\n\n    /**\n     * The number of bufferable objects before a flush\n     * occurs automatically.\n     * @default PIXI.BatchRenderer.defaultBatchSize * 4\n     */\n    public size: number;\n\n    /**\n     * Maximum number of textures that can be uploaded to\n     * the GPU under the current context. It is initialized\n     * properly in `this.contextChange`.\n     * @see PIXI.BatchRenderer#contextChange\n     * @readonly\n     */\n    public maxTextures: number;\n\n    /**\n     * This is used to generate a shader that can\n     * color each vertex based on a `aTextureId`\n     * attribute that points to an texture in `uSampler`.\n     *\n     * This enables the objects with different textures\n     * to be drawn in the same draw call.\n     *\n     * You can customize your shader by creating your\n     * custom shader generator.\n     */\n    protected shaderGenerator: BatchShaderGenerator;\n\n    /**\n     * The class that represents the geometry of objects\n     * that are going to be batched with this.\n     * @member {object}\n     * @default PIXI.BatchGeometry\n     */\n    protected geometryClass: typeof BatchGeometry;\n\n    /**\n     * Size of data being buffered per vertex in the\n     * attribute buffers (in floats). By default, the\n     * batch-renderer plugin uses 6:\n     *\n     * | aVertexPosition | 2 |\n     * |-----------------|---|\n     * | aTextureCoords  | 2 |\n     * | aColor          | 1 |\n     * | aTextureId      | 1 |\n     * @default 6\n     */\n    protected vertexSize: number;\n\n    /** Total count of all vertices used by the currently buffered objects. */\n    protected _vertexCount: number;\n\n    /** Total count of all indices used by the currently buffered objects. */\n    protected _indexCount: number;\n\n    /**\n     * Buffer of objects that are yet to be rendered.\n     * @member {PIXI.DisplayObject[]}\n     */\n    protected _bufferedElements: Array<IBatchableElement>;\n\n    /**\n     * Data for texture batch builder, helps to save a bit of CPU on a pass.\n     * @member {PIXI.BaseTexture[]}\n     */\n    protected _bufferedTextures: Array<BaseTexture>;\n\n    /** Number of elements that are buffered and are waiting to be flushed. */\n    protected _bufferSize: number;\n\n    /**\n     * This shader is generated by `this.shaderGenerator`.\n     *\n     * It is generated specifically to handle the required\n     * number of textures being batched together.\n     */\n    protected _shader: Shader;\n\n    /**\n     * A flush may occur multiple times in a single\n     * frame. On iOS devices or when\n     * `BatchRenderer.canUploadSameBuffer` is false, the\n     * batch renderer does not upload data to the same\n     * `WebGLBuffer` for performance reasons.\n     *\n     * This is the index into `packedGeometries` that points to\n     * geometry holding the most recent buffers.\n     */\n    protected _flushId: number;\n\n    /**\n     * Pool of `ViewableBuffer` objects that are sorted in\n     * order of increasing size. The flush method uses\n     * the buffer with the least size above the amount\n     * it requires. These are used for passing attributes.\n     *\n     * The first buffer has a size of 8; each subsequent\n     * buffer has double capacity of its previous.\n     * @member {PIXI.ViewableBuffer[]}\n     * @see PIXI.BatchRenderer#getAttributeBuffer\n     */\n    protected _aBuffers: Array<ViewableBuffer>;\n\n    /**\n     * Pool of `Uint16Array` objects that are sorted in\n     * order of increasing size. The flush method uses\n     * the buffer with the least size above the amount\n     * it requires. These are used for passing indices.\n     *\n     * The first buffer has a size of 12; each subsequent\n     * buffer has double capacity of its previous.\n     * @member {Uint16Array[]}\n     * @see PIXI.BatchRenderer#getIndexBuffer\n     */\n    protected _iBuffers: Array<Uint16Array>;\n    protected _dcIndex: number;\n    protected _aIndex: number;\n    protected _iIndex: number;\n    protected _attributeBuffer: ViewableBuffer;\n    protected _indexBuffer: Uint16Array;\n    protected _tempBoundTextures: BaseTexture[];\n\n    /**\n     * Pool of `this.geometryClass` geometry objects\n     * that store buffers. They are used to pass data\n     * to the shader on each draw call.\n     *\n     * These are never re-allocated again, unless a\n     * context change occurs; however, the pool may\n     * be expanded if required.\n     * @member {PIXI.Geometry[]}\n     * @see PIXI.BatchRenderer.contextChange\n     */\n    private _packedGeometries: Array<BatchGeometry>;\n\n    /**\n     * Size of `this._packedGeometries`. It can be expanded\n     * if more than `this._packedGeometryPoolSize` flushes\n     * occur in a single frame.\n     */\n    private _packedGeometryPoolSize: number;\n\n    /**\n     * This will hook onto the renderer's `contextChange`\n     * and `prerender` signals.\n     * @param {PIXI.Renderer} renderer - The renderer this works for.\n     */\n    constructor(renderer: Renderer)\n    {\n        super(renderer);\n\n        this.setShaderGenerator();\n        this.geometryClass = BatchGeometry;\n        this.vertexSize = 6;\n        this.state = State.for2d();\n        this.size = BatchRenderer.defaultBatchSize * 4;\n        this._vertexCount = 0;\n        this._indexCount = 0;\n        this._bufferedElements = [];\n        this._bufferedTextures = [];\n        this._bufferSize = 0;\n        this._shader = null;\n        this._packedGeometries = [];\n        this._packedGeometryPoolSize = 2;\n        this._flushId = 0;\n        this._aBuffers = {} as any;\n        this._iBuffers = {} as any;\n\n        this.maxTextures = 1;\n\n        this.renderer.on('prerender', this.onPrerender, this);\n        renderer.runners.contextChange.add(this);\n\n        this._dcIndex = 0;\n        this._aIndex = 0;\n        this._iIndex = 0;\n        this._attributeBuffer = null;\n        this._indexBuffer = null;\n        this._tempBoundTextures = [];\n    }\n\n    /**\n     * @see PIXI.BatchRenderer#maxTextures\n     * @deprecated since 7.1.0\n     * @readonly\n     */\n    get MAX_TEXTURES(): number\n    {\n        if (process.env.DEBUG)\n        {\n            deprecation('7.1.0', 'BatchRenderer#MAX_TEXTURES renamed to BatchRenderer#maxTextures');\n        }\n\n        return this.maxTextures;\n    }\n\n    /**\n     * The default vertex shader source\n     * @readonly\n     */\n    static get defaultVertexSrc(): string\n    {\n        return defaultVertex;\n    }\n\n    /**\n     * The default fragment shader source\n     * @readonly\n     */\n    static get defaultFragmentTemplate(): string\n    {\n        return defaultFragment;\n    }\n\n    /**\n     * Set the shader generator.\n     * @param {object} [options]\n     * @param {string} [options.vertex=PIXI.BatchRenderer.defaultVertexSrc] - Vertex shader source\n     * @param {string} [options.fragment=PIXI.BatchRenderer.defaultFragmentTemplate] - Fragment shader template\n     */\n    public setShaderGenerator({\n        vertex = BatchRenderer.defaultVertexSrc,\n        fragment = BatchRenderer.defaultFragmentTemplate\n    }: { vertex?: string, fragment?: string } = {}): void\n    {\n        this.shaderGenerator = new BatchShaderGenerator(vertex, fragment);\n    }\n\n    /**\n     * Handles the `contextChange` signal.\n     *\n     * It calculates `this.maxTextures` and allocating the packed-geometry object pool.\n     */\n    contextChange(): void\n    {\n        const gl = this.renderer.gl;\n\n        if (settings.PREFER_ENV === ENV.WEBGL_LEGACY)\n        {\n            this.maxTextures = 1;\n        }\n        else\n        {\n            // step 1: first check max textures the GPU can handle.\n            this.maxTextures = Math.min(\n                gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS),\n                BatchRenderer.defaultMaxTextures);\n\n            // step 2: check the maximum number of if statements the shader can have too..\n            this.maxTextures = checkMaxIfStatementsInShader(\n                this.maxTextures, gl);\n        }\n\n        this._shader = this.shaderGenerator.generateShader(this.maxTextures);\n\n        // we use the second shader as the first one depending on your browser\n        // may omit aTextureId as it is not used by the shader so is optimized out.\n        for (let i = 0; i < this._packedGeometryPoolSize; i++)\n        {\n            /* eslint-disable max-len */\n            this._packedGeometries[i] = new (this.geometryClass)();\n        }\n\n        this.initFlushBuffers();\n    }\n\n    /** Makes sure that static and dynamic flush pooled objects have correct dimensions. */\n    initFlushBuffers(): void\n    {\n        const {\n            _drawCallPool,\n            _textureArrayPool,\n        } = BatchRenderer;\n        // max draw calls\n        const MAX_SPRITES = this.size / 4;\n        // max texture arrays\n        const MAX_TA = Math.floor(MAX_SPRITES / this.maxTextures) + 1;\n\n        while (_drawCallPool.length < MAX_SPRITES)\n        {\n            _drawCallPool.push(new BatchDrawCall());\n        }\n        while (_textureArrayPool.length < MAX_TA)\n        {\n            _textureArrayPool.push(new BatchTextureArray());\n        }\n        for (let i = 0; i < this.maxTextures; i++)\n        {\n            this._tempBoundTextures[i] = null;\n        }\n    }\n\n    /** Handles the `prerender` signal. It ensures that flushes start from the first geometry object again. */\n    onPrerender(): void\n    {\n        this._flushId = 0;\n    }\n\n    /**\n     * Buffers the \"batchable\" object. It need not be rendered immediately.\n     * @param {PIXI.DisplayObject} element - the element to render when\n     *    using this renderer\n     */\n    render(element: IBatchableElement): void\n    {\n        if (!element._texture.valid)\n        {\n            return;\n        }\n\n        if (this._vertexCount + (element.vertexData.length / 2) > this.size)\n        {\n            this.flush();\n        }\n\n        this._vertexCount += element.vertexData.length / 2;\n        this._indexCount += element.indices.length;\n        this._bufferedTextures[this._bufferSize] = element._texture.baseTexture;\n        this._bufferedElements[this._bufferSize++] = element;\n    }\n\n    buildTexturesAndDrawCalls(): void\n    {\n        const {\n            _bufferedTextures: textures,\n            maxTextures,\n        } = this;\n        const textureArrays = BatchRenderer._textureArrayPool;\n        const batch = this.renderer.batch;\n        const boundTextures = this._tempBoundTextures;\n        const touch = this.renderer.textureGC.count;\n\n        let TICK = ++BaseTexture._globalBatch;\n        let countTexArrays = 0;\n        let texArray = textureArrays[0];\n        let start = 0;\n\n        batch.copyBoundTextures(boundTextures, maxTextures);\n\n        for (let i = 0; i < this._bufferSize; ++i)\n        {\n            const tex = textures[i];\n\n            textures[i] = null;\n            if (tex._batchEnabled === TICK)\n            {\n                continue;\n            }\n\n            if (texArray.count >= maxTextures)\n            {\n                batch.boundArray(texArray, boundTextures, TICK, maxTextures);\n                this.buildDrawCalls(texArray, start, i);\n                start = i;\n                texArray = textureArrays[++countTexArrays];\n                ++TICK;\n            }\n\n            tex._batchEnabled = TICK;\n            tex.touched = touch;\n            texArray.elements[texArray.count++] = tex;\n        }\n\n        if (texArray.count > 0)\n        {\n            batch.boundArray(texArray, boundTextures, TICK, maxTextures);\n            this.buildDrawCalls(texArray, start, this._bufferSize);\n            ++countTexArrays;\n            ++TICK;\n        }\n\n        // Clean-up\n\n        for (let i = 0; i < boundTextures.length; i++)\n        {\n            boundTextures[i] = null;\n        }\n        BaseTexture._globalBatch = TICK;\n    }\n\n    /**\n     * Populating drawcalls for rendering\n     * @param texArray\n     * @param start\n     * @param finish\n     */\n    buildDrawCalls(texArray: BatchTextureArray, start: number, finish: number): void\n    {\n        const {\n            _bufferedElements: elements,\n            _attributeBuffer,\n            _indexBuffer,\n            vertexSize,\n        } = this;\n        const drawCalls = BatchRenderer._drawCallPool;\n\n        let dcIndex = this._dcIndex;\n        let aIndex = this._aIndex;\n        let iIndex = this._iIndex;\n\n        let drawCall = drawCalls[dcIndex];\n\n        drawCall.start = this._iIndex;\n        drawCall.texArray = texArray;\n\n        for (let i = start; i < finish; ++i)\n        {\n            const sprite = elements[i];\n            const tex = sprite._texture.baseTexture;\n            const spriteBlendMode = premultiplyBlendMode[\n                tex.alphaMode ? 1 : 0][sprite.blendMode];\n\n            elements[i] = null;\n\n            if (start < i && drawCall.blend !== spriteBlendMode)\n            {\n                drawCall.size = iIndex - drawCall.start;\n                start = i;\n                drawCall = drawCalls[++dcIndex];\n                drawCall.texArray = texArray;\n                drawCall.start = iIndex;\n            }\n\n            this.packInterleavedGeometry(sprite, _attributeBuffer, _indexBuffer, aIndex, iIndex);\n            aIndex += sprite.vertexData.length / 2 * vertexSize;\n            iIndex += sprite.indices.length;\n\n            drawCall.blend = spriteBlendMode;\n        }\n\n        if (start < finish)\n        {\n            drawCall.size = iIndex - drawCall.start;\n            ++dcIndex;\n        }\n\n        this._dcIndex = dcIndex;\n        this._aIndex = aIndex;\n        this._iIndex = iIndex;\n    }\n\n    /**\n     * Bind textures for current rendering\n     * @param texArray\n     */\n    bindAndClearTexArray(texArray: BatchTextureArray): void\n    {\n        const textureSystem = this.renderer.texture;\n\n        for (let j = 0; j < texArray.count; j++)\n        {\n            textureSystem.bind(texArray.elements[j], texArray.ids[j]);\n            texArray.elements[j] = null;\n        }\n        texArray.count = 0;\n    }\n\n    updateGeometry(): void\n    {\n        const {\n            _packedGeometries: packedGeometries,\n            _attributeBuffer: attributeBuffer,\n            _indexBuffer: indexBuffer,\n        } = this;\n\n        if (!BatchRenderer.canUploadSameBuffer)\n        { /* Usually on iOS devices, where the browser doesn't\n            like uploads to the same buffer in a single frame. */\n            if (this._packedGeometryPoolSize <= this._flushId)\n            {\n                this._packedGeometryPoolSize++;\n                packedGeometries[this._flushId] = new (this.geometryClass)();\n            }\n\n            packedGeometries[this._flushId]._buffer.update(attributeBuffer.rawBinaryData);\n            packedGeometries[this._flushId]._indexBuffer.update(indexBuffer);\n\n            this.renderer.geometry.bind(packedGeometries[this._flushId]);\n            this.renderer.geometry.updateBuffers();\n            this._flushId++;\n        }\n        else\n        {\n            // lets use the faster option, always use buffer number 0\n            packedGeometries[this._flushId]._buffer.update(attributeBuffer.rawBinaryData);\n            packedGeometries[this._flushId]._indexBuffer.update(indexBuffer);\n\n            this.renderer.geometry.updateBuffers();\n        }\n    }\n\n    drawBatches(): void\n    {\n        const dcCount = this._dcIndex;\n        const { gl, state: stateSystem } = this.renderer;\n        const drawCalls = BatchRenderer._drawCallPool;\n\n        let curTexArray = null;\n\n        // Upload textures and do the draw calls\n        for (let i = 0; i < dcCount; i++)\n        {\n            const { texArray, type, size, start, blend } = drawCalls[i];\n\n            if (curTexArray !== texArray)\n            {\n                curTexArray = texArray;\n                this.bindAndClearTexArray(texArray);\n            }\n\n            this.state.blendMode = blend;\n            stateSystem.set(this.state);\n            gl.drawElements(type, size, gl.UNSIGNED_SHORT, start * 2);\n        }\n    }\n\n    /** Renders the content _now_ and empties the current batch. */\n    flush(): void\n    {\n        if (this._vertexCount === 0)\n        {\n            return;\n        }\n\n        this._attributeBuffer = this.getAttributeBuffer(this._vertexCount);\n        this._indexBuffer = this.getIndexBuffer(this._indexCount);\n        this._aIndex = 0;\n        this._iIndex = 0;\n        this._dcIndex = 0;\n\n        this.buildTexturesAndDrawCalls();\n        this.updateGeometry();\n        this.drawBatches();\n\n        // reset elements buffer for the next flush\n        this._bufferSize = 0;\n        this._vertexCount = 0;\n        this._indexCount = 0;\n    }\n\n    /** Starts a new sprite batch. */\n    start(): void\n    {\n        this.renderer.state.set(this.state);\n\n        this.renderer.texture.ensureSamplerType(this.maxTextures);\n\n        this.renderer.shader.bind(this._shader);\n\n        if (BatchRenderer.canUploadSameBuffer)\n        {\n            // bind buffer #0, we don't need others\n            this.renderer.geometry.bind(this._packedGeometries[this._flushId]);\n        }\n    }\n\n    /** Stops and flushes the current batch. */\n    stop(): void\n    {\n        this.flush();\n    }\n\n    /** Destroys this `BatchRenderer`. It cannot be used again. */\n    destroy(): void\n    {\n        for (let i = 0; i < this._packedGeometryPoolSize; i++)\n        {\n            if (this._packedGeometries[i])\n            {\n                this._packedGeometries[i].destroy();\n            }\n        }\n\n        this.renderer.off('prerender', this.onPrerender, this);\n\n        this._aBuffers = null;\n        this._iBuffers = null;\n        this._packedGeometries = null;\n        this._attributeBuffer = null;\n        this._indexBuffer = null;\n\n        if (this._shader)\n        {\n            this._shader.destroy();\n            this._shader = null;\n        }\n\n        super.destroy();\n    }\n\n    /**\n     * Fetches an attribute buffer from `this._aBuffers` that can hold atleast `size` floats.\n     * @param size - minimum capacity required\n     * @returns - buffer than can hold atleast `size` floats\n     */\n    getAttributeBuffer(size: number): ViewableBuffer\n    {\n        // 8 vertices is enough for 2 quads\n        const roundedP2 = nextPow2(Math.ceil(size / 8));\n        const roundedSizeIndex = log2(roundedP2);\n        const roundedSize = roundedP2 * 8;\n\n        if (this._aBuffers.length <= roundedSizeIndex)\n        {\n            this._iBuffers.length = roundedSizeIndex + 1;\n        }\n\n        let buffer = this._aBuffers[roundedSize];\n\n        if (!buffer)\n        {\n            this._aBuffers[roundedSize] = buffer = new ViewableBuffer(roundedSize * this.vertexSize * 4);\n        }\n\n        return buffer;\n    }\n\n    /**\n     * Fetches an index buffer from `this._iBuffers` that can\n     * have at least `size` capacity.\n     * @param size - minimum required capacity\n     * @returns - buffer that can fit `size` indices.\n     */\n    getIndexBuffer(size: number): Uint16Array\n    {\n        // 12 indices is enough for 2 quads\n        const roundedP2 = nextPow2(Math.ceil(size / 12));\n        const roundedSizeIndex = log2(roundedP2);\n        const roundedSize = roundedP2 * 12;\n\n        if (this._iBuffers.length <= roundedSizeIndex)\n        {\n            this._iBuffers.length = roundedSizeIndex + 1;\n        }\n\n        let buffer = this._iBuffers[roundedSizeIndex];\n\n        if (!buffer)\n        {\n            this._iBuffers[roundedSizeIndex] = buffer = new Uint16Array(roundedSize);\n        }\n\n        return buffer;\n    }\n\n    /**\n     * Takes the four batching parameters of `element`, interleaves\n     * and pushes them into the batching attribute/index buffers given.\n     *\n     * It uses these properties: `vertexData` `uvs`, `textureId` and\n     * `indicies`. It also uses the \"tint\" of the base-texture, if\n     * present.\n     * @param {PIXI.DisplayObject} element - element being rendered\n     * @param attributeBuffer - attribute buffer.\n     * @param indexBuffer - index buffer\n     * @param aIndex - number of floats already in the attribute buffer\n     * @param iIndex - number of indices already in `indexBuffer`\n     */\n    packInterleavedGeometry(element: IBatchableElement, attributeBuffer: ViewableBuffer, indexBuffer: Uint16Array,\n        aIndex: number, iIndex: number): void\n    {\n        const {\n            uint32View,\n            float32View,\n        } = attributeBuffer;\n\n        const packedVertices = aIndex / this.vertexSize;\n        const uvs = element.uvs;\n        const indicies = element.indices;\n        const vertexData = element.vertexData;\n        const textureId = element._texture.baseTexture._batchLocation;\n\n        const alpha = Math.min(element.worldAlpha, 1.0);\n        const argb = Color.shared\n            .setValue(element._tintRGB)\n            .toPremultiplied(alpha, element._texture.baseTexture.alphaMode > 0);\n\n        // lets not worry about tint! for now..\n        for (let i = 0; i < vertexData.length; i += 2)\n        {\n            float32View[aIndex++] = vertexData[i];\n            float32View[aIndex++] = vertexData[i + 1];\n            float32View[aIndex++] = uvs[i];\n            float32View[aIndex++] = uvs[i + 1];\n            uint32View[aIndex++] = argb;\n            float32View[aIndex++] = textureId;\n        }\n\n        for (let i = 0; i < indicies.length; i++)\n        {\n            indexBuffer[iIndex++] = packedVertices + indicies[i];\n        }\n    }\n\n    /**\n     * Pool of `BatchDrawCall` objects that `flush` used\n     * to create \"batches\" of the objects being rendered.\n     *\n     * These are never re-allocated again.\n     * Shared between all batch renderers because it can be only one \"flush\" working at the moment.\n     * @member {PIXI.BatchDrawCall[]}\n     */\n    static _drawCallPool: Array<BatchDrawCall> = [];\n\n    /**\n     * Pool of `BatchDrawCall` objects that `flush` used\n     * to create \"batches\" of the objects being rendered.\n     *\n     * These are never re-allocated again.\n     * Shared between all batch renderers because it can be only one \"flush\" working at the moment.\n     * @member {PIXI.BatchTextureArray[]}\n     */\n    static _textureArrayPool: Array<BatchTextureArray> = [];\n}\n\n// Install BatchRenderer as default\nextensions.add(BatchRenderer);\n"],"names":["_BatchRenderer"],"mappings":"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"}