import { Matrix } from '@pixi/math' ; import { BaseTexture , BatchTextureArray , Shader , Texture } from '@pixi/core' ; import { BLEND_MODES } from '@pixi/constants' ; export interface IGraphicsBatchSettings { maxStyles : number ; maxTextures : number ; pixelLine : number ; } export function matrixEquals ( th , matrix , eps = 1e-3 ) { return this === matrix || Math . abs ( th . a - matrix . a ) < eps && Math . abs ( th . b - matrix . b ) < eps && Math . abs ( th . c - matrix . c ) < eps && Math . abs ( th . d - matrix . d ) < eps && Math . abs ( th . tx - matrix . tx ) < eps && Math . abs ( th . ty - matrix . ty ) < eps ; } export class BatchStyleArray { public textureIds : number [ ] ; public matrices : Matrix [ ] ; public lines : number [ ] ; public count : number ; constructor ( ) { this . textureIds = [ ] ; this . matrices = [ ] ; this . lines = [ ] ; this . count = 0 ; } clear ( ) { for ( let i = 0 ; i < this . count ; i ++ ) { this . textureIds [ i ] = null ; this . matrices [ i ] = null ; } this . count = 0 ; } add ( textureId , matrix , lineWidth , lineAlignment , lineScaleMode , settings ) { const { textureIds , matrices , lines , count } = this ; textureId = ( textureId * 4 ) + lineScaleMode ; for ( let i = 0 ; i < count ; i ++ ) { if ( lines [ i * 2 ] === lineWidth && lines [ ( i * 2 ) + 1 ] === lineAlignment && textureIds [ i ] === textureId && ( matrixEquals ( matrices [ i ] , matrix ) ) ) { return i ; } } if ( count >= settings . maxStyles ) { return - 1 ; } textureIds [ count ] = textureId ; matrices [ count ] = matrix ; lines [ count * 2 ] = lineWidth ; lines [ ( count * 2 ) + 1 ] = lineAlignment ; this . count ++ ; return count ; } } export class BatchDrawCall { texArray : BatchTextureArray ; styleArray : BatchStyleArray ; blend : BLEND_MODES ; start : number ; size : number ; data : any ; shader : Shader ; TICK : number ; settings : IGraphicsBatchSettings ; constructor ( ) { this . texArray = new BatchTextureArray ( ) ; this . styleArray = new BatchStyleArray ( ) ; this . shader = null ; this . blend = BLEND_MODES . NORMAL ; this . start = 0 ; this . size = 0 ; this . TICK = 0 ; this . settings = null ; member this . data = null ; } clear ( ) { this . texArray . clear ( ) ; this . styleArray . clear ( ) ; this . settings = null ; this . data = null ; this . shader = null ; } begin ( settings , shader ) { this . TICK = ++ BaseTexture . _globalBatch ; this . settings = settings ; this . shader = shader ; this . start = 0 ; this . size = 0 ; this . data = null ; if ( shader && ( shader as any ) . settings ) { this . settings = ( shader as any ) . settings ; } } check ( shader ) { if ( this . size === 0 ) { this . shader = shader ; return true ; } return ( this . shader === shader ) ; } add ( texture , matrix , lineWidth , lineAlignment , lineScaleMode ) { const { texArray , TICK , styleArray , settings } = this ; const { baseTexture } = texture ; if ( baseTexture . _batchEnabled !== TICK && texArray . count === settings . maxTextures ) { return - 1 ; } const loc = baseTexture . _batchEnabled !== TICK ? texArray . count : baseTexture . _batchLocation ; const res = styleArray . add ( loc , matrix || Matrix . IDENTITY , lineWidth , lineAlignment , lineScaleMode , settings ) ; if ( res >= 0 ) { if ( baseTexture . _batchEnabled !== TICK ) { baseTexture . _batchEnabled = TICK ; baseTexture . _batchLocation = texArray . count ; texArray . elements [ texArray . count ++ ] = baseTexture ; } } return res ; } }