@@ -71,9 +71,6 @@ class Texture {
71
71
/** @protected */
72
72
_invalid = false ;
73
73
74
- /** @protected */
75
- _lockedLevel = - 1 ;
76
-
77
74
/** @protected */
78
75
_lockedMode = TEXTURELOCK_NONE ;
79
76
@@ -287,7 +284,7 @@ class Texture {
287
284
if ( this . _levels ) {
288
285
this . upload ( options . immediate ?? false ) ;
289
286
} else {
290
- this . _levels = this . cubemap ? [ [ null , null , null , null , null , null ] ] : [ null ] ;
287
+ this . _levels = ( this . cubemap || this . array ) ? [ Array ( this . _slices ) . fill ( null ) ] : [ null ] ;
291
288
}
292
289
293
290
// track the texture
@@ -826,7 +823,7 @@ class Texture {
826
823
827
824
// Force a full resubmission of the texture to the GPU (used on a context restore event)
828
825
dirtyAll ( ) {
829
- this . _levelsUpdated = this . cubemap ? [ [ true , true , true , true , true , true ] ] : [ true ] ;
826
+ this . _levelsUpdated = ( this . cubemap || this . array ) ? [ Array ( this . _slices ) . fill ( true ) ] : [ true ] ;
830
827
831
828
this . _needsUpload = true ;
832
829
this . _needsMipmapsUpload = this . _mipmaps ;
@@ -843,6 +840,8 @@ class Texture {
843
840
* to 0.
844
841
* @param {number } [options.face] - If the texture is a cubemap, this is the index of the face
845
842
* to lock.
843
+ * @param {number } [options.slice] - If the texture is a texture array, this is the index of the
844
+ * slice to lock.
846
845
* @param {number } [options.mode] - The lock mode. Can be:
847
846
* - {@link TEXTURELOCK_READ}
848
847
* - {@link TEXTURELOCK_WRITE}
@@ -854,6 +853,7 @@ class Texture {
854
853
// Initialize options to some sensible defaults
855
854
options . level ??= 0 ;
856
855
options . face ??= 0 ;
856
+ options . slice ??= 0 ;
857
857
options . mode ??= TEXTURELOCK_WRITE ;
858
858
859
859
Debug . assert (
@@ -868,19 +868,38 @@ class Texture {
868
868
this
869
869
) ;
870
870
871
+ Debug . assert (
872
+ options . level >= 0 && options . level < this . _levels . length ,
873
+ 'Invalid mip level' ,
874
+ this
875
+ ) ;
876
+
877
+ Debug . assert (
878
+ ( ( this . cubemap || this . array ) && options . mode === TEXTURELOCK_WRITE ) ? options . level === 0 : true ,
879
+ 'Only mip level 0 can be locked for writing for cubemaps and texture arrays' ,
880
+ this
881
+ ) ;
882
+
871
883
this . _lockedMode = options . mode ;
872
- this . _lockedLevel = options . level ;
873
884
874
- const levels = this . cubemap ? this . _levels [ options . face ] : this . _levels ;
885
+ const levels = this . cubemap ? this . _levels [ options . face ] : this . array ? this . _levels [ options . slice ] : this . _levels ;
875
886
if ( levels [ options . level ] === null ) {
876
887
// allocate storage for this mip level
877
888
const width = Math . max ( 1 , this . _width >> options . level ) ;
878
889
const height = Math . max ( 1 , this . _height >> options . level ) ;
879
- const depth = Math . max ( 1 , ( this . _dimension === TEXTUREDIMENSION_3D ? this . _slices : 1 ) >> options . level ) ;
890
+ const depth = Math . max ( 1 , this . depth >> options . level ) ;
880
891
const data = new ArrayBuffer ( TextureUtils . calcLevelGpuSize ( width , height , depth , this . _format ) ) ;
881
892
levels [ options . level ] = new ( getPixelFormatArrayType ( this . _format ) ) ( data ) ;
882
893
}
883
894
895
+ if ( this . _lockedMode === TEXTURELOCK_WRITE ) {
896
+ if ( this . cubemap || this . array ) {
897
+ this . _levelsUpdated [ 0 ] [ options . face ?? options . slice ] = true ;
898
+ } else {
899
+ this . _levelsUpdated [ 0 ] = true ;
900
+ }
901
+ }
902
+
884
903
return levels [ options . level ] ;
885
904
}
886
905
@@ -890,22 +909,21 @@ class Texture {
890
909
*
891
910
* @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement|HTMLCanvasElement[]|HTMLImageElement[]|HTMLVideoElement[] } source - A
892
911
* canvas, image or video element, or an array of 6 canvas, image or video elements.
893
- * @param {number } [mipLevel] - A non-negative integer specifying the image level of detail.
894
912
* Defaults to 0, which represents the base image source. A level value of N, that is greater
895
913
* than 0, represents the image source for the Nth mipmap reduction level.
896
914
* @param {boolean } [immediate] - When set to true it forces an immediate upload upon assignment. Defaults to false.
897
915
*/
898
- setSource ( source , mipLevel = 0 , immediate = false ) {
916
+ setSource ( source , immediate = false ) {
899
917
let invalid = false ;
900
918
let width , height ;
901
919
902
- if ( this . cubemap ) {
920
+ if ( this . cubemap || this . array ) {
903
921
if ( source [ 0 ] ) {
904
922
// rely on first face sizes
905
923
width = source [ 0 ] . width || 0 ;
906
924
height = source [ 0 ] . height || 0 ;
907
925
908
- for ( let i = 0 ; i < 6 ; i ++ ) {
926
+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
909
927
const face = source [ i ] ;
910
928
// cubemap becomes invalid if any condition is not satisfied
911
929
if ( ! face || // face is missing
@@ -923,10 +941,9 @@ class Texture {
923
941
924
942
if ( ! invalid ) {
925
943
// mark levels as updated
926
- for ( let i = 0 ; i < 6 ; i ++ ) {
927
- if ( this . _levels [ mipLevel ] [ i ] !== source [ i ] ) {
928
- this . _levelsUpdated [ mipLevel ] [ i ] = true ;
929
- }
944
+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
945
+ if ( this . _levels [ 0 ] [ i ] !== source [ i ] )
946
+ this . _levelsUpdated [ 0 ] [ i ] = true ;
930
947
}
931
948
}
932
949
} else {
@@ -937,9 +954,8 @@ class Texture {
937
954
938
955
if ( ! invalid ) {
939
956
// mark level as updated
940
- if ( source !== this . _levels [ mipLevel ] ) {
941
- this . _levelsUpdated [ mipLevel ] = true ;
942
- }
957
+ if ( source !== this . _levels [ 0 ] )
958
+ this . _levelsUpdated [ 0 ] = true ;
943
959
944
960
width = source . width ;
945
961
height = source . height ;
@@ -954,23 +970,22 @@ class Texture {
954
970
this . _height = 4 ;
955
971
956
972
// remove levels
957
- if ( this . cubemap ) {
958
- for ( let i = 0 ; i < 6 ; i ++ ) {
959
- this . _levels [ mipLevel ] [ i ] = null ;
960
- this . _levelsUpdated [ mipLevel ] [ i ] = true ;
973
+ if ( this . cubemap || this . array ) {
974
+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
975
+ this . _levels [ 0 ] [ i ] = null ;
976
+ this . _levelsUpdated [ 0 ] [ i ] = true ;
961
977
}
962
978
} else {
963
- this . _levels [ mipLevel ] = null ;
964
- this . _levelsUpdated [ mipLevel ] = true ;
979
+ this . _levels [ 0 ] = null ;
980
+ this . _levelsUpdated [ 0 ] = true ;
965
981
}
966
982
} else {
967
983
// valid texture
968
- if ( mipLevel === 0 ) {
969
- this . _width = width ;
970
- this . _height = height ;
971
- }
972
984
973
- this . _levels [ mipLevel ] = source ;
985
+ this . _width = width ;
986
+ this . _height = height ;
987
+
988
+ this . _levels [ 0 ] = source ;
974
989
}
975
990
976
991
// valid or changed state of validity
@@ -986,14 +1001,11 @@ class Texture {
986
1001
* Get the pixel data of the texture. If this is a cubemap then an array of 6 images will be
987
1002
* returned otherwise a single image.
988
1003
*
989
- * @param {number } [mipLevel] - A non-negative integer specifying the image level of detail.
990
- * Defaults to 0, which represents the base image source. A level value of N, that is greater
991
- * than 0, represents the image source for the Nth mipmap reduction level.
992
1004
* @returns {HTMLImageElement } The source image of this texture. Can be null if source not
993
1005
* assigned for specific image level.
994
1006
*/
995
- getSource ( mipLevel = 0 ) {
996
- return this . _levels [ mipLevel ] ;
1007
+ getSource ( ) {
1008
+ return this . _levels [ 0 ] ;
997
1009
}
998
1010
999
1011
/**
@@ -1009,7 +1021,6 @@ class Texture {
1009
1021
if ( this . _lockedMode === TEXTURELOCK_WRITE ) {
1010
1022
this . upload ( immediate ) ;
1011
1023
}
1012
- this . _lockedLevel = - 1 ;
1013
1024
this . _lockedMode = TEXTURELOCK_NONE ;
1014
1025
}
1015
1026
0 commit comments