4
4
*
5
5
* GPU Accelerated JavaScript
6
6
*
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)
9
9
*
10
10
* @license MIT
11
11
* The MIT License
@@ -790,6 +790,12 @@ class CPUKernel extends Kernel {
790
790
}
791
791
}
792
792
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
+
793
799
this . checkOutput ( ) ;
794
800
}
795
801
@@ -885,7 +891,7 @@ class CPUKernel extends Kernel {
885
891
return function (${ this . argumentNames . map ( argumentName => 'user_' + argumentName ) . join ( ', ' ) } ) {
886
892
${ this . _processConstants ( ) }
887
893
${ this . _processArguments ( ) }
888
- ${ this . graphical ? this . _graphicalKernelLoop ( kernel ) : this . _resultKernelLoop ( kernel ) }
894
+ ${ this . graphical ? this . _graphicalKernelBody ( kernel ) : this . _resultKernelBody ( kernel ) }
889
895
${ translatedSources . length > 0 ? translatedSources . join ( '\n' ) : '' }
890
896
}.bind(this);` ;
891
897
return kernelString ;
@@ -958,18 +964,38 @@ class CPUKernel extends Kernel {
958
964
const imageArray = new Array ( image . height ) ;
959
965
let index = 0 ;
960
966
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 ) ;
962
968
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 ;
968
975
}
969
976
}
970
977
return imageArray ;
971
978
}
972
979
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
+
973
999
_imageTo3DArray ( images ) {
974
1000
const imagesArray = new Array ( images . length ) ;
975
1001
for ( let i = 0 ; i < images . length ; i ++ ) {
@@ -978,7 +1004,7 @@ class CPUKernel extends Kernel {
978
1004
return imagesArray ;
979
1005
}
980
1006
981
- _resultKernelLoop ( kernelString ) {
1007
+ _resultKernelBody ( kernelString ) {
982
1008
switch ( this . output . length ) {
983
1009
case 1 :
984
1010
return this . _resultKernel1DLoop ( kernelString ) + this . _kernelOutput ( ) ;
@@ -991,14 +1017,10 @@ class CPUKernel extends Kernel {
991
1017
}
992
1018
}
993
1019
994
- _graphicalKernelLoop ( kernelString ) {
1020
+ _graphicalKernelBody ( kernelString ) {
995
1021
switch ( this . output . length ) {
996
- case 1 :
997
- return this . _graphicalKernel1DLoop ( kernelString ) + this . _graphicalOutput ( ) ;
998
1022
case 2 :
999
1023
return this . _graphicalKernel2DLoop ( kernelString ) + this . _graphicalOutput ( ) ;
1000
- case 3 :
1001
- return this . _graphicalKernel3DLoop ( kernelString ) + this . _graphicalOutput ( ) ;
1002
1024
default :
1003
1025
throw new Error ( 'unsupported size kernel' ) ;
1004
1026
}
@@ -1049,30 +1071,12 @@ class CPUKernel extends Kernel {
1049
1071
}` ;
1050
1072
}
1051
1073
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
-
1070
1074
_resultKernel2DLoop ( kernelString ) {
1071
1075
const {
1072
1076
output
1073
1077
} = this ;
1074
1078
const constructorString = this . _getKernelResultTypeConstructorString ( ) ;
1075
- return `const result = new Array(${ output [ 2 ] } );
1079
+ return `const result = new Array(${ output [ 1 ] } );
1076
1080
${ this . _mapSubKernels ( subKernel => `let subKernelResult_${ subKernel . name } ;` ) . join ( '\n' ) }
1077
1081
${ this . _mapSubKernels ( subKernel => `const result_${ subKernel . name } = new Array(${ output [ 1 ] } );\n` ) . join ( '' ) }
1078
1082
for (let y = 0; y < ${ output [ 1 ] } ; y++) {
@@ -1136,28 +1140,6 @@ class CPUKernel extends Kernel {
1136
1140
}` ;
1137
1141
}
1138
1142
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
-
1161
1143
_kernelOutput ( ) {
1162
1144
if ( ! this . subKernels ) {
1163
1145
return 'return result;' ;
@@ -3585,6 +3567,16 @@ class GLKernel extends Kernel {
3585
3567
}
3586
3568
return zResults ;
3587
3569
}
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
+ }
3588
3580
}
3589
3581
3590
3582
const renderStrategy = Object . freeze ( {
@@ -4071,6 +4063,10 @@ class Kernel {
4071
4063
}
4072
4064
}
4073
4065
4066
+ getPixels ( ) {
4067
+ throw new Error ( `"getPixels" called on ${ this . constructor . name } ` ) ;
4068
+ }
4069
+
4074
4070
checkOutput ( ) {
4075
4071
if ( ! this . output || ! Array . isArray ( this . output ) ) throw new Error ( 'kernel.output not an array' ) ;
4076
4072
if ( this . output . length < 1 ) throw new Error ( 'kernel.output is empty, needs at least 1 value' ) ;
0 commit comments