@@ -1938,6 +1938,30 @@ class WebglGraphicsDevice extends GraphicsDevice {
1938
1938
gl . readPixels ( x , y , w , h , gl . RGBA , gl . UNSIGNED_BYTE , pixels ) ;
1939
1939
}
1940
1940
1941
+ clientWaitAsync ( flags , interval_ms ) {
1942
+ const gl = this . gl ;
1943
+ const sync = gl . fenceSync ( gl . SYNC_GPU_COMMANDS_COMPLETE , 0 ) ;
1944
+ this . submit ( ) ;
1945
+
1946
+ return new Promise ( ( resolve , reject ) => {
1947
+ function test ( ) {
1948
+ const res = gl . clientWaitSync ( sync , flags , 0 ) ;
1949
+ if ( res === gl . TIMEOUT_EXPIRED ) {
1950
+ // check again in a while
1951
+ setTimeout ( test , interval_ms ) ;
1952
+ } else {
1953
+ gl . deleteSync ( sync ) ;
1954
+ if ( res === gl . WAIT_FAILED ) {
1955
+ reject ( new Error ( 'webgl clientWaitSync sync failed' ) ) ;
1956
+ } else {
1957
+ resolve ( ) ;
1958
+ }
1959
+ }
1960
+ }
1961
+ test ( ) ;
1962
+ } ) ;
1963
+ }
1964
+
1941
1965
/**
1942
1966
* Asynchronously reads a block of pixels from a specified rectangle of the current color framebuffer
1943
1967
* into an ArrayBufferView object.
@@ -1953,27 +1977,6 @@ class WebglGraphicsDevice extends GraphicsDevice {
1953
1977
async readPixelsAsync ( x , y , w , h , pixels ) {
1954
1978
const gl = this . gl ;
1955
1979
1956
- const clientWaitAsync = ( flags , interval_ms ) => {
1957
- const sync = gl . fenceSync ( gl . SYNC_GPU_COMMANDS_COMPLETE , 0 ) ;
1958
- this . submit ( ) ;
1959
-
1960
- return new Promise ( ( resolve , reject ) => {
1961
- function test ( ) {
1962
- const res = gl . clientWaitSync ( sync , flags , 0 ) ;
1963
- if ( res === gl . WAIT_FAILED ) {
1964
- gl . deleteSync ( sync ) ;
1965
- reject ( new Error ( 'webgl clientWaitSync sync failed' ) ) ;
1966
- } else if ( res === gl . TIMEOUT_EXPIRED ) {
1967
- setTimeout ( test , interval_ms ) ;
1968
- } else {
1969
- gl . deleteSync ( sync ) ;
1970
- resolve ( ) ;
1971
- }
1972
- }
1973
- test ( ) ;
1974
- } ) ;
1975
- } ;
1976
-
1977
1980
const impl = this . renderTarget . colorBuffer ?. impl ;
1978
1981
const format = impl ?. _glFormat ?? gl . RGBA ;
1979
1982
const pixelType = impl ?. _glPixelType ?? gl . UNSIGNED_BYTE ;
@@ -1986,7 +1989,7 @@ class WebglGraphicsDevice extends GraphicsDevice {
1986
1989
gl . bindBuffer ( gl . PIXEL_PACK_BUFFER , null ) ;
1987
1990
1988
1991
// async wait for previous read to finish
1989
- await clientWaitAsync ( 0 , 20 ) ;
1992
+ await this . clientWaitAsync ( 0 , 16 ) ;
1990
1993
1991
1994
// copy the resulting data once it's arrived
1992
1995
gl . bindBuffer ( gl . PIXEL_PACK_BUFFER , buf ) ;
@@ -2027,6 +2030,27 @@ class WebglGraphicsDevice extends GraphicsDevice {
2027
2030
} ) ;
2028
2031
}
2029
2032
2033
+ async writeTextureAsync ( texture , x , y , width , height , data ) {
2034
+ const gl = this . gl ;
2035
+ const impl = texture . impl ;
2036
+ const format = impl ?. _glFormat ?? gl . RGBA ;
2037
+ const pixelType = impl ?. _glPixelType ?? gl . UNSIGNED_BYTE ;
2038
+
2039
+ // create temporary (gpu-side) buffer and copy data into it
2040
+ const buf = gl . createBuffer ( ) ;
2041
+ gl . bindBuffer ( gl . PIXEL_UNPACK_BUFFER , buf ) ;
2042
+ gl . bufferData ( gl . PIXEL_UNPACK_BUFFER , data , gl . STREAM_DRAW ) ;
2043
+ gl . bindTexture ( gl . TEXTURE_2D , impl . _glTexture ) ;
2044
+ gl . texSubImage2D ( gl . TEXTURE_2D , 0 , x , y , width , height , format , pixelType , 0 ) ;
2045
+ gl . bindBuffer ( gl . PIXEL_UNPACK_BUFFER , null ) ;
2046
+
2047
+ texture . _needsUpload = false ;
2048
+ texture . _mipmapsUploaded = false ;
2049
+
2050
+ // async wait for previous read to finish
2051
+ await this . clientWaitAsync ( 0 , 16 ) ;
2052
+ }
2053
+
2030
2054
/**
2031
2055
* Enables or disables alpha to coverage.
2032
2056
*
0 commit comments