WEBGL_get_buffer_sub_data_async WebGL working group (public_webgl 'at' khronos.org) Kai Ninomiya, Google Inc. Members of the WebGL working group 34

This extension allows asynchronous buffer readback in WebGL 2.0.

This extension exposes an asynchronous buffer readback entry point for non-blocking readbacks from WebGL buffers. It is equivalent to getBufferSubData but returns a Promise instead of an immediate readback result.
[NoInterfaceObject] interface WEBGL_get_buffer_sub_data_async { // Asynchronous version of getBufferSubData which fulfills the returned promise when the data becomes available. Promise<ArrayBuffer> getBufferSubDataAsync(GLenum target, GLintptr srcByteOffset, ArrayBufferView dstBuffer, optional GLuint dstOffset = 0, optional GLuint length = 0); // May throw DOMException }; Reads back data asynchronously from the bound WebGLBuffer into dstBuffer.

Let buf be the buffer bound to target at the time getBufferSubDataAsync is called. If length is 0, let copyLength be dstBuffer.length - dstOffset; otherwise, let copyLength be length.

If copyLength is greater than zero, copy copyLength typed elements (each of size dstBuffer.BYTES_PER_ELEMENT) from buf into dstBuffer, reading buf starting at byte index srcByteOffset and writing into dstBuffer starting at element index dstOffset. If copyLength is 0, no data is written to dstBuffer, but this does not cause a GL error to be generated.
  • If no WebGLBuffer is bound to target, an INVALID_OPERATION error is generated.
  • If target is TRANSFORM_FEEDBACK_BUFFER, and any transform feedback object is currently active, an INVALID_OPERATION error is generated.
  • If dstOffset is greater than dstBuffer.length, an INVALID_VALUE error is generated.
  • If dstOffset + copyLength is greater than dstBuffer.length, an INVALID_VALUE error is generated.
  • If srcByteOffset is less than zero, an INVALID_VALUE error is generated.
  • If srcByteOffset + copyLength*dstBuffer.BYTES_PER_ELEMENT is larger than the length of buf, an INVALID_OPERATION is generated.
When invoked, getBufferSubDataAsync must run these steps:
  • Let promise be a Promise to be returned.
  • Check for the errors defined above. If there are any errors, generate the GL error synchronously and reject promise with an InvalidStateError.
  • Insert a readback of buf into the GL command stream, using the range defined above.
  • Return promise, but continue running these steps in parallel.
  • Upon completion of the readback, queue a task performing the following steps:
    • If the context has been lost, or if dstBuffer has been neutered, reject promise with an InvalidStateError. In this case, no GL error is generated.
    • Write the readback result into dstBuffer, using the range defined above.
    • Resolve promise with dstBuffer.
    The task source for this task is the WebGL task source.
If the returned Promise is rejected, no data is written to dstBuffer.
Even if getBufferSubDataAsync is called multiple times in a row with the same dstBuffer, then callbacks added synchronously will never see results of subsequent getBufferSubDataAsync calls.
Compared to the synchronous version of getBufferSubData, this version may impose less overhead on applications. Intended use cases include reading pixels into a pixel buffer object and examining that data on the CPU. It does not force the graphics pipeline to be stalled as getBufferSubData does.
Initial revision. Set status to rejected following the working group's decision to allow optimizations of the existing getBufferSubData API instead of exposing a new one.