Skip to content

Commit

Permalink
read tex async (#27006)
Browse files Browse the repository at this point in the history
Co-authored-by: aardgoose <angus.sawyer@email.com>
  • Loading branch information
aardgoose and aardgoose committed Nov 28, 2023
1 parent 0f70ecc commit 3b86f57
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 2 deletions.
4 changes: 2 additions & 2 deletions examples/jsm/renderers/webgl/WebGLBackend.js
Original file line number Diff line number Diff line change
Expand Up @@ -605,9 +605,9 @@ class WebGLBackend extends Backend {

}

copyTextureToBuffer( /*texture, x, y, width, height*/ ) {
copyTextureToBuffer( texture, x, y, width, height ) {

console.warn( 'Abstract class.' );
return this.textureUtils.copyTextureToBuffer( texture, x, y, width, height );

}

Expand Down
103 changes: 103 additions & 0 deletions examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,109 @@ class WebGLTextureUtils {

}

async copyTextureToBuffer( texture, x, y, width, height ) {

const { gl } = this;

const { textureGPU, glFormat, glType } = this.backend.get( texture );

const fb = gl.createFramebuffer();

gl.bindFramebuffer( gl.READ_FRAMEBUFFER, fb );
gl.framebufferTexture2D( gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textureGPU, 0 );

const typedArrayType = this._getTypedArrayType( glType );
const bytesPerTexel = this._getBytesPerTexel( glFormat );

const elementCount = width * height;
const byteLength = elementCount * bytesPerTexel;

const buffer = gl.createBuffer();

gl.bindBuffer( gl.PIXEL_PACK_BUFFER, buffer );
gl.bufferData( gl.PIXEL_PACK_BUFFER, byteLength, gl.STREAM_READ );
gl.readPixels( x, y, width, height, glFormat, glType, 0 );
gl.bindBuffer( gl.PIXEL_PACK_BUFFER, null );

const sync = gl.fenceSync( gl.SYNC_GPU_COMMANDS_COMPLETE, 0 );

gl.flush();

await this._clientWaitAsync( sync );

gl.deleteSync( sync );

const dstBuffer = new typedArrayType( elementCount );

gl.bindBuffer( gl.PIXEL_PACK_BUFFER, buffer );
gl.getBufferSubData( gl.PIXEL_PACK_BUFFER, 0, dstBuffer );
gl.bindBuffer( gl.PIXEL_PACK_BUFFER, null );

return dstBuffer;

}

_getTypedArrayType( glType ) {

const { gl } = this;

if ( glType === gl.UNSIGNED_BYTE ) return Uint8Array;

if ( glType === gl.UNSIGNED_SHORT_4_4_4_4 ) return Uint16Array;
if ( glType === gl.UNSIGNED_SHORT_5_5_5_1 ) return Uint16Array;
if ( glType === gl.UNSIGNED_SHORT_5_6_5 ) return Uint16Array;
if ( glType === gl.UNSIGNED_SHORT ) return Uint16Array;

if ( glType === gl.UNSIGNED_INT ) return Uint32Array;

if ( glType === gl.UNSIGNED_FLOAT ) return Float32Array;

}

_getBytesPerTexel( glFormat ) {

const { gl } = this;

if ( glFormat === gl.RGBA ) return 4;
if ( glFormat === gl.RGB ) return 3;
if ( glFormat === gl.ALPHA ) return 1;

}

_clientWaitAsync( sync ) {

const { gl } = this;

return new Promise( ( resolve, reject ) => {

function test() {

const res = gl.clientWaitSync( sync, gl.SYNC_FLUSH_COMMANDS_BIT, 0 );

if ( res === gl.WAIT_FAILED) {

reject();
return;

}

if ( res === gl.TIMEOUT_EXPIRED) {

requestAnimationFrame( test );
return;

}

resolve();

}

test();

} );

}

}

export default WebGLTextureUtils;

0 comments on commit 3b86f57

Please sign in to comment.