@@ -78,9 +78,6 @@ class Texture {
7878 /** @protected */
7979 _invalid = false ;
8080
81- /** @protected */
82- _lockedLevel = - 1 ;
83-
8481 /** @protected */
8582 _lockedMode = TEXTURELOCK_NONE ;
8683
@@ -295,7 +292,7 @@ class Texture {
295292 if ( this . _levels ) {
296293 this . upload ( options . immediate ?? false ) ;
297294 } else {
298- this . _levels = this . cubemap ? [ [ null , null , null , null , null , null ] ] : [ null ] ;
295+ this . _levels = ( this . cubemap || this . array ) ? [ Array ( this . _slices ) . fill ( null ) ] : [ null ] ;
299296 }
300297
301298 // track the texture
@@ -837,7 +834,7 @@ class Texture {
837834
838835 // Force a full resubmission of the texture to the GPU (used on a context restore event)
839836 dirtyAll ( ) {
840- this . _levelsUpdated = this . cubemap ? [ [ true , true , true , true , true , true ] ] : [ true ] ;
837+ this . _levelsUpdated = ( this . cubemap || this . array ) ? [ Array ( this . _slices ) . fill ( true ) ] : [ true ] ;
841838
842839 this . _needsUpload = true ;
843840 this . _needsMipmapsUpload = this . _mipmaps ;
@@ -854,6 +851,8 @@ class Texture {
854851 * to 0.
855852 * @param {number } [options.face] - If the texture is a cubemap, this is the index of the face
856853 * to lock.
854+ * @param {number } [options.slice] - If the texture is a texture array, this is the index of the
855+ * slice to lock.
857856 * @param {number } [options.mode] - The lock mode. Can be:
858857 * - {@link TEXTURELOCK_READ}
859858 * - {@link TEXTURELOCK_WRITE}
@@ -865,6 +864,7 @@ class Texture {
865864 // Initialize options to some sensible defaults
866865 options . level ??= 0 ;
867866 options . face ??= 0 ;
867+ options . slice ??= 0 ;
868868 options . mode ??= TEXTURELOCK_WRITE ;
869869
870870 Debug . assert (
@@ -879,19 +879,38 @@ class Texture {
879879 this
880880 ) ;
881881
882+ Debug . assert (
883+ options . level >= 0 && options . level < this . _levels . length ,
884+ 'Invalid mip level' ,
885+ this
886+ ) ;
887+
888+ Debug . assert (
889+ ( ( this . cubemap || this . array ) && options . mode === TEXTURELOCK_WRITE ) ? options . level === 0 : true ,
890+ 'Only mip level 0 can be locked for writing for cubemaps and texture arrays' ,
891+ this
892+ ) ;
893+
882894 this . _lockedMode = options . mode ;
883- this . _lockedLevel = options . level ;
884895
885- const levels = this . cubemap ? this . _levels [ options . face ] : this . _levels ;
896+ const levels = this . cubemap ? this . _levels [ options . face ] : this . array ? this . _levels [ options . slice ] : this . _levels ;
886897 if ( levels [ options . level ] === null ) {
887898 // allocate storage for this mip level
888899 const width = Math . max ( 1 , this . _width >> options . level ) ;
889900 const height = Math . max ( 1 , this . _height >> options . level ) ;
890- const depth = Math . max ( 1 , ( this . _dimension === TEXTUREDIMENSION_3D ? this . _slices : 1 ) >> options . level ) ;
901+ const depth = Math . max ( 1 , this . depth >> options . level ) ;
891902 const data = new ArrayBuffer ( TextureUtils . calcLevelGpuSize ( width , height , depth , this . _format ) ) ;
892903 levels [ options . level ] = new ( getPixelFormatArrayType ( this . _format ) ) ( data ) ;
893904 }
894905
906+ if ( this . _lockedMode === TEXTURELOCK_WRITE ) {
907+ if ( this . cubemap || this . array ) {
908+ this . _levelsUpdated [ 0 ] [ options . face ?? options . slice ] = true ;
909+ } else {
910+ this . _levelsUpdated [ 0 ] = true ;
911+ }
912+ }
913+
895914 return levels [ options . level ] ;
896915 }
897916
@@ -901,22 +920,21 @@ class Texture {
901920 *
902921 * @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement|HTMLCanvasElement[]|HTMLImageElement[]|HTMLVideoElement[] } source - A
903922 * canvas, image or video element, or an array of 6 canvas, image or video elements.
904- * @param {number } [mipLevel] - A non-negative integer specifying the image level of detail.
905923 * Defaults to 0, which represents the base image source. A level value of N, that is greater
906924 * than 0, represents the image source for the Nth mipmap reduction level.
907925 * @param {boolean } [immediate] - When set to true it forces an immediate upload upon assignment. Defaults to false.
908926 */
909- setSource ( source , mipLevel = 0 , immediate = false ) {
927+ setSource ( source , immediate = false ) {
910928 let invalid = false ;
911929 let width , height ;
912930
913- if ( this . cubemap ) {
931+ if ( this . cubemap || this . array ) {
914932 if ( source [ 0 ] ) {
915933 // rely on first face sizes
916934 width = source [ 0 ] . width || 0 ;
917935 height = source [ 0 ] . height || 0 ;
918936
919- for ( let i = 0 ; i < 6 ; i ++ ) {
937+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
920938 const face = source [ i ] ;
921939 // cubemap becomes invalid if any condition is not satisfied
922940 if ( ! face || // face is missing
@@ -934,9 +952,9 @@ class Texture {
934952
935953 if ( ! invalid ) {
936954 // mark levels as updated
937- for ( let i = 0 ; i < 6 ; i ++ ) {
938- if ( this . _levels [ mipLevel ] [ i ] !== source [ i ] )
939- this . _levelsUpdated [ mipLevel ] [ i ] = true ;
955+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
956+ if ( this . _levels [ 0 ] [ i ] !== source [ i ] )
957+ this . _levelsUpdated [ 0 ] [ i ] = true ;
940958 }
941959 }
942960 } else {
@@ -946,8 +964,8 @@ class Texture {
946964
947965 if ( ! invalid ) {
948966 // mark level as updated
949- if ( source !== this . _levels [ mipLevel ] )
950- this . _levelsUpdated [ mipLevel ] = true ;
967+ if ( source !== this . _levels [ 0 ] )
968+ this . _levelsUpdated [ 0 ] = true ;
951969
952970 width = source . width ;
953971 height = source . height ;
@@ -962,23 +980,22 @@ class Texture {
962980 this . _height = 4 ;
963981
964982 // remove levels
965- if ( this . cubemap ) {
966- for ( let i = 0 ; i < 6 ; i ++ ) {
967- this . _levels [ mipLevel ] [ i ] = null ;
968- this . _levelsUpdated [ mipLevel ] [ i ] = true ;
983+ if ( this . cubemap || this . array ) {
984+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
985+ this . _levels [ 0 ] [ i ] = null ;
986+ this . _levelsUpdated [ 0 ] [ i ] = true ;
969987 }
970988 } else {
971- this . _levels [ mipLevel ] = null ;
972- this . _levelsUpdated [ mipLevel ] = true ;
989+ this . _levels [ 0 ] = null ;
990+ this . _levelsUpdated [ 0 ] = true ;
973991 }
974992 } else {
975993 // valid texture
976- if ( mipLevel === 0 ) {
977- this . _width = width ;
978- this . _height = height ;
979- }
980994
981- this . _levels [ mipLevel ] = source ;
995+ this . _width = width ;
996+ this . _height = height ;
997+
998+ this . _levels [ 0 ] = source ;
982999 }
9831000
9841001 // valid or changed state of validity
@@ -994,14 +1011,11 @@ class Texture {
9941011 * Get the pixel data of the texture. If this is a cubemap then an array of 6 images will be
9951012 * returned otherwise a single image.
9961013 *
997- * @param {number } [mipLevel] - A non-negative integer specifying the image level of detail.
998- * Defaults to 0, which represents the base image source. A level value of N, that is greater
999- * than 0, represents the image source for the Nth mipmap reduction level.
10001014 * @returns {HTMLImageElement } The source image of this texture. Can be null if source not
10011015 * assigned for specific image level.
10021016 */
1003- getSource ( mipLevel = 0 ) {
1004- return this . _levels [ mipLevel ] ;
1017+ getSource ( ) {
1018+ return this . _levels [ 0 ] ;
10051019 }
10061020
10071021 /**
@@ -1017,7 +1031,6 @@ class Texture {
10171031 if ( this . _lockedMode === TEXTURELOCK_WRITE ) {
10181032 this . upload ( immediate ) ;
10191033 }
1020- this . _lockedLevel = - 1 ;
10211034 this . _lockedMode = TEXTURELOCK_NONE ;
10221035 }
10231036
0 commit comments