11import {
2- prelude ,
3- preludeFragPrecisionQualifiers ,
4- preludeVertPrecisionQualifiers ,
5- preludeCommonSource ,
62 includeMap ,
7- preludeFragExtensions ,
3+ FRAGMENT_PRELUDE_BLOCK ,
4+ VERTEX_PRELUDE_BLOCK
85} from '../shaders/shaders' ;
96import assert from 'assert' ;
107import VertexArrayObject from './vertex_array_object' ;
@@ -30,7 +27,7 @@ import type SegmentVector from '../data/segment';
3027import type VertexBuffer from '../gl/vertex_buffer' ;
3128import type IndexBuffer from '../gl/index_buffer' ;
3229import type CullFaceMode from '../gl/cull_face_mode' ;
33- import type { UniformBindings , UniformValues } from './uniform_binding' ;
30+ import type { UniformBindings , UniformValues , IUniform } from './uniform_binding' ;
3431import type { BinderUniform } from '../data/program_configuration' ;
3532import type Painter from './painter' ;
3633import type { Segment } from "../data/segment" ;
@@ -44,7 +41,7 @@ export type DrawMode = WebGL2RenderingContext['POINTS'] | WebGL2RenderingContext
4441export type ShaderSource = {
4542 fragmentSource : string ;
4643 vertexSource : string ;
47- usedDefines : Array < DynamicDefinesType > ;
44+ usedDefines : Set < DynamicDefinesType > ;
4845 vertexIncludes : Array < string > ;
4946 fragmentIncludes : Array < string > ;
5047} ;
@@ -76,7 +73,9 @@ const instancingUniforms = (context: Context): InstancingUniformType => ({
7673class Program < Us extends UniformBindings > {
7774 program : WebGLProgram ;
7875 attributes : Record < string , number > ;
79- fixedUniforms : Us ;
76+ fixedUniforms : Readonly < Us > ;
77+ // Cache fixedUniforms entries to avoid allocations during draw calls
78+ fixedUniformsEntries : ReadonlyArray < [ string , IUniform < unknown > ] > ;
8079 binderUniforms : Array < BinderUniform > ;
8180 failedToCreate : boolean ;
8281 terrainUniforms : TerrainUniformsType | null | undefined ;
@@ -88,7 +87,7 @@ class Program<Us extends UniformBindings> {
8887
8988 name : ProgramName ;
9089 configuration : ProgramConfiguration | null | undefined ;
91- fixedDefines : DynamicDefinesType [ ] ;
90+ fixedDefines : ReadonlyArray < DynamicDefinesType > ;
9291
9392 // Manually handle instancing by issuing draw calls and replacing gl_InstanceID with uniform
9493 forceManualRenderingForInstanceIDShaders : boolean ;
@@ -100,13 +99,19 @@ class Program<Us extends UniformBindings> {
10099 defines : DynamicDefinesType [ ] ,
101100 programConfiguration ?: ProgramConfiguration | null ,
102101 ) : string {
103- let key = `${ name } ${ programConfiguration ? programConfiguration . cacheKey : '' } ` ;
102+ const parts : string [ ] = [ name ] ;
103+
104+ if ( programConfiguration ) {
105+ parts . push ( programConfiguration . cacheKey ) ;
106+ }
107+
104108 for ( const define of defines ) {
105- if ( source . usedDefines . includes ( define ) ) {
106- key += `/ ${ define } ` ;
109+ if ( source . usedDefines . has ( define ) ) {
110+ parts . push ( define as string ) ;
107111 }
108112 }
109- return key ;
113+
114+ return parts . join ( '/' ) ;
110115 }
111116
112117 constructor (
@@ -124,44 +129,36 @@ class Program<Us extends UniformBindings> {
124129 this . name = name ;
125130 this . fixedDefines = [ ...fixedDefines ] ;
126131
127- let defines = configuration ? configuration . defines ( ) : [ ] ;
128- defines = defines . concat ( fixedDefines . map ( ( define ) => `#define ${ define } ` ) ) ;
129- const version = ' #version 300 es\n' ;
132+ const configDefines = configuration ? configuration . defines ( ) : [ ] ;
133+ const defines = configDefines . concat ( fixedDefines . map ( ( define ) => `#define ${ define } ` ) ) . join ( '\n' ) ;
134+ const definesBlock = ` #version 300 es\n${ defines } ` ;
130135
131- let fragmentSource = version + defines . concat (
132- preludeFragExtensions ,
133- preludeFragPrecisionQualifiers ,
134- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
135- preludeCommonSource ,
136- prelude . fragmentSource ) . join ( '\n' ) ;
136+ const fragmentParts = [ definesBlock , FRAGMENT_PRELUDE_BLOCK ] ;
137137 for ( const include of source . fragmentIncludes ) {
138- fragmentSource += `\n ${ includeMap [ include ] } ` ;
138+ fragmentParts . push ( includeMap [ include ] ) ;
139139 }
140- fragmentSource += `\n${ source . fragmentSource } ` ;
141140
142- let vertexSource = version + defines . concat (
143- preludeVertPrecisionQualifiers ,
144- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
145- preludeCommonSource ,
146- prelude . vertexSource ) . join ( '\n' ) ;
141+ fragmentParts . push ( source . fragmentSource ) ;
142+ const fragmentSource = fragmentParts . join ( '\n' ) ;
143+
144+ const vertexParts = [ definesBlock , VERTEX_PRELUDE_BLOCK ] ;
147145 for ( const include of source . vertexIncludes ) {
148- vertexSource += `\n ${ includeMap [ include ] } ` ;
146+ vertexParts . push ( includeMap [ include ] ) ;
149147 }
150148
151- this . forceManualRenderingForInstanceIDShaders = context . forceManualRenderingForInstanceIDShaders && source . vertexSource . indexOf ( " gl_InstanceID" ) !== - 1 ;
149+ this . forceManualRenderingForInstanceIDShaders = context . forceManualRenderingForInstanceIDShaders && source . vertexSource . includes ( ' gl_InstanceID' ) ;
152150
153151 if ( this . forceManualRenderingForInstanceIDShaders ) {
154- vertexSource += `\nuniform int u_instanceID;\n` ;
152+ vertexParts . push ( 'uniform int u_instanceID;' ) ;
155153 }
156154
157- vertexSource += `\n${ source . vertexSource } ` ;
155+ vertexParts . push ( source . vertexSource ) ;
156+ let vertexSource = vertexParts . join ( '\n' ) ;
158157
159158 if ( this . forceManualRenderingForInstanceIDShaders ) {
160- vertexSource = vertexSource . replaceAll ( " gl_InstanceID" , " u_instanceID" ) ;
159+ vertexSource = vertexSource . replaceAll ( ' gl_InstanceID' , ' u_instanceID' ) ;
161160 }
162161
163- // Replace
164-
165162 const fragmentShader = ( gl . createShader ( gl . FRAGMENT_SHADER ) ) ;
166163 if ( gl . isContextLost ( ) ) {
167164 this . failedToCreate = true ;
@@ -191,6 +188,7 @@ class Program<Us extends UniformBindings> {
191188 gl . deleteShader ( fragmentShader ) ;
192189
193190 this . fixedUniforms = fixedUniforms ( context ) ;
191+ this . fixedUniformsEntries = Object . entries ( this . fixedUniforms ) ;
194192 this . binderUniforms = configuration ? configuration . getUniforms ( context ) : [ ] ;
195193
196194 if ( this . forceManualRenderingForInstanceIDShaders ) {
@@ -199,7 +197,7 @@ class Program<Us extends UniformBindings> {
199197
200198 // Symbol and circle layer are depth (terrain + 3d layers) occluded
201199 // For the sake of native compatibility depth occlusion goes via terrain uniforms block
202- if ( fixedDefines . includes ( 'TERRAIN' ) || name . indexOf ( " symbol" ) !== - 1 || name . indexOf ( " circle" ) !== - 1 ) {
200+ if ( fixedDefines . includes ( 'TERRAIN' ) || name . includes ( ' symbol' ) || name . includes ( ' circle' ) ) {
203201 this . terrainUniforms = terrainUniforms ( context ) ;
204202 }
205203 if ( fixedDefines . includes ( 'GLOBE' ) ) {
@@ -363,17 +361,13 @@ class Program<Us extends UniformBindings> {
363361 return ;
364362 }
365363
366- const debugDefines : DynamicDefinesType [ ] = [ ...this . fixedDefines ] ;
367- debugDefines . push ( 'DEBUG_WIREFRAME' ) ;
364+ const debugDefines : DynamicDefinesType [ ] = [ ...this . fixedDefines , 'DEBUG_WIREFRAME' ] ;
368365 const debugProgram = painter . getOrCreateProgram ( this . name , { config : this . configuration , defines : debugDefines } ) ;
369366
370367 context . program . set ( debugProgram . program ) ;
371368
372- // eslint-disable-next-line @typescript-eslint/no-explicit-any
373- const copyUniformValues = ( group : string , pSrc : any , pDst : any ) => {
374- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
369+ const copyUniformValues = ( group : string , pSrc : Program < Us > , pDst : Program < UniformBindings > ) => {
375370 if ( pSrc [ group ] && pDst [ group ] ) {
376- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
377371 for ( const name in pSrc [ group ] ) {
378372 // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
379373 if ( pDst [ group ] [ name ] ) {
@@ -488,8 +482,8 @@ class Program<Us extends UniformBindings> {
488482 context . setColorMode ( colorMode ) ;
489483 context . setCullFace ( cullFaceMode ) ;
490484
491- for ( const name of Object . keys ( this . fixedUniforms ) ) {
492- this . fixedUniforms [ name ] . set ( this . program , name , uniformValues [ name ] ) ;
485+ for ( const [ name , uniform ] of this . fixedUniformsEntries ) {
486+ uniform . set ( this . program , name , uniformValues [ name ] ) ;
493487 }
494488
495489 if ( configuration ) {
@@ -505,6 +499,10 @@ class Program<Us extends UniformBindings> {
505499
506500 this . checkUniforms ( layerID , 'RENDER_SHADOWS' , this . shadowUniforms ) ;
507501
502+ const dynamicBuffers = dynamicLayoutBuffers || [ ] ;
503+ const paintVertexBuffers = configuration ? configuration . getPaintVertexBuffers ( ) : [ ] ;
504+ const shouldDrawWireframe = drawMode === gl . TRIANGLES && indexBuffer ;
505+
508506 const vertexAttribDivisorValue = instanceCount && instanceCount > 0 ? 1 : undefined ;
509507 for ( const segment of segments . get ( ) ) {
510508 const vaos = segment . vaos || ( segment . vaos = { } ) ;
@@ -513,10 +511,10 @@ class Program<Us extends UniformBindings> {
513511 context ,
514512 this ,
515513 layoutVertexBuffer ,
516- configuration ? configuration . getPaintVertexBuffers ( ) : [ ] ,
514+ paintVertexBuffers ,
517515 indexBuffer ,
518516 segment . vertexOffset ,
519- dynamicLayoutBuffers ? dynamicLayoutBuffers : [ ] ,
517+ dynamicBuffers ,
520518 vertexAttribDivisorValue
521519 ) ;
522520
@@ -555,8 +553,7 @@ class Program<Us extends UniformBindings> {
555553 gl . drawArrays ( drawMode , segment . vertexOffset , segment . vertexLength ) ;
556554 }
557555 }
558- if ( drawMode === gl . TRIANGLES && indexBuffer ) {
559- // Handle potential wireframe rendering for current draw call
556+ if ( shouldDrawWireframe ) {
560557 this . _drawDebugWireframe ( painter , depthMode , stencilMode , colorMode , indexBuffer , segment ,
561558 currentProperties , zoom , configuration , instanceCount ) ;
562559 }
0 commit comments