@@ -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
@@ -787,7 +784,7 @@ class Texture {
787784
788785 // Force a full resubmission of the texture to the GPU (used on a context restore event)
789786 dirtyAll ( ) {
790- this . _levelsUpdated = this . cubemap ? [ [ true , true , true , true , true , true ] ] : [ true ] ;
787+ this . _levelsUpdated = ( this . cubemap || this . array ) ? [ Array ( this . _slices ) . fill ( true ) ] : [ true ] ;
791788
792789 this . _needsUpload = true ;
793790 this . _needsMipmapsUpload = this . _mipmaps ;
@@ -804,6 +801,8 @@ class Texture {
804801 * to 0.
805802 * @param {number } [options.face] - If the texture is a cubemap, this is the index of the face
806803 * to lock.
804+ * @param {number } [options.slice] - If the texture is a texture array, this is the index of the
805+ * slice to lock.
807806 * @param {number } [options.mode] - The lock mode. Can be:
808807 * - {@link TEXTURELOCK_READ}
809808 * - {@link TEXTURELOCK_WRITE}
@@ -815,6 +814,7 @@ class Texture {
815814 // Initialize options to some sensible defaults
816815 options . level ??= 0 ;
817816 options . face ??= 0 ;
817+ options . slice ??= 0 ;
818818 options . mode ??= TEXTURELOCK_WRITE ;
819819
820820 Debug . assert (
@@ -829,19 +829,38 @@ class Texture {
829829 this
830830 ) ;
831831
832+ Debug . assert (
833+ options . level >= 0 && options . level < this . _levels . length ,
834+ 'Invalid mip level' ,
835+ this
836+ ) ;
837+
838+ Debug . assert (
839+ ( ( this . cubemap || this . array ) && options . mode === TEXTURELOCK_WRITE ) ? options . level === 0 : true ,
840+ 'Only mip level 0 can be locked for writing for cubemaps and texture arrays' ,
841+ this
842+ ) ;
843+
832844 this . _lockedMode = options . mode ;
833- this . _lockedLevel = options . level ;
834845
835- const levels = this . cubemap ? this . _levels [ options . face ] : this . _levels ;
846+ const levels = this . cubemap ? this . _levels [ options . face ] : this . array ? this . _levels [ options . slice ] : this . _levels ;
836847 if ( levels [ options . level ] === null ) {
837848 // allocate storage for this mip level
838849 const width = Math . max ( 1 , this . _width >> options . level ) ;
839850 const height = Math . max ( 1 , this . _height >> options . level ) ;
840- const depth = Math . max ( 1 , ( this . _dimension === TEXTUREDIMENSION_3D ? this . _slices : 1 ) >> options . level ) ;
851+ const depth = Math . max ( 1 , this . depth >> options . level ) ;
841852 const data = new ArrayBuffer ( TextureUtils . calcLevelGpuSize ( width , height , depth , this . _format ) ) ;
842853 levels [ options . level ] = new ( getPixelFormatArrayType ( this . _format ) ) ( data ) ;
843854 }
844855
856+ if ( this . _lockedMode === TEXTURELOCK_WRITE ) {
857+ if ( this . cubemap || this . array ) {
858+ this . _levelsUpdated [ 0 ] [ options . face ?? options . slice ] = true ;
859+ } else {
860+ this . _levelsUpdated [ 0 ] = true ;
861+ }
862+ }
863+
845864 return levels [ options . level ] ;
846865 }
847866
@@ -851,22 +870,21 @@ class Texture {
851870 *
852871 * @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement|HTMLCanvasElement[]|HTMLImageElement[]|HTMLVideoElement[] } source - A
853872 * canvas, image or video element, or an array of 6 canvas, image or video elements.
854- * @param {number } [mipLevel] - A non-negative integer specifying the image level of detail.
855873 * Defaults to 0, which represents the base image source. A level value of N, that is greater
856874 * than 0, represents the image source for the Nth mipmap reduction level.
857875 * @param {boolean } [immediate] - When set to true it forces an immediate upload upon assignment. Defaults to false.
858876 */
859- setSource ( source , mipLevel = 0 , immediate = false ) {
877+ setSource ( source , immediate = false ) {
860878 let invalid = false ;
861879 let width , height ;
862880
863- if ( this . cubemap ) {
881+ if ( this . cubemap || this . array ) {
864882 if ( source [ 0 ] ) {
865883 // rely on first face sizes
866884 width = source [ 0 ] . width || 0 ;
867885 height = source [ 0 ] . height || 0 ;
868886
869- for ( let i = 0 ; i < 6 ; i ++ ) {
887+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
870888 const face = source [ i ] ;
871889 // cubemap becomes invalid if any condition is not satisfied
872890 if ( ! face || // face is missing
@@ -884,9 +902,9 @@ class Texture {
884902
885903 if ( ! invalid ) {
886904 // mark levels as updated
887- for ( let i = 0 ; i < 6 ; i ++ ) {
888- if ( this . _levels [ mipLevel ] [ i ] !== source [ i ] )
889- this . _levelsUpdated [ mipLevel ] [ i ] = true ;
905+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
906+ if ( this . _levels [ 0 ] [ i ] !== source [ i ] )
907+ this . _levelsUpdated [ 0 ] [ i ] = true ;
890908 }
891909 }
892910 } else {
@@ -896,8 +914,8 @@ class Texture {
896914
897915 if ( ! invalid ) {
898916 // mark level as updated
899- if ( source !== this . _levels [ mipLevel ] )
900- this . _levelsUpdated [ mipLevel ] = true ;
917+ if ( source !== this . _levels [ 0 ] )
918+ this . _levelsUpdated [ 0 ] = true ;
901919
902920 width = source . width ;
903921 height = source . height ;
@@ -912,23 +930,22 @@ class Texture {
912930 this . _height = 4 ;
913931
914932 // remove levels
915- if ( this . cubemap ) {
916- for ( let i = 0 ; i < 6 ; i ++ ) {
917- this . _levels [ mipLevel ] [ i ] = null ;
918- this . _levelsUpdated [ mipLevel ] [ i ] = true ;
933+ if ( this . cubemap || this . array ) {
934+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
935+ this . _levels [ 0 ] [ i ] = null ;
936+ this . _levelsUpdated [ 0 ] [ i ] = true ;
919937 }
920938 } else {
921- this . _levels [ mipLevel ] = null ;
922- this . _levelsUpdated [ mipLevel ] = true ;
939+ this . _levels [ 0 ] = null ;
940+ this . _levelsUpdated [ 0 ] = true ;
923941 }
924942 } else {
925943 // valid texture
926- if ( mipLevel === 0 ) {
927- this . _width = width ;
928- this . _height = height ;
929- }
930944
931- this . _levels [ mipLevel ] = source ;
945+ this . _width = width ;
946+ this . _height = height ;
947+
948+ this . _levels [ 0 ] = source ;
932949 }
933950
934951 // valid or changed state of validity
@@ -944,14 +961,11 @@ class Texture {
944961 * Get the pixel data of the texture. If this is a cubemap then an array of 6 images will be
945962 * returned otherwise a single image.
946963 *
947- * @param {number } [mipLevel] - A non-negative integer specifying the image level of detail.
948- * Defaults to 0, which represents the base image source. A level value of N, that is greater
949- * than 0, represents the image source for the Nth mipmap reduction level.
950964 * @returns {HTMLImageElement } The source image of this texture. Can be null if source not
951965 * assigned for specific image level.
952966 */
953- getSource ( mipLevel = 0 ) {
954- return this . _levels [ mipLevel ] ;
967+ getSource ( ) {
968+ return this . _levels [ 0 ] ;
955969 }
956970
957971 /**
@@ -967,7 +981,6 @@ class Texture {
967981 if ( this . _lockedMode === TEXTURELOCK_WRITE ) {
968982 this . upload ( immediate ) ;
969983 }
970- this . _lockedLevel = - 1 ;
971984 this . _lockedMode = TEXTURELOCK_NONE ;
972985 }
973986
0 commit comments