Skip to content

Commit fff4f00

Browse files
aardgooseaardgoose
and
aardgoose
authored
WebGPURenderer: support getArrayBufferAsync() for WebGL backend (#27355)
* read buffer async * return ArrayBuffer --------- Co-authored-by: aardgoose <[email protected]>
1 parent 9807b24 commit fff4f00

File tree

4 files changed

+82
-42
lines changed

4 files changed

+82
-42
lines changed

examples/jsm/renderers/webgl/WebGLBackend.js

+6
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ class WebGLBackend extends Backend {
5353

5454
}
5555

56+
async getArrayBufferAsync( attribute ) {
57+
58+
return await this.attributeUtils.getArrayBufferAsync( attribute );
59+
60+
}
61+
5662
beginRender( renderContext ) {
5763

5864
const { gl } = this;

examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js

+32
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,38 @@ class WebGLAttributeUtils {
134134

135135
}
136136

137+
async getArrayBufferAsync( attribute ) {
138+
139+
const backend = this.backend;
140+
const { gl } = backend;
141+
142+
const bufferAttribute = attribute.isInterleavedBufferAttribute ? attribute.data : attribute;
143+
const { bufferGPU } = backend.get( bufferAttribute );
144+
145+
const array = attribute.array;
146+
const byteLength = array.byteLength;
147+
148+
gl.bindBuffer( gl.COPY_READ_BUFFER, bufferGPU );
149+
150+
const writeBuffer = gl.createBuffer();
151+
152+
gl.bindBuffer( gl.COPY_WRITE_BUFFER, writeBuffer );
153+
gl.bufferData( gl.COPY_WRITE_BUFFER, byteLength, gl.STREAM_READ );
154+
155+
gl.copyBufferSubData( gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, byteLength );
156+
157+
await backend.utils._clientWaitAsync();
158+
159+
const dstBuffer = new attribute.array.constructor( array.length );
160+
161+
gl.getBufferSubData( gl.COPY_WRITE_BUFFER, 0, dstBuffer );
162+
163+
gl.deleteBuffer( writeBuffer );
164+
165+
return dstBuffer.buffer;
166+
167+
}
168+
137169
}
138170

139171
export default WebGLAttributeUtils;

examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js

+2-42
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ class WebGLTextureUtils {
213213

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

216-
const { gl } = this;
216+
const { backend, gl } = this;
217217

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

@@ -235,13 +235,7 @@ class WebGLTextureUtils {
235235
gl.readPixels( x, y, width, height, glFormat, glType, 0 );
236236
gl.bindBuffer( gl.PIXEL_PACK_BUFFER, null );
237237

238-
const sync = gl.fenceSync( gl.SYNC_GPU_COMMANDS_COMPLETE, 0 );
239-
240-
gl.flush();
241-
242-
await this._clientWaitAsync( sync );
243-
244-
gl.deleteSync( sync );
238+
await backend.utils._clientWaitAsync();
245239

246240
const dstBuffer = new typedArrayType( elementCount );
247241

@@ -280,40 +274,6 @@ class WebGLTextureUtils {
280274

281275
}
282276

283-
_clientWaitAsync( sync ) {
284-
285-
const { gl } = this;
286-
287-
return new Promise( ( resolve, reject ) => {
288-
289-
function test() {
290-
291-
const res = gl.clientWaitSync( sync, gl.SYNC_FLUSH_COMMANDS_BIT, 0 );
292-
293-
if ( res === gl.WAIT_FAILED) {
294-
295-
reject();
296-
return;
297-
298-
}
299-
300-
if ( res === gl.TIMEOUT_EXPIRED) {
301-
302-
requestAnimationFrame( test );
303-
return;
304-
305-
}
306-
307-
resolve();
308-
309-
}
310-
311-
test();
312-
313-
} );
314-
315-
}
316-
317277
}
318278

319279
export default WebGLTextureUtils;

examples/jsm/renderers/webgl/utils/WebGLUtils.js

+42
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,48 @@ class WebGLUtils {
237237

238238
}
239239

240+
_clientWaitAsync() {
241+
242+
const { gl } = this;
243+
244+
const sync = gl.fenceSync( gl.SYNC_GPU_COMMANDS_COMPLETE, 0 );
245+
246+
gl.flush();
247+
248+
return new Promise( ( resolve, reject ) => {
249+
250+
function test() {
251+
252+
const res = gl.clientWaitSync( sync, gl.SYNC_FLUSH_COMMANDS_BIT, 0 );
253+
254+
if ( res === gl.WAIT_FAILED) {
255+
256+
gl.deleteSync( sync );
257+
258+
reject();
259+
return;
260+
261+
}
262+
263+
if ( res === gl.TIMEOUT_EXPIRED) {
264+
265+
requestAnimationFrame( test );
266+
return;
267+
268+
}
269+
270+
gl.deleteSync( sync );
271+
272+
resolve();
273+
274+
}
275+
276+
test();
277+
278+
} );
279+
280+
}
281+
240282
}
241283

242284
export default WebGLUtils;

0 commit comments

Comments
 (0)