4
4
*
5
5
* GPU Accelerated JavaScript
6
6
*
7
- * @version 2.9.5
8
- * @date Sun Jul 19 2020 07:39:18 GMT-0400 (Eastern Daylight Time)
7
+ * @version 2.10.0
8
+ * @date Tue Aug 25 2020 14:05:30 GMT-0400 (Eastern Daylight Time)
9
9
*
10
10
* @license MIT
11
11
* The MIT License
@@ -1043,6 +1043,15 @@ class CPUFunctionNode extends FunctionNode {
1043
1043
this . astGeneric ( mNode . property , retArr ) ;
1044
1044
retArr . push ( ']' ) ;
1045
1045
return retArr ;
1046
+ case 'fn()[][]' :
1047
+ this . astGeneric ( mNode . object . object , retArr ) ;
1048
+ retArr . push ( '[' ) ;
1049
+ this . astGeneric ( mNode . object . property , retArr ) ;
1050
+ retArr . push ( ']' ) ;
1051
+ retArr . push ( '[' ) ;
1052
+ this . astGeneric ( mNode . property , retArr ) ;
1053
+ retArr . push ( ']' ) ;
1054
+ return retArr ;
1046
1055
default :
1047
1056
throw this . astErrorOutput ( 'Unexpected expression' , mNode ) ;
1048
1057
}
@@ -1064,6 +1073,9 @@ class CPUFunctionNode extends FunctionNode {
1064
1073
case 'Array(2)' :
1065
1074
case 'Array(3)' :
1066
1075
case 'Array(4)' :
1076
+ case 'Matrix(2)' :
1077
+ case 'Matrix(3)' :
1078
+ case 'Matrix(4)' :
1067
1079
case 'HTMLImageArray' :
1068
1080
case 'ArrayTexture(1)' :
1069
1081
case 'ArrayTexture(2)' :
@@ -1165,18 +1177,23 @@ class CPUFunctionNode extends FunctionNode {
1165
1177
}
1166
1178
1167
1179
astArrayExpression ( arrNode , retArr ) {
1180
+ const returnType = this . getType ( arrNode ) ;
1168
1181
const arrLen = arrNode . elements . length ;
1169
-
1170
- retArr . push ( 'new Float32Array([' ) ;
1182
+ const elements = [ ] ;
1171
1183
for ( let i = 0 ; i < arrLen ; ++ i ) {
1172
- if ( i > 0 ) {
1173
- retArr . push ( ', ' ) ;
1174
- }
1175
- const subNode = arrNode . elements [ i ] ;
1176
- this . astGeneric ( subNode , retArr )
1184
+ const element = [ ] ;
1185
+ this . astGeneric ( arrNode . elements [ i ] , element ) ;
1186
+ elements . push ( element . join ( '' ) ) ;
1187
+ }
1188
+ switch ( returnType ) {
1189
+ case 'Matrix(2)' :
1190
+ case 'Matrix(3)' :
1191
+ case 'Matrix(4)' :
1192
+ retArr . push ( `[${ elements . join ( ', ' ) } ]` ) ;
1193
+ break ;
1194
+ default :
1195
+ retArr . push ( `new Float32Array([${ elements . join ( ', ' ) } ])` ) ;
1177
1196
}
1178
- retArr . push ( '])' ) ;
1179
-
1180
1197
return retArr ;
1181
1198
}
1182
1199
@@ -1208,6 +1225,9 @@ function constantsToString(constants, types) {
1208
1225
case 'Array(2)' :
1209
1226
case 'Array(3)' :
1210
1227
case 'Array(4)' :
1228
+ case 'Matrix(2)' :
1229
+ case 'Matrix(3)' :
1230
+ case 'Matrix(4)' :
1211
1231
results . push ( `${ name } :new ${ constant . constructor . name } (${ JSON . stringify ( Array . from ( constant ) ) } )` ) ;
1212
1232
break ;
1213
1233
}
@@ -1347,6 +1367,9 @@ ${ header.join('\n') }
1347
1367
case 'Array(2)':
1348
1368
case 'Array(3)':
1349
1369
case 'Array(4)':
1370
+ case 'Matrix(2)':
1371
+ case 'Matrix(3)':
1372
+ case 'Matrix(4)':
1350
1373
if (incomingConstants.hasOwnProperty(p)) {
1351
1374
console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned');
1352
1375
}
@@ -2843,6 +2866,13 @@ class FunctionNode {
2843
2866
case 'BlockStatement' :
2844
2867
return this . getType ( ast . body ) ;
2845
2868
case 'ArrayExpression' :
2869
+ const childType = this . getType ( ast . elements [ 0 ] ) ;
2870
+ switch ( childType ) {
2871
+ case 'Array(2)' :
2872
+ case 'Array(3)' :
2873
+ case 'Array(4)' :
2874
+ return `Matrix(${ ast . elements . length } )` ;
2875
+ }
2846
2876
return `Array(${ ast . elements . length } )` ;
2847
2877
case 'Literal' :
2848
2878
const literalKey = this . astKey ( ast ) ;
@@ -3774,6 +3804,7 @@ class FunctionNode {
3774
3804
} ;
3775
3805
}
3776
3806
case 'fn()[]' :
3807
+ case 'fn()[][]' :
3777
3808
case '[][]' :
3778
3809
return {
3779
3810
signature : variableSignature ,
@@ -3883,6 +3914,9 @@ const typeLookupMap = {
3883
3914
'Array(2)' : 'Number' ,
3884
3915
'Array(3)' : 'Number' ,
3885
3916
'Array(4)' : 'Number' ,
3917
+ 'Matrix(2)' : 'Number' ,
3918
+ 'Matrix(3)' : 'Number' ,
3919
+ 'Matrix(4)' : 'Number' ,
3886
3920
'Array2D' : 'Number' ,
3887
3921
'Array3D' : 'Number' ,
3888
3922
'Input' : 'Number' ,
@@ -4004,8 +4038,21 @@ class FunctionTracer {
4004
4038
}
4005
4039
4006
4040
getDeclaration ( name ) {
4007
- const { currentContext, currentFunctionContext } = this ;
4008
- return currentContext [ name ] || currentFunctionContext [ name ] || null ;
4041
+ const { currentContext, currentFunctionContext, runningContexts } = this ;
4042
+ const declaration = currentContext [ name ] || currentFunctionContext [ name ] || null ;
4043
+
4044
+ if (
4045
+ ! declaration &&
4046
+ currentContext === currentFunctionContext &&
4047
+ runningContexts . length > 0
4048
+ ) {
4049
+ const previousRunningContext = runningContexts [ runningContexts . length - 2 ] ;
4050
+ if ( previousRunningContext [ name ] ) {
4051
+ return previousRunningContext [ name ] ;
4052
+ }
4053
+ }
4054
+
4055
+ return declaration ;
4009
4056
}
4010
4057
4011
4058
scan ( ast ) {
@@ -4380,14 +4427,15 @@ function glKernelString(Kernel, args, originKernel, setupContextString, destroyC
4380
4427
result . push ( context . toString ( ) ) ;
4381
4428
if ( kernel . renderOutput === kernel . renderTexture ) {
4382
4429
context . reset ( ) ;
4430
+ const framebufferName = context . getContextVariableName ( kernel . framebuffer ) ;
4383
4431
if ( kernel . renderKernels ) {
4384
4432
const results = kernel . renderKernels ( ) ;
4385
4433
const textureName = context . getContextVariableName ( kernel . texture . texture ) ;
4386
4434
result . push ( ` return {
4387
4435
result: {
4388
4436
texture: ${ textureName } ,
4389
4437
type: '${ results . result . type } ',
4390
- toArray: ${ getToArrayString ( results . result , textureName ) }
4438
+ toArray: ${ getToArrayString ( results . result , textureName , framebufferName ) }
4391
4439
},` ) ;
4392
4440
const { subKernels, mappedTextures } = kernel ;
4393
4441
for ( let i = 0 ; i < subKernels . length ; i ++ ) {
@@ -4399,7 +4447,7 @@ function glKernelString(Kernel, args, originKernel, setupContextString, destroyC
4399
4447
${ subKernel . property } : {
4400
4448
texture: ${ subKernelTextureName } ,
4401
4449
type: '${ subKernelResult . type } ',
4402
- toArray: ${ getToArrayString ( subKernelResult , subKernelTextureName ) }
4450
+ toArray: ${ getToArrayString ( subKernelResult , subKernelTextureName , framebufferName ) }
4403
4451
},` ) ;
4404
4452
}
4405
4453
result . push ( ` };` ) ;
@@ -4409,7 +4457,7 @@ function glKernelString(Kernel, args, originKernel, setupContextString, destroyC
4409
4457
result . push ( ` return {
4410
4458
texture: ${ textureName } ,
4411
4459
type: '${ rendered . type } ',
4412
- toArray: ${ getToArrayString ( rendered , textureName ) }
4460
+ toArray: ${ getToArrayString ( rendered , textureName , framebufferName ) }
4413
4461
};` ) ;
4414
4462
}
4415
4463
}
@@ -4424,7 +4472,7 @@ function glKernelString(Kernel, args, originKernel, setupContextString, destroyC
4424
4472
4425
4473
let constantsUpload = [ ] ;
4426
4474
kernelConstants . forEach ( ( kernelConstant ) => {
4427
- constantsUpload . push ( `${ kernelConstant . getStringValueHandler ( ) } ` ) ;
4475
+ constantsUpload . push ( `${ kernelConstant . getStringValueHandler ( ) } ` ) ;
4428
4476
} ) ;
4429
4477
return `function kernel(settings) {
4430
4478
const { context, constants } = settings;
@@ -4468,14 +4516,17 @@ function getGetPixelsString(kernel) {
4468
4516
} ) ;
4469
4517
}
4470
4518
4471
- function getToArrayString ( kernelResult , textureName ) {
4519
+ function getToArrayString ( kernelResult , textureName , framebufferName ) {
4472
4520
const toArray = kernelResult . toArray . toString ( ) ;
4473
4521
const useFunctionKeyword = ! / ^ f u n c t i o n / . test ( toArray ) ;
4474
4522
const flattenedFunctions = utils . flattenFunctionToString ( `${ useFunctionKeyword ? 'function ' : '' } ${ toArray } ` , {
4475
4523
findDependency : ( object , name ) => {
4476
4524
if ( object === 'utils' ) {
4477
4525
return `const ${ name } = ${ utils [ name ] . toString ( ) } ;` ;
4478
4526
} else if ( object === 'this' ) {
4527
+ if ( name === 'framebuffer' ) {
4528
+ return '' ;
4529
+ }
4479
4530
return `${ useFunctionKeyword ? 'function ' : '' } ${ kernelResult [ name ] . toString ( ) } ` ;
4480
4531
} else {
4481
4532
throw new Error ( 'unhandled fromObject' ) ;
@@ -4489,17 +4540,14 @@ function getToArrayString(kernelResult, textureName) {
4489
4540
if ( isDeclaration ) return null ;
4490
4541
return 'gl' ;
4491
4542
}
4492
- if ( property === '_framebuffer' ) {
4493
- return '_framebuffer' ;
4494
- }
4495
4543
if ( kernelResult . hasOwnProperty ( property ) ) {
4496
4544
return JSON . stringify ( kernelResult [ property ] ) ;
4497
4545
}
4498
4546
throw new Error ( `unhandled thisLookup ${ property } ` ) ;
4499
4547
}
4500
4548
} ) ;
4501
4549
return `() => {
4502
- let _framebuffer ;
4550
+ function framebuffer() { return ${ framebufferName } ; } ;
4503
4551
${ flattenedFunctions }
4504
4552
return toArray();
4505
4553
}` ;
@@ -5801,18 +5849,12 @@ class GLTexture extends Texture {
5801
5849
if ( this . texture . _refs ) return ;
5802
5850
}
5803
5851
this . context . deleteTexture ( this . texture ) ;
5804
- if ( this . texture . _refs === 0 && this . _framebuffer ) {
5805
- this . context . deleteFramebuffer ( this . _framebuffer ) ;
5806
- this . _framebuffer = null ;
5807
- }
5808
5852
}
5809
5853
5810
5854
framebuffer ( ) {
5811
5855
if ( ! this . _framebuffer ) {
5812
- this . _framebuffer = this . context . createFramebuffer ( ) ;
5856
+ this . _framebuffer = this . kernel . getRawValueFramebuffer ( this . size [ 0 ] , this . size [ 1 ] ) ;
5813
5857
}
5814
- this . _framebuffer . width = this . size [ 0 ] ;
5815
- this . _framebuffer . height = this . size [ 1 ] ;
5816
5858
return this . _framebuffer ;
5817
5859
}
5818
5860
}
@@ -5926,8 +5968,7 @@ class GLTextureUnsigned extends GLTexture {
5926
5968
}
5927
5969
renderRawOutput ( ) {
5928
5970
const { context : gl } = this ;
5929
- const framebuffer = gl . createFramebuffer ( ) ;
5930
- gl . bindFramebuffer ( gl . FRAMEBUFFER , framebuffer ) ;
5971
+ gl . bindFramebuffer ( gl . FRAMEBUFFER , this . framebuffer ( ) ) ;
5931
5972
gl . framebufferTexture2D (
5932
5973
gl . FRAMEBUFFER ,
5933
5974
gl . COLOR_ATTACHMENT0 ,
@@ -7412,6 +7453,9 @@ class WebGLFunctionNode extends FunctionNode {
7412
7453
case 'Array(4)' :
7413
7454
case 'Array(3)' :
7414
7455
case 'Array(2)' :
7456
+ case 'Matrix(2)' :
7457
+ case 'Matrix(3)' :
7458
+ case 'Matrix(4)' :
7415
7459
case 'Input' :
7416
7460
this . astGeneric ( ast . argument , result ) ;
7417
7461
break ;
@@ -7977,7 +8021,7 @@ class WebGLFunctionNode extends FunctionNode {
7977
8021
}
7978
8022
const markupType = typeMap [ type ] ;
7979
8023
if ( ! markupType ) {
7980
- throw this . astErrorOutput ( `Markup type ${ markupType } not handled` , varDecNode ) ;
8024
+ throw this . astErrorOutput ( `Markup type ${ type } not handled` , varDecNode ) ;
7981
8025
}
7982
8026
const declarationResult = [ ] ;
7983
8027
if ( actualType === 'Integer' && type === 'Integer' ) {
@@ -8275,6 +8319,15 @@ class WebGLFunctionNode extends FunctionNode {
8275
8319
retArr . push ( this . memberExpressionPropertyMarkup ( property ) ) ;
8276
8320
retArr . push ( ']' ) ;
8277
8321
return retArr ;
8322
+ case 'fn()[][]' :
8323
+ this . astCallExpression ( mNode . object . object , retArr ) ;
8324
+ retArr . push ( '[' ) ;
8325
+ retArr . push ( this . memberExpressionPropertyMarkup ( mNode . object . property ) ) ;
8326
+ retArr . push ( ']' ) ;
8327
+ retArr . push ( '[' ) ;
8328
+ retArr . push ( this . memberExpressionPropertyMarkup ( mNode . property ) ) ;
8329
+ retArr . push ( ']' ) ;
8330
+ return retArr ;
8278
8331
case '[][]' :
8279
8332
this . astArrayExpression ( mNode . object , retArr ) ;
8280
8333
retArr . push ( '[' ) ;
@@ -8402,6 +8455,14 @@ class WebGLFunctionNode extends FunctionNode {
8402
8455
this . memberExpressionXYZ ( xProperty , yProperty , zProperty , retArr ) ;
8403
8456
retArr . push ( ')' ) ;
8404
8457
break ;
8458
+ case 'Matrix(2)' :
8459
+ case 'Matrix(3)' :
8460
+ case 'Matrix(4)' :
8461
+ retArr . push ( `${ markupName } [${ this . memberExpressionPropertyMarkup ( yProperty ) } ]` ) ;
8462
+ if ( yProperty ) {
8463
+ retArr . push ( `[${ this . memberExpressionPropertyMarkup ( xProperty ) } ]` ) ;
8464
+ }
8465
+ break ;
8405
8466
default :
8406
8467
throw new Error ( `unhandled member expression "${ type } "` ) ;
8407
8468
}
@@ -8574,9 +8635,19 @@ class WebGLFunctionNode extends FunctionNode {
8574
8635
}
8575
8636
8576
8637
astArrayExpression ( arrNode , retArr ) {
8638
+ const returnType = this . getType ( arrNode ) ;
8639
+
8577
8640
const arrLen = arrNode . elements . length ;
8578
8641
8579
- retArr . push ( 'vec' + arrLen + '(' ) ;
8642
+ switch ( returnType ) {
8643
+ case 'Matrix(2)' :
8644
+ case 'Matrix(3)' :
8645
+ case 'Matrix(4)' :
8646
+ retArr . push ( `mat${ arrLen } (` ) ;
8647
+ break ;
8648
+ default :
8649
+ retArr . push ( `vec${ arrLen } (` ) ;
8650
+ }
8580
8651
for ( let i = 0 ; i < arrLen ; ++ i ) {
8581
8652
if ( i > 0 ) {
8582
8653
retArr . push ( ', ' ) ;
@@ -8630,6 +8701,9 @@ const typeMap = {
8630
8701
'Array(2)' : 'vec2' ,
8631
8702
'Array(3)' : 'vec3' ,
8632
8703
'Array(4)' : 'vec4' ,
8704
+ 'Matrix(2)' : 'mat2' ,
8705
+ 'Matrix(3)' : 'mat3' ,
8706
+ 'Matrix(4)' : 'mat4' ,
8633
8707
'Array2D' : 'sampler2D' ,
8634
8708
'Array3D' : 'sampler2D' ,
8635
8709
'Boolean' : 'bool' ,
@@ -10467,6 +10541,7 @@ class WebGLKernel extends GLKernel {
10467
10541
this . framebuffer = gl . createFramebuffer ( ) ;
10468
10542
this . framebuffer . width = texSize [ 0 ] ;
10469
10543
this . framebuffer . height = texSize [ 1 ] ;
10544
+ this . rawValueFramebuffers = { } ;
10470
10545
10471
10546
const vertices = new Float32Array ( [ - 1 , - 1 ,
10472
10547
1 , - 1 , - 1 , 1 ,
@@ -10999,6 +11074,19 @@ float integerCorrectionModulo(float number, float divisor) {
10999
11074
return result . join ( '' ) ;
11000
11075
}
11001
11076
11077
+ getRawValueFramebuffer ( width , height ) {
11078
+ if ( ! this . rawValueFramebuffers [ width ] ) {
11079
+ this . rawValueFramebuffers [ width ] = { } ;
11080
+ }
11081
+ if ( ! this . rawValueFramebuffers [ width ] [ height ] ) {
11082
+ const framebuffer = this . context . createFramebuffer ( ) ;
11083
+ framebuffer . width = width ;
11084
+ framebuffer . height = height ;
11085
+ this . rawValueFramebuffers [ width ] [ height ] = framebuffer ;
11086
+ }
11087
+ return this . rawValueFramebuffers [ width ] [ height ] ;
11088
+ }
11089
+
11002
11090
getKernelResultDeclaration ( ) {
11003
11091
switch ( this . returnType ) {
11004
11092
case 'Array(2)' :
@@ -11329,6 +11417,13 @@ float integerCorrectionModulo(float number, float divisor) {
11329
11417
if ( this . framebuffer ) {
11330
11418
this . context . deleteFramebuffer ( this . framebuffer ) ;
11331
11419
}
11420
+ for ( const width in this . rawValueFramebuffers ) {
11421
+ for ( const height in this . rawValueFramebuffers [ width ] ) {
11422
+ this . context . deleteFramebuffer ( this . rawValueFramebuffers [ width ] [ height ] ) ;
11423
+ delete this . rawValueFramebuffers [ width ] [ height ] ;
11424
+ }
11425
+ delete this . rawValueFramebuffers [ width ] ;
11426
+ }
11332
11427
if ( this . vertShader ) {
11333
11428
this . context . deleteShader ( this . vertShader ) ;
11334
11429
}
@@ -14754,7 +14849,7 @@ const utils = {
14754
14849
if ( ! flattened [ functionDependency ] ) {
14755
14850
flattened [ functionDependency ] = true ;
14756
14851
}
14757
- flattenedFunctionDependencies . push ( utils . flattenFunctionToString ( functionDependency , settings ) + '\n' ) ;
14852
+ functionDependency ? flattenedFunctionDependencies . push ( utils . flattenFunctionToString ( functionDependency , settings ) + '\n' ) : '' ;
14758
14853
}
14759
14854
return flattenedFunctionDependencies . join ( '' ) + result ;
14760
14855
}
0 commit comments