@@ -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
@@ -833,7 +830,7 @@ class Texture {
833830
834831 // Force a full resubmission of the texture to the GPU (used on a context restore event)
835832 dirtyAll ( ) {
836- this . _levelsUpdated = this . cubemap ? [ [ true , true , true , true , true , true ] ] : [ true ] ;
833+ this . _levelsUpdated = ( this . cubemap || this . array ) ? [ Array ( this . _slices ) . fill ( true ) ] : [ true ] ;
837834
838835 this . _needsUpload = true ;
839836 this . _needsMipmapsUpload = this . _mipmaps ;
@@ -850,6 +847,8 @@ class Texture {
850847 * to 0.
851848 * @param {number } [options.face] - If the texture is a cubemap, this is the index of the face
852849 * to lock.
850+ * @param {number } [options.slice] - If the texture is a texture array, this is the index of the
851+ * slice to lock.
853852 * @param {number } [options.mode] - The lock mode. Can be:
854853 * - {@link TEXTURELOCK_READ}
855854 * - {@link TEXTURELOCK_WRITE}
@@ -861,6 +860,7 @@ class Texture {
861860 // Initialize options to some sensible defaults
862861 options . level ??= 0 ;
863862 options . face ??= 0 ;
863+ options . slice ??= 0 ;
864864 options . mode ??= TEXTURELOCK_WRITE ;
865865
866866 Debug . assert (
@@ -875,19 +875,38 @@ class Texture {
875875 this
876876 ) ;
877877
878+ Debug . assert (
879+ options . level >= 0 && options . level < this . _levels . length ,
880+ 'Invalid mip level' ,
881+ this
882+ ) ;
883+
884+ Debug . assert (
885+ ( ( this . cubemap || this . array ) && options . mode === TEXTURELOCK_WRITE ) ? options . level === 0 : true ,
886+ 'Only mip level 0 can be locked for writing for cubemaps and texture arrays' ,
887+ this
888+ ) ;
889+
878890 this . _lockedMode = options . mode ;
879- this . _lockedLevel = options . level ;
880891
881- const levels = this . cubemap ? this . _levels [ options . face ] : this . _levels ;
892+ const levels = this . cubemap ? this . _levels [ options . face ] : this . array ? this . _levels [ options . slice ] : this . _levels ;
882893 if ( levels [ options . level ] === null ) {
883894 // allocate storage for this mip level
884895 const width = Math . max ( 1 , this . _width >> options . level ) ;
885896 const height = Math . max ( 1 , this . _height >> options . level ) ;
886- const depth = Math . max ( 1 , ( this . _dimension === TEXTUREDIMENSION_3D ? this . _slices : 1 ) >> options . level ) ;
897+ const depth = Math . max ( 1 , this . depth >> options . level ) ;
887898 const data = new ArrayBuffer ( TextureUtils . calcLevelGpuSize ( width , height , depth , this . _format ) ) ;
888899 levels [ options . level ] = new ( getPixelFormatArrayType ( this . _format ) ) ( data ) ;
889900 }
890901
902+ if ( this . _lockedMode === TEXTURELOCK_WRITE ) {
903+ if ( this . cubemap || this . array ) {
904+ this . _levelsUpdated [ 0 ] [ options . face ?? options . slice ] = true ;
905+ } else {
906+ this . _levelsUpdated [ 0 ] = true ;
907+ }
908+ }
909+
891910 return levels [ options . level ] ;
892911 }
893912
@@ -897,22 +916,21 @@ class Texture {
897916 *
898917 * @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement|HTMLCanvasElement[]|HTMLImageElement[]|HTMLVideoElement[] } source - A
899918 * canvas, image or video element, or an array of 6 canvas, image or video elements.
900- * @param {number } [mipLevel] - A non-negative integer specifying the image level of detail.
901919 * Defaults to 0, which represents the base image source. A level value of N, that is greater
902920 * than 0, represents the image source for the Nth mipmap reduction level.
903921 * @param {boolean } [immediate] - When set to true it forces an immediate upload upon assignment. Defaults to false.
904922 */
905- setSource ( source , mipLevel = 0 , immediate = false ) {
923+ setSource ( source , immediate = false ) {
906924 let invalid = false ;
907925 let width , height ;
908926
909- if ( this . cubemap ) {
927+ if ( this . cubemap || this . array ) {
910928 if ( source [ 0 ] ) {
911929 // rely on first face sizes
912930 width = source [ 0 ] . width || 0 ;
913931 height = source [ 0 ] . height || 0 ;
914932
915- for ( let i = 0 ; i < 6 ; i ++ ) {
933+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
916934 const face = source [ i ] ;
917935 // cubemap becomes invalid if any condition is not satisfied
918936 if ( ! face || // face is missing
@@ -930,9 +948,9 @@ class Texture {
930948
931949 if ( ! invalid ) {
932950 // mark levels as updated
933- for ( let i = 0 ; i < 6 ; i ++ ) {
934- if ( this . _levels [ mipLevel ] [ i ] !== source [ i ] )
935- this . _levelsUpdated [ mipLevel ] [ i ] = true ;
951+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
952+ if ( this . _levels [ 0 ] [ i ] !== source [ i ] )
953+ this . _levelsUpdated [ 0 ] [ i ] = true ;
936954 }
937955 }
938956 } else {
@@ -942,8 +960,8 @@ class Texture {
942960
943961 if ( ! invalid ) {
944962 // mark level as updated
945- if ( source !== this . _levels [ mipLevel ] )
946- this . _levelsUpdated [ mipLevel ] = true ;
963+ if ( source !== this . _levels [ 0 ] )
964+ this . _levelsUpdated [ 0 ] = true ;
947965
948966 width = source . width ;
949967 height = source . height ;
@@ -958,23 +976,22 @@ class Texture {
958976 this . _height = 4 ;
959977
960978 // remove levels
961- if ( this . cubemap ) {
962- for ( let i = 0 ; i < 6 ; i ++ ) {
963- this . _levels [ mipLevel ] [ i ] = null ;
964- this . _levelsUpdated [ mipLevel ] [ i ] = true ;
979+ if ( this . cubemap || this . array ) {
980+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
981+ this . _levels [ 0 ] [ i ] = null ;
982+ this . _levelsUpdated [ 0 ] [ i ] = true ;
965983 }
966984 } else {
967- this . _levels [ mipLevel ] = null ;
968- this . _levelsUpdated [ mipLevel ] = true ;
985+ this . _levels [ 0 ] = null ;
986+ this . _levelsUpdated [ 0 ] = true ;
969987 }
970988 } else {
971989 // valid texture
972- if ( mipLevel === 0 ) {
973- this . _width = width ;
974- this . _height = height ;
975- }
976990
977- this . _levels [ mipLevel ] = source ;
991+ this . _width = width ;
992+ this . _height = height ;
993+
994+ this . _levels [ 0 ] = source ;
978995 }
979996
980997 // valid or changed state of validity
@@ -990,14 +1007,11 @@ class Texture {
9901007 * Get the pixel data of the texture. If this is a cubemap then an array of 6 images will be
9911008 * returned otherwise a single image.
9921009 *
993- * @param {number } [mipLevel] - A non-negative integer specifying the image level of detail.
994- * Defaults to 0, which represents the base image source. A level value of N, that is greater
995- * than 0, represents the image source for the Nth mipmap reduction level.
9961010 * @returns {HTMLImageElement } The source image of this texture. Can be null if source not
9971011 * assigned for specific image level.
9981012 */
999- getSource ( mipLevel = 0 ) {
1000- return this . _levels [ mipLevel ] ;
1013+ getSource ( ) {
1014+ return this . _levels [ 0 ] ;
10011015 }
10021016
10031017 /**
@@ -1013,7 +1027,6 @@ class Texture {
10131027 if ( this . _lockedMode === TEXTURELOCK_WRITE ) {
10141028 this . upload ( immediate ) ;
10151029 }
1016- this . _lockedLevel = - 1 ;
10171030 this . _lockedMode = TEXTURELOCK_NONE ;
10181031 }
10191032
0 commit comments