44 *
55 * GPU Accelerated JavaScript
66 *
7- * @version 2.0.0-rc.11
8- * @date Wed Apr 24 2019 17:53:53 GMT-0400 (Eastern Daylight Time)
7+ * @version 2.0.0-rc.12
8+ * @date Fri Apr 26 2019 22:06:12 GMT-0400 (Eastern Daylight Time)
99 *
1010 * @license MIT
1111 * The MIT License
@@ -790,6 +790,12 @@ class CPUKernel extends Kernel {
790790 }
791791 }
792792
793+ if ( this . graphical ) {
794+ if ( this . output . length !== 2 ) {
795+ throw new Error ( 'Output must have 2 dimensions on graphical mode' ) ;
796+ }
797+ }
798+
793799 this . checkOutput ( ) ;
794800 }
795801
@@ -885,7 +891,7 @@ class CPUKernel extends Kernel {
885891 return function (${ this . argumentNames . map ( argumentName => 'user_' + argumentName ) . join ( ', ' ) } ) {
886892 ${ this . _processConstants ( ) }
887893 ${ this . _processArguments ( ) }
888- ${ this . graphical ? this . _graphicalKernelLoop ( kernel ) : this . _resultKernelLoop ( kernel ) }
894+ ${ this . graphical ? this . _graphicalKernelBody ( kernel ) : this . _resultKernelBody ( kernel ) }
889895 ${ translatedSources . length > 0 ? translatedSources . join ( '\n' ) : '' }
890896 }.bind(this);` ;
891897 return kernelString ;
@@ -958,18 +964,38 @@ class CPUKernel extends Kernel {
958964 const imageArray = new Array ( image . height ) ;
959965 let index = 0 ;
960966 for ( let y = image . height - 1 ; y >= 0 ; y -- ) {
961- imageArray [ y ] = new Array ( image . width ) ;
967+ const row = imageArray [ y ] = new Array ( image . width ) ;
962968 for ( let x = 0 ; x < image . width ; x ++ ) {
963- const r = pixelsData [ index ++ ] / 255 ;
964- const g = pixelsData [ index ++ ] / 255 ;
965- const b = pixelsData [ index ++ ] / 255 ;
966- const a = pixelsData [ index ++ ] / 255 ;
967- imageArray [ y ] [ x ] = [ r , g , b , a ] ;
969+ const pixel = new Float32Array ( 4 ) ;
970+ pixel [ 0 ] = pixelsData [ index ++ ] / 255 ;
971+ pixel [ 1 ] = pixelsData [ index ++ ] / 255 ;
972+ pixel [ 2 ] = pixelsData [ index ++ ] / 255 ;
973+ pixel [ 3 ] = pixelsData [ index ++ ] / 255 ;
974+ row [ x ] = pixel ;
968975 }
969976 }
970977 return imageArray ;
971978 }
972979
980+ getPixels ( ) {
981+ const [ width , height ] = this . output ;
982+ const halfHeight = height / 2 | 0 ;
983+ const bytesPerRow = width * 4 ;
984+ const temp = new Uint8Array ( width * 4 ) ;
985+ const pixels = this . _imageData . data . slice ( 0 ) ;
986+ for ( let y = 0 ; y < halfHeight ; ++ y ) {
987+ var topOffset = y * bytesPerRow ;
988+ var bottomOffset = ( height - y - 1 ) * bytesPerRow ;
989+
990+ temp . set ( pixels . subarray ( topOffset , topOffset + bytesPerRow ) ) ;
991+
992+ pixels . copyWithin ( topOffset , bottomOffset , bottomOffset + bytesPerRow ) ;
993+
994+ pixels . set ( temp , bottomOffset ) ;
995+ }
996+ return pixels ;
997+ }
998+
973999 _imageTo3DArray ( images ) {
9741000 const imagesArray = new Array ( images . length ) ;
9751001 for ( let i = 0 ; i < images . length ; i ++ ) {
@@ -978,7 +1004,7 @@ class CPUKernel extends Kernel {
9781004 return imagesArray ;
9791005 }
9801006
981- _resultKernelLoop ( kernelString ) {
1007+ _resultKernelBody ( kernelString ) {
9821008 switch ( this . output . length ) {
9831009 case 1 :
9841010 return this . _resultKernel1DLoop ( kernelString ) + this . _kernelOutput ( ) ;
@@ -991,14 +1017,10 @@ class CPUKernel extends Kernel {
9911017 }
9921018 }
9931019
994- _graphicalKernelLoop ( kernelString ) {
1020+ _graphicalKernelBody ( kernelString ) {
9951021 switch ( this . output . length ) {
996- case 1 :
997- return this . _graphicalKernel1DLoop ( kernelString ) + this . _graphicalOutput ( ) ;
9981022 case 2 :
9991023 return this . _graphicalKernel2DLoop ( kernelString ) + this . _graphicalOutput ( ) ;
1000- case 3 :
1001- return this . _graphicalKernel3DLoop ( kernelString ) + this . _graphicalOutput ( ) ;
10021024 default :
10031025 throw new Error ( 'unsupported size kernel' ) ;
10041026 }
@@ -1049,30 +1071,12 @@ class CPUKernel extends Kernel {
10491071 }` ;
10501072 }
10511073
1052- _graphicalKernel1DLoop ( kernelString ) {
1053- const {
1054- output
1055- } = this ;
1056- const constructorString = this . _getKernelResultTypeConstructorString ( ) ;
1057- return `${ this . _mapSubKernels ( subKernel => `let subKernelResult_${ subKernel . name } ;` ) . join ( '\n' ) }
1058- ${ this . _mapSubKernels ( subKernel => `const result_${ subKernel . name } = new ${ constructorString } (${ output [ 0 ] } );\n` ) . join ( '' ) }
1059- for (let x = 0; x < ${ output [ 0 ] } ; x++) {
1060- this.thread.x = x;
1061- this.thread.y = 0;
1062- this.thread.z = 0;
1063- let kernelResult;
1064- ${ kernelString }
1065- result[x] = kernelResult;
1066- ${ this . _mapSubKernels ( subKernel => `result_${ subKernel . name } [x] = subKernelResult_${ subKernel . name } ;\n` ) . join ( '' ) }
1067- }` ;
1068- }
1069-
10701074 _resultKernel2DLoop ( kernelString ) {
10711075 const {
10721076 output
10731077 } = this ;
10741078 const constructorString = this . _getKernelResultTypeConstructorString ( ) ;
1075- return `const result = new Array(${ output [ 2 ] } );
1079+ return `const result = new Array(${ output [ 1 ] } );
10761080 ${ this . _mapSubKernels ( subKernel => `let subKernelResult_${ subKernel . name } ;` ) . join ( '\n' ) }
10771081 ${ this . _mapSubKernels ( subKernel => `const result_${ subKernel . name } = new Array(${ output [ 1 ] } );\n` ) . join ( '' ) }
10781082 for (let y = 0; y < ${ output [ 1 ] } ; y++) {
@@ -1136,28 +1140,6 @@ class CPUKernel extends Kernel {
11361140 }` ;
11371141 }
11381142
1139- _graphicalKernel3DLoop ( kernelString ) {
1140- const {
1141- output
1142- } = this ;
1143- const constructorString = this . _getKernelResultTypeConstructorString ( ) ;
1144- return `${ this . _mapSubKernels ( subKernel => `let subKernelResult_${ subKernel . name } ;` ) . join ( '\n' ) }
1145- ${ this . _mapSubKernels ( subKernel => `const result_${ subKernel . name } = new Array(${ output [ 2 ] } );\n` ) . join ( '' ) }
1146- for (let z = 0; z < ${ output [ 2 ] } ; z++) {
1147- this.thread.z = z;
1148- ${ this . _mapSubKernels ( subKernel => `const result_${ subKernel . name } Y = result_${ subKernel . name } [z] = new Array(${ output [ 1 ] } );\n` ) . join ( '' ) }
1149- for (let y = 0; y < ${ output [ 1 ] } ; y++) {
1150- this.thread.y = y;
1151- ${ this . _mapSubKernels ( subKernel => `const result_${ subKernel . name } X = result_${ subKernel . name } Y[y] = new ${ constructorString } (${ output [ 0 ] } );\n` ) . join ( '' ) }
1152- for (let x = 0; x < ${ output [ 0 ] } ; x++) {
1153- this.thread.x = x;
1154- ${ kernelString }
1155- ${ this . _mapSubKernels ( subKernel => `result_${ subKernel . name } X[x] = subKernelResult_${ subKernel . name } ;\n` ) . join ( '' ) }
1156- }
1157- }
1158- }` ;
1159- }
1160-
11611143 _kernelOutput ( ) {
11621144 if ( ! this . subKernels ) {
11631145 return 'return result;' ;
@@ -3585,6 +3567,16 @@ class GLKernel extends Kernel {
35853567 }
35863568 return zResults ;
35873569 }
3570+ getPixels ( ) {
3571+ const {
3572+ context : gl ,
3573+ output
3574+ } = this ;
3575+ const [ width , height ] = output ;
3576+ const pixels = new Uint8Array ( width * height * 4 ) ;
3577+ gl . readPixels ( 0 , 0 , width , height , gl . RGBA , gl . UNSIGNED_BYTE , pixels ) ;
3578+ return pixels ;
3579+ }
35883580}
35893581
35903582const renderStrategy = Object . freeze ( {
@@ -4071,6 +4063,10 @@ class Kernel {
40714063 }
40724064 }
40734065
4066+ getPixels ( ) {
4067+ throw new Error ( `"getPixels" called on ${ this . constructor . name } ` ) ;
4068+ }
4069+
40744070 checkOutput ( ) {
40754071 if ( ! this . output || ! Array . isArray ( this . output ) ) throw new Error ( 'kernel.output not an array' ) ;
40764072 if ( this . output . length < 1 ) throw new Error ( 'kernel.output is empty, needs at least 1 value' ) ;
0 commit comments