11/**
22 * @author Richard Davey <rich@photonstorm.com>
33 * @author Felipe Alfonso <@bitnenfer>
4+ * @author Matthew Groves <@doormat>
45 * @copyright 2020 Photon Storm Ltd.
56 * @license {@link https://opensource.org/licenses/MIT|MIT License }
67 */
78
9+ /**
10+ * Generate shader source to test maximum ifs.
11+ *
12+ * @private
13+ * @param {number } maxIfs - The number of if statements to generate
14+ */
15+ function GenerateSrc ( maxIfs )
16+ {
17+ var src = '' ;
18+
19+ for ( var i = 0 ; i < maxIfs ; ++ i )
20+ {
21+ if ( i > 0 )
22+ {
23+ src += '\nelse ' ;
24+ }
25+
26+ if ( i < maxIfs - 1 )
27+ {
28+ src += 'if(test == ' + i + '.0){}' ;
29+ }
30+ }
31+
32+ return src ;
33+ }
34+
835/**
936 * @namespace Phaser.Renderer.WebGL.Utils
1037 * @since 3.0.0
@@ -16,12 +43,12 @@ module.exports = {
1643 *
1744 * @function Phaser.Renderer.WebGL.Utils.getTintFromFloats
1845 * @since 3.0.0
19- *
20- * @param {number } r - Red component in a range from 0.0 to 1.0
46+ *
47+ * @param {number } r - Red component in a range from 0.0 to 1.0
2148 * @param {number } g - Green component in a range from 0.0 to 1.0
2249 * @param {number } b - Blue component in a range from 0.0 to 1.0
2350 * @param {number } a - Alpha component in a range from 0.0 to 1.0
24- *
51+ *
2552 * @return {number } The packed RGBA values as a Uint32.
2653 */
2754 getTintFromFloats : function ( r , g , b , a )
@@ -40,10 +67,10 @@ module.exports = {
4067 *
4168 * @function Phaser.Renderer.WebGL.Utils.getTintAppendFloatAlpha
4269 * @since 3.0.0
43- *
70+ *
4471 * @param {number } rgb - Uint24 representing RGB components
4572 * @param {number } a - Float32 representing Alpha component
46- *
73+ *
4774 * @return {number } Packed RGBA as Uint32
4875 */
4976 getTintAppendFloatAlpha : function ( rgb , a )
@@ -54,15 +81,15 @@ module.exports = {
5481
5582 /**
5683 * Packs a Uint24, representing RGB components, with a Float32, representing
57- * the alpha component, with a range between 0.0 and 1.0 and return a
84+ * the alpha component, with a range between 0.0 and 1.0 and return a
5885 * swizzled Uint32
5986 *
6087 * @function Phaser.Renderer.WebGL.Utils.getTintAppendFloatAlphaAndSwap
6188 * @since 3.0.0
62- *
89+ *
6390 * @param {number } rgb - Uint24 representing RGB components
6491 * @param {number } a - Float32 representing Alpha component
65- *
92+ *
6693 * @return {number } Packed RGBA as Uint32
6794 */
6895 getTintAppendFloatAlphaAndSwap : function ( rgb , a )
@@ -80,10 +107,10 @@ module.exports = {
80107 *
81108 * @function Phaser.Renderer.WebGL.Utils.getFloatsFromUintRGB
82109 * @since 3.0.0
83- *
110+ *
84111 * @param {number } rgb - RGB packed as a Uint24
85- *
86- * @return {array } Array of floats representing each component as a float
112+ *
113+ * @return {array } Array of floats representing each component as a float
87114 */
88115 getFloatsFromUintRGB : function ( rgb )
89116 {
@@ -99,10 +126,10 @@ module.exports = {
99126 *
100127 * @function Phaser.Renderer.WebGL.Utils.getComponentCount
101128 * @since 3.0.0
102- *
103- * @param {array } attributes - Array of attributes
129+ *
130+ * @param {array } attributes - Array of attributes
104131 * @param {WebGLRenderingContext } glContext - WebGLContext used for check types
105- *
132+ *
106133 * @return {number } Count of 32 bit attributes in vertex
107134 */
108135 getComponentCount : function ( attributes , glContext )
@@ -112,7 +139,7 @@ module.exports = {
112139 for ( var index = 0 ; index < attributes . length ; ++ index )
113140 {
114141 var element = attributes [ index ] ;
115-
142+
116143 if ( element . type === glContext . FLOAT )
117144 {
118145 count += element . size ;
@@ -124,6 +151,58 @@ module.exports = {
124151 }
125152
126153 return count ;
154+ } ,
155+
156+ /**
157+ * Check to see how many texture units the GPU supports, based on the given config value.
158+ * Then tests this against the maximum number of iterations GLSL can support.
159+ *
160+ * @function Phaser.Renderer.WebGL.Utils.checkShaderMax
161+ * @since 3.25.0
162+ *
163+ * @param {WebGLRenderingContext } gl - The WebGLContext used to create the shaders.
164+ * @param {number } maxTextures - The Game Config maxTextures value.
165+ *
166+ * @return {number } The number of texture units that is supported by this browser and GPU.
167+ */
168+ checkShaderMax : function ( gl , maxTextures )
169+ {
170+ if ( ! maxTextures || maxTextures === - 1 )
171+ {
172+ maxTextures = gl . getParameter ( gl . MAX_TEXTURE_IMAGE_UNITS ) ;
173+ }
174+
175+ var shader = gl . createShader ( gl . FRAGMENT_SHADER ) ;
176+
177+ var fragTemplate = [
178+ 'precision mediump float;' ,
179+ 'void main(void){' ,
180+ 'float test = 0.1;' ,
181+ '%forloop%' ,
182+ 'gl_FragColor = vec4(0.0);' ,
183+ '}'
184+ ] . join ( '\n' ) ;
185+
186+ // eslint-disable-next-line no-constant-condition
187+ while ( true )
188+ {
189+ var fragmentSrc = fragTemplate . replace ( / % f o r l o o p % / gi, GenerateSrc ( maxTextures ) ) ;
190+
191+ gl . shaderSource ( shader , fragmentSrc ) ;
192+ gl . compileShader ( shader ) ;
193+
194+ if ( ! gl . getShaderParameter ( shader , gl . COMPILE_STATUS ) )
195+ {
196+ maxTextures = ( maxTextures / 2 ) | 0 ;
197+ }
198+ else
199+ {
200+ // valid!
201+ break ;
202+ }
203+ }
204+
205+ return maxTextures ;
127206 }
128207
129208} ;
0 commit comments