44 *
55 * GPU Accelerated JavaScript
66 *
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)
99 *
1010 * @license MIT
1111 * The MIT License
@@ -1043,6 +1043,15 @@ class CPUFunctionNode extends FunctionNode {
10431043 this . astGeneric ( mNode . property , retArr ) ;
10441044 retArr . push ( ']' ) ;
10451045 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 ;
10461055 default :
10471056 throw this . astErrorOutput ( 'Unexpected expression' , mNode ) ;
10481057 }
@@ -1064,6 +1073,9 @@ class CPUFunctionNode extends FunctionNode {
10641073 case 'Array(2)' :
10651074 case 'Array(3)' :
10661075 case 'Array(4)' :
1076+ case 'Matrix(2)' :
1077+ case 'Matrix(3)' :
1078+ case 'Matrix(4)' :
10671079 case 'HTMLImageArray' :
10681080 case 'ArrayTexture(1)' :
10691081 case 'ArrayTexture(2)' :
@@ -1165,18 +1177,23 @@ class CPUFunctionNode extends FunctionNode {
11651177 }
11661178
11671179 astArrayExpression ( arrNode , retArr ) {
1180+ const returnType = this . getType ( arrNode ) ;
11681181 const arrLen = arrNode . elements . length ;
1169-
1170- retArr . push ( 'new Float32Array([' ) ;
1182+ const elements = [ ] ;
11711183 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 ( ', ' ) } ])` ) ;
11771196 }
1178- retArr . push ( '])' ) ;
1179-
11801197 return retArr ;
11811198 }
11821199
@@ -1208,6 +1225,9 @@ function constantsToString(constants, types) {
12081225 case 'Array(2)' :
12091226 case 'Array(3)' :
12101227 case 'Array(4)' :
1228+ case 'Matrix(2)' :
1229+ case 'Matrix(3)' :
1230+ case 'Matrix(4)' :
12111231 results . push ( `${ name } :new ${ constant . constructor . name } (${ JSON . stringify ( Array . from ( constant ) ) } )` ) ;
12121232 break ;
12131233 }
@@ -1347,6 +1367,9 @@ ${ header.join('\n') }
13471367 case 'Array(2)':
13481368 case 'Array(3)':
13491369 case 'Array(4)':
1370+ case 'Matrix(2)':
1371+ case 'Matrix(3)':
1372+ case 'Matrix(4)':
13501373 if (incomingConstants.hasOwnProperty(p)) {
13511374 console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned');
13521375 }
@@ -2843,6 +2866,13 @@ class FunctionNode {
28432866 case 'BlockStatement' :
28442867 return this . getType ( ast . body ) ;
28452868 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+ }
28462876 return `Array(${ ast . elements . length } )` ;
28472877 case 'Literal' :
28482878 const literalKey = this . astKey ( ast ) ;
@@ -3774,6 +3804,7 @@ class FunctionNode {
37743804 } ;
37753805 }
37763806 case 'fn()[]' :
3807+ case 'fn()[][]' :
37773808 case '[][]' :
37783809 return {
37793810 signature : variableSignature ,
@@ -3883,6 +3914,9 @@ const typeLookupMap = {
38833914 'Array(2)' : 'Number' ,
38843915 'Array(3)' : 'Number' ,
38853916 'Array(4)' : 'Number' ,
3917+ 'Matrix(2)' : 'Number' ,
3918+ 'Matrix(3)' : 'Number' ,
3919+ 'Matrix(4)' : 'Number' ,
38863920 'Array2D' : 'Number' ,
38873921 'Array3D' : 'Number' ,
38883922 'Input' : 'Number' ,
@@ -4004,8 +4038,21 @@ class FunctionTracer {
40044038 }
40054039
40064040 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 ;
40094056 }
40104057
40114058 scan ( ast ) {
@@ -4380,14 +4427,15 @@ function glKernelString(Kernel, args, originKernel, setupContextString, destroyC
43804427 result . push ( context . toString ( ) ) ;
43814428 if ( kernel . renderOutput === kernel . renderTexture ) {
43824429 context . reset ( ) ;
4430+ const framebufferName = context . getContextVariableName ( kernel . framebuffer ) ;
43834431 if ( kernel . renderKernels ) {
43844432 const results = kernel . renderKernels ( ) ;
43854433 const textureName = context . getContextVariableName ( kernel . texture . texture ) ;
43864434 result . push ( ` return {
43874435 result: {
43884436 texture: ${ textureName } ,
43894437 type: '${ results . result . type } ',
4390- toArray: ${ getToArrayString ( results . result , textureName ) }
4438+ toArray: ${ getToArrayString ( results . result , textureName , framebufferName ) }
43914439 },` ) ;
43924440 const { subKernels, mappedTextures } = kernel ;
43934441 for ( let i = 0 ; i < subKernels . length ; i ++ ) {
@@ -4399,7 +4447,7 @@ function glKernelString(Kernel, args, originKernel, setupContextString, destroyC
43994447 ${ subKernel . property } : {
44004448 texture: ${ subKernelTextureName } ,
44014449 type: '${ subKernelResult . type } ',
4402- toArray: ${ getToArrayString ( subKernelResult , subKernelTextureName ) }
4450+ toArray: ${ getToArrayString ( subKernelResult , subKernelTextureName , framebufferName ) }
44034451 },` ) ;
44044452 }
44054453 result . push ( ` };` ) ;
@@ -4409,7 +4457,7 @@ function glKernelString(Kernel, args, originKernel, setupContextString, destroyC
44094457 result . push ( ` return {
44104458 texture: ${ textureName } ,
44114459 type: '${ rendered . type } ',
4412- toArray: ${ getToArrayString ( rendered , textureName ) }
4460+ toArray: ${ getToArrayString ( rendered , textureName , framebufferName ) }
44134461 };` ) ;
44144462 }
44154463 }
@@ -4424,7 +4472,7 @@ function glKernelString(Kernel, args, originKernel, setupContextString, destroyC
44244472
44254473 let constantsUpload = [ ] ;
44264474 kernelConstants . forEach ( ( kernelConstant ) => {
4427- constantsUpload . push ( `${ kernelConstant . getStringValueHandler ( ) } ` ) ;
4475+ constantsUpload . push ( `${ kernelConstant . getStringValueHandler ( ) } ` ) ;
44284476 } ) ;
44294477 return `function kernel(settings) {
44304478 const { context, constants } = settings;
@@ -4468,14 +4516,17 @@ function getGetPixelsString(kernel) {
44684516 } ) ;
44694517}
44704518
4471- function getToArrayString ( kernelResult , textureName ) {
4519+ function getToArrayString ( kernelResult , textureName , framebufferName ) {
44724520 const toArray = kernelResult . toArray . toString ( ) ;
44734521 const useFunctionKeyword = ! / ^ f u n c t i o n / . test ( toArray ) ;
44744522 const flattenedFunctions = utils . flattenFunctionToString ( `${ useFunctionKeyword ? 'function ' : '' } ${ toArray } ` , {
44754523 findDependency : ( object , name ) => {
44764524 if ( object === 'utils' ) {
44774525 return `const ${ name } = ${ utils [ name ] . toString ( ) } ;` ;
44784526 } else if ( object === 'this' ) {
4527+ if ( name === 'framebuffer' ) {
4528+ return '' ;
4529+ }
44794530 return `${ useFunctionKeyword ? 'function ' : '' } ${ kernelResult [ name ] . toString ( ) } ` ;
44804531 } else {
44814532 throw new Error ( 'unhandled fromObject' ) ;
@@ -4489,17 +4540,14 @@ function getToArrayString(kernelResult, textureName) {
44894540 if ( isDeclaration ) return null ;
44904541 return 'gl' ;
44914542 }
4492- if ( property === '_framebuffer' ) {
4493- return '_framebuffer' ;
4494- }
44954543 if ( kernelResult . hasOwnProperty ( property ) ) {
44964544 return JSON . stringify ( kernelResult [ property ] ) ;
44974545 }
44984546 throw new Error ( `unhandled thisLookup ${ property } ` ) ;
44994547 }
45004548 } ) ;
45014549 return `() => {
4502- let _framebuffer ;
4550+ function framebuffer() { return ${ framebufferName } ; } ;
45034551 ${ flattenedFunctions }
45044552 return toArray();
45054553 }` ;
@@ -5801,18 +5849,12 @@ class GLTexture extends Texture {
58015849 if ( this . texture . _refs ) return ;
58025850 }
58035851 this . context . deleteTexture ( this . texture ) ;
5804- if ( this . texture . _refs === 0 && this . _framebuffer ) {
5805- this . context . deleteFramebuffer ( this . _framebuffer ) ;
5806- this . _framebuffer = null ;
5807- }
58085852 }
58095853
58105854 framebuffer ( ) {
58115855 if ( ! this . _framebuffer ) {
5812- this . _framebuffer = this . context . createFramebuffer ( ) ;
5856+ this . _framebuffer = this . kernel . getRawValueFramebuffer ( this . size [ 0 ] , this . size [ 1 ] ) ;
58135857 }
5814- this . _framebuffer . width = this . size [ 0 ] ;
5815- this . _framebuffer . height = this . size [ 1 ] ;
58165858 return this . _framebuffer ;
58175859 }
58185860}
@@ -5926,8 +5968,7 @@ class GLTextureUnsigned extends GLTexture {
59265968 }
59275969 renderRawOutput ( ) {
59285970 const { context : gl } = this ;
5929- const framebuffer = gl . createFramebuffer ( ) ;
5930- gl . bindFramebuffer ( gl . FRAMEBUFFER , framebuffer ) ;
5971+ gl . bindFramebuffer ( gl . FRAMEBUFFER , this . framebuffer ( ) ) ;
59315972 gl . framebufferTexture2D (
59325973 gl . FRAMEBUFFER ,
59335974 gl . COLOR_ATTACHMENT0 ,
@@ -7412,6 +7453,9 @@ class WebGLFunctionNode extends FunctionNode {
74127453 case 'Array(4)' :
74137454 case 'Array(3)' :
74147455 case 'Array(2)' :
7456+ case 'Matrix(2)' :
7457+ case 'Matrix(3)' :
7458+ case 'Matrix(4)' :
74157459 case 'Input' :
74167460 this . astGeneric ( ast . argument , result ) ;
74177461 break ;
@@ -7977,7 +8021,7 @@ class WebGLFunctionNode extends FunctionNode {
79778021 }
79788022 const markupType = typeMap [ type ] ;
79798023 if ( ! markupType ) {
7980- throw this . astErrorOutput ( `Markup type ${ markupType } not handled` , varDecNode ) ;
8024+ throw this . astErrorOutput ( `Markup type ${ type } not handled` , varDecNode ) ;
79818025 }
79828026 const declarationResult = [ ] ;
79838027 if ( actualType === 'Integer' && type === 'Integer' ) {
@@ -8275,6 +8319,15 @@ class WebGLFunctionNode extends FunctionNode {
82758319 retArr . push ( this . memberExpressionPropertyMarkup ( property ) ) ;
82768320 retArr . push ( ']' ) ;
82778321 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 ;
82788331 case '[][]' :
82798332 this . astArrayExpression ( mNode . object , retArr ) ;
82808333 retArr . push ( '[' ) ;
@@ -8402,6 +8455,14 @@ class WebGLFunctionNode extends FunctionNode {
84028455 this . memberExpressionXYZ ( xProperty , yProperty , zProperty , retArr ) ;
84038456 retArr . push ( ')' ) ;
84048457 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 ;
84058466 default :
84068467 throw new Error ( `unhandled member expression "${ type } "` ) ;
84078468 }
@@ -8574,9 +8635,19 @@ class WebGLFunctionNode extends FunctionNode {
85748635 }
85758636
85768637 astArrayExpression ( arrNode , retArr ) {
8638+ const returnType = this . getType ( arrNode ) ;
8639+
85778640 const arrLen = arrNode . elements . length ;
85788641
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+ }
85808651 for ( let i = 0 ; i < arrLen ; ++ i ) {
85818652 if ( i > 0 ) {
85828653 retArr . push ( ', ' ) ;
@@ -8630,6 +8701,9 @@ const typeMap = {
86308701 'Array(2)' : 'vec2' ,
86318702 'Array(3)' : 'vec3' ,
86328703 'Array(4)' : 'vec4' ,
8704+ 'Matrix(2)' : 'mat2' ,
8705+ 'Matrix(3)' : 'mat3' ,
8706+ 'Matrix(4)' : 'mat4' ,
86338707 'Array2D' : 'sampler2D' ,
86348708 'Array3D' : 'sampler2D' ,
86358709 'Boolean' : 'bool' ,
@@ -10467,6 +10541,7 @@ class WebGLKernel extends GLKernel {
1046710541 this . framebuffer = gl . createFramebuffer ( ) ;
1046810542 this . framebuffer . width = texSize [ 0 ] ;
1046910543 this . framebuffer . height = texSize [ 1 ] ;
10544+ this . rawValueFramebuffers = { } ;
1047010545
1047110546 const vertices = new Float32Array ( [ - 1 , - 1 ,
1047210547 1 , - 1 , - 1 , 1 ,
@@ -10999,6 +11074,19 @@ float integerCorrectionModulo(float number, float divisor) {
1099911074 return result . join ( '' ) ;
1100011075 }
1100111076
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+
1100211090 getKernelResultDeclaration ( ) {
1100311091 switch ( this . returnType ) {
1100411092 case 'Array(2)' :
@@ -11329,6 +11417,13 @@ float integerCorrectionModulo(float number, float divisor) {
1132911417 if ( this . framebuffer ) {
1133011418 this . context . deleteFramebuffer ( this . framebuffer ) ;
1133111419 }
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+ }
1133211427 if ( this . vertShader ) {
1133311428 this . context . deleteShader ( this . vertShader ) ;
1133411429 }
@@ -14754,7 +14849,7 @@ const utils = {
1475414849 if ( ! flattened [ functionDependency ] ) {
1475514850 flattened [ functionDependency ] = true ;
1475614851 }
14757- flattenedFunctionDependencies . push ( utils . flattenFunctionToString ( functionDependency , settings ) + '\n' ) ;
14852+ functionDependency ? flattenedFunctionDependencies . push ( utils . flattenFunctionToString ( functionDependency , settings ) + '\n' ) : '' ;
1475814853 }
1475914854 return flattenedFunctionDependencies . join ( '' ) + result ;
1476014855 }
0 commit comments