@@ -78,9 +78,6 @@ class Texture {
78
78
/** @protected */
79
79
_invalid = false ;
80
80
81
- /** @protected */
82
- _lockedLevel = - 1 ;
83
-
84
81
/** @protected */
85
82
_lockedMode = TEXTURELOCK_NONE ;
86
83
@@ -295,7 +292,7 @@ class Texture {
295
292
if ( this . _levels ) {
296
293
this . upload ( options . immediate ?? false ) ;
297
294
} 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 ] ;
299
296
}
300
297
301
298
// track the texture
@@ -787,7 +784,7 @@ class Texture {
787
784
788
785
// Force a full resubmission of the texture to the GPU (used on a context restore event)
789
786
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 ] ;
791
788
792
789
this . _needsUpload = true ;
793
790
this . _needsMipmapsUpload = this . _mipmaps ;
@@ -804,6 +801,8 @@ class Texture {
804
801
* to 0.
805
802
* @param {number } [options.face] - If the texture is a cubemap, this is the index of the face
806
803
* to lock.
804
+ * @param {number } [options.slice] - If the texture is a texture array, this is the index of the
805
+ * slice to lock.
807
806
* @param {number } [options.mode] - The lock mode. Can be:
808
807
* - {@link TEXTURELOCK_READ}
809
808
* - {@link TEXTURELOCK_WRITE}
@@ -815,6 +814,7 @@ class Texture {
815
814
// Initialize options to some sensible defaults
816
815
options . level ??= 0 ;
817
816
options . face ??= 0 ;
817
+ options . slice ??= 0 ;
818
818
options . mode ??= TEXTURELOCK_WRITE ;
819
819
820
820
Debug . assert (
@@ -829,19 +829,38 @@ class Texture {
829
829
this
830
830
) ;
831
831
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
+
832
844
this . _lockedMode = options . mode ;
833
- this . _lockedLevel = options . level ;
834
845
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 ;
836
847
if ( levels [ options . level ] === null ) {
837
848
// allocate storage for this mip level
838
849
const width = Math . max ( 1 , this . _width >> options . level ) ;
839
850
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 ) ;
841
852
const data = new ArrayBuffer ( TextureUtils . calcLevelGpuSize ( width , height , depth , this . _format ) ) ;
842
853
levels [ options . level ] = new ( getPixelFormatArrayType ( this . _format ) ) ( data ) ;
843
854
}
844
855
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
+
845
864
return levels [ options . level ] ;
846
865
}
847
866
@@ -851,22 +870,21 @@ class Texture {
851
870
*
852
871
* @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement|HTMLCanvasElement[]|HTMLImageElement[]|HTMLVideoElement[] } source - A
853
872
* 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.
855
873
* Defaults to 0, which represents the base image source. A level value of N, that is greater
856
874
* than 0, represents the image source for the Nth mipmap reduction level.
857
875
* @param {boolean } [immediate] - When set to true it forces an immediate upload upon assignment. Defaults to false.
858
876
*/
859
- setSource ( source , mipLevel = 0 , immediate = false ) {
877
+ setSource ( source , immediate = false ) {
860
878
let invalid = false ;
861
879
let width , height ;
862
880
863
- if ( this . cubemap ) {
881
+ if ( this . cubemap || this . array ) {
864
882
if ( source [ 0 ] ) {
865
883
// rely on first face sizes
866
884
width = source [ 0 ] . width || 0 ;
867
885
height = source [ 0 ] . height || 0 ;
868
886
869
- for ( let i = 0 ; i < 6 ; i ++ ) {
887
+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
870
888
const face = source [ i ] ;
871
889
// cubemap becomes invalid if any condition is not satisfied
872
890
if ( ! face || // face is missing
@@ -884,9 +902,9 @@ class Texture {
884
902
885
903
if ( ! invalid ) {
886
904
// 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 ;
890
908
}
891
909
}
892
910
} else {
@@ -896,8 +914,8 @@ class Texture {
896
914
897
915
if ( ! invalid ) {
898
916
// 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 ;
901
919
902
920
width = source . width ;
903
921
height = source . height ;
@@ -912,23 +930,22 @@ class Texture {
912
930
this . _height = 4 ;
913
931
914
932
// 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 ;
919
937
}
920
938
} else {
921
- this . _levels [ mipLevel ] = null ;
922
- this . _levelsUpdated [ mipLevel ] = true ;
939
+ this . _levels [ 0 ] = null ;
940
+ this . _levelsUpdated [ 0 ] = true ;
923
941
}
924
942
} else {
925
943
// valid texture
926
- if ( mipLevel === 0 ) {
927
- this . _width = width ;
928
- this . _height = height ;
929
- }
930
944
931
- this . _levels [ mipLevel ] = source ;
945
+ this . _width = width ;
946
+ this . _height = height ;
947
+
948
+ this . _levels [ 0 ] = source ;
932
949
}
933
950
934
951
// valid or changed state of validity
@@ -944,14 +961,11 @@ class Texture {
944
961
* Get the pixel data of the texture. If this is a cubemap then an array of 6 images will be
945
962
* returned otherwise a single image.
946
963
*
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.
950
964
* @returns {HTMLImageElement } The source image of this texture. Can be null if source not
951
965
* assigned for specific image level.
952
966
*/
953
- getSource ( mipLevel = 0 ) {
954
- return this . _levels [ mipLevel ] ;
967
+ getSource ( ) {
968
+ return this . _levels [ 0 ] ;
955
969
}
956
970
957
971
/**
@@ -967,7 +981,6 @@ class Texture {
967
981
if ( this . _lockedMode === TEXTURELOCK_WRITE ) {
968
982
this . upload ( immediate ) ;
969
983
}
970
- this . _lockedLevel = - 1 ;
971
984
this . _lockedMode = TEXTURELOCK_NONE ;
972
985
}
973
986
0 commit comments