@@ -81,9 +81,6 @@ class Texture {
8181 /** @protected */
8282 _invalid = false ;
8383
84- /** @protected */
85- _lockedLevel = - 1 ;
86-
8784 /** @protected */
8885 _lockedMode = TEXTURELOCK_NONE ;
8986
@@ -297,7 +294,7 @@ class Texture {
297294 if ( this . _levels ) {
298295 this . upload ( options . immediate ?? false ) ;
299296 } else {
300- this . _levels = this . cubemap ? [ [ null , null , null , null , null , null ] ] : [ null ] ;
297+ this . _levels = ( this . cubemap || this . array ) ? [ Array ( this . _slices ) . fill ( null ) ] : [ null ] ;
301298 }
302299
303300 // track the texture
@@ -836,7 +833,7 @@ class Texture {
836833
837834 // Force a full resubmission of the texture to the GPU (used on a context restore event)
838835 dirtyAll ( ) {
839- this . _levelsUpdated = this . cubemap ? [ [ true , true , true , true , true , true ] ] : [ true ] ;
836+ this . _levelsUpdated = ( this . cubemap || this . array ) ? [ Array ( this . _slices ) . fill ( true ) ] : [ true ] ;
840837
841838 this . _needsUpload = true ;
842839 this . _needsMipmapsUpload = this . _mipmaps ;
@@ -853,6 +850,8 @@ class Texture {
853850 * to 0.
854851 * @param {number } [options.face] - If the texture is a cubemap, this is the index of the face
855852 * to lock.
853+ * @param {number } [options.slice] - If the texture is a texture array, this is the index of the
854+ * slice to lock.
856855 * @param {number } [options.mode] - The lock mode. Can be:
857856 * - {@link TEXTURELOCK_READ}
858857 * - {@link TEXTURELOCK_WRITE}
@@ -864,6 +863,7 @@ class Texture {
864863 // Initialize options to some sensible defaults
865864 options . level ??= 0 ;
866865 options . face ??= 0 ;
866+ options . slice ??= 0 ;
867867 options . mode ??= TEXTURELOCK_WRITE ;
868868
869869 Debug . assert (
@@ -878,19 +878,38 @@ class Texture {
878878 this
879879 ) ;
880880
881+ Debug . assert (
882+ options . level >= 0 && options . level < this . _levels . length ,
883+ 'Invalid mip level' ,
884+ this
885+ ) ;
886+
887+ Debug . assert (
888+ ( ( this . cubemap || this . array ) && options . mode === TEXTURELOCK_WRITE ) ? options . level === 0 : true ,
889+ 'Only mip level 0 can be locked for writing for cubemaps and texture arrays' ,
890+ this
891+ ) ;
892+
881893 this . _lockedMode = options . mode ;
882- this . _lockedLevel = options . level ;
883894
884- const levels = this . cubemap ? this . _levels [ options . face ] : this . _levels ;
895+ const levels = this . cubemap ? this . _levels [ options . face ] : this . array ? this . _levels [ options . slice ] : this . _levels ;
885896 if ( levels [ options . level ] === null ) {
886897 // allocate storage for this mip level
887898 const width = Math . max ( 1 , this . _width >> options . level ) ;
888899 const height = Math . max ( 1 , this . _height >> options . level ) ;
889- const depth = Math . max ( 1 , ( this . _dimension === TEXTUREDIMENSION_3D ? this . _slices : 1 ) >> options . level ) ;
900+ const depth = Math . max ( 1 , this . depth >> options . level ) ;
890901 const data = new ArrayBuffer ( TextureUtils . calcLevelGpuSize ( width , height , depth , this . _format ) ) ;
891902 levels [ options . level ] = new ( getPixelFormatArrayType ( this . _format ) ) ( data ) ;
892903 }
893904
905+ if ( this . _lockedMode === TEXTURELOCK_WRITE ) {
906+ if ( this . cubemap || this . array ) {
907+ this . _levelsUpdated [ 0 ] [ options . face ?? options . slice ] = true ;
908+ } else {
909+ this . _levelsUpdated [ 0 ] = true ;
910+ }
911+ }
912+
894913 return levels [ options . level ] ;
895914 }
896915
@@ -900,22 +919,21 @@ class Texture {
900919 *
901920 * @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement|HTMLCanvasElement[]|HTMLImageElement[]|HTMLVideoElement[] } source - A
902921 * canvas, image or video element, or an array of 6 canvas, image or video elements.
903- * @param {number } [mipLevel] - A non-negative integer specifying the image level of detail.
904922 * Defaults to 0, which represents the base image source. A level value of N, that is greater
905923 * than 0, represents the image source for the Nth mipmap reduction level.
906924 * @param {boolean } [immediate] - When set to true it forces an immediate upload upon assignment. Defaults to false.
907925 */
908- setSource ( source , mipLevel = 0 , immediate = false ) {
926+ setSource ( source , immediate = false ) {
909927 let invalid = false ;
910928 let width , height ;
911929
912- if ( this . cubemap ) {
930+ if ( this . cubemap || this . array ) {
913931 if ( source [ 0 ] ) {
914932 // rely on first face sizes
915933 width = source [ 0 ] . width || 0 ;
916934 height = source [ 0 ] . height || 0 ;
917935
918- for ( let i = 0 ; i < 6 ; i ++ ) {
936+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
919937 const face = source [ i ] ;
920938 // cubemap becomes invalid if any condition is not satisfied
921939 if ( ! face || // face is missing
@@ -933,9 +951,9 @@ class Texture {
933951
934952 if ( ! invalid ) {
935953 // mark levels as updated
936- for ( let i = 0 ; i < 6 ; i ++ ) {
937- if ( this . _levels [ mipLevel ] [ i ] !== source [ i ] )
938- this . _levelsUpdated [ mipLevel ] [ i ] = true ;
954+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
955+ if ( this . _levels [ 0 ] [ i ] !== source [ i ] )
956+ this . _levelsUpdated [ 0 ] [ i ] = true ;
939957 }
940958 }
941959 } else {
@@ -945,8 +963,8 @@ class Texture {
945963
946964 if ( ! invalid ) {
947965 // mark level as updated
948- if ( source !== this . _levels [ mipLevel ] )
949- this . _levelsUpdated [ mipLevel ] = true ;
966+ if ( source !== this . _levels [ 0 ] )
967+ this . _levelsUpdated [ 0 ] = true ;
950968
951969 width = source . width ;
952970 height = source . height ;
@@ -961,23 +979,22 @@ class Texture {
961979 this . _height = 4 ;
962980
963981 // remove levels
964- if ( this . cubemap ) {
965- for ( let i = 0 ; i < 6 ; i ++ ) {
966- this . _levels [ mipLevel ] [ i ] = null ;
967- this . _levelsUpdated [ mipLevel ] [ i ] = true ;
982+ if ( this . cubemap || this . array ) {
983+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
984+ this . _levels [ 0 ] [ i ] = null ;
985+ this . _levelsUpdated [ 0 ] [ i ] = true ;
968986 }
969987 } else {
970- this . _levels [ mipLevel ] = null ;
971- this . _levelsUpdated [ mipLevel ] = true ;
988+ this . _levels [ 0 ] = null ;
989+ this . _levelsUpdated [ 0 ] = true ;
972990 }
973991 } else {
974992 // valid texture
975- if ( mipLevel === 0 ) {
976- this . _width = width ;
977- this . _height = height ;
978- }
979993
980- this . _levels [ mipLevel ] = source ;
994+ this . _width = width ;
995+ this . _height = height ;
996+
997+ this . _levels [ 0 ] = source ;
981998 }
982999
9831000 // valid or changed state of validity
@@ -993,14 +1010,11 @@ class Texture {
9931010 * Get the pixel data of the texture. If this is a cubemap then an array of 6 images will be
9941011 * returned otherwise a single image.
9951012 *
996- * @param {number } [mipLevel] - A non-negative integer specifying the image level of detail.
997- * Defaults to 0, which represents the base image source. A level value of N, that is greater
998- * than 0, represents the image source for the Nth mipmap reduction level.
9991013 * @returns {HTMLImageElement } The source image of this texture. Can be null if source not
10001014 * assigned for specific image level.
10011015 */
1002- getSource ( mipLevel = 0 ) {
1003- return this . _levels [ mipLevel ] ;
1016+ getSource ( ) {
1017+ return this . _levels [ 0 ] ;
10041018 }
10051019
10061020 /**
@@ -1016,7 +1030,6 @@ class Texture {
10161030 if ( this . _lockedMode === TEXTURELOCK_WRITE ) {
10171031 this . upload ( immediate ) ;
10181032 }
1019- this . _lockedLevel = - 1 ;
10201033 this . _lockedMode = TEXTURELOCK_NONE ;
10211034 }
10221035
0 commit comments