[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Public WebGL] Re: WEBGL_get_buffer_sub_data_async



On Thu, Jan 12, 2017 at 3:23 AM, Kenneth Russell <kbr@google.com> wrote:
The reason Promises were chosen for this extension is that they're the current best practice on the web platform for expressing asynchronous computation.
Queries are the established best practice for asynchronous computation in realtime and GL code. Queries can also be adapted to emit promises with a few simple lines of JS code for anybody who wishes to do so.
 
The syntax is fluent, and it would have been difficult for me to argue with Chrome's leadership that there was a significant enough performance implication that a raw callback should be passed, contrary to the design of all other current web specs.
Callbacks are irrelevant to the discussion if we should rather use queries.
 
Kai and Jaume Sanchez ( https://www.clicktorelease.com/ ) are preparing another test case based on one of Jaume's global illumination examples. Once that's ready we'll post more data. At a high level, using this asynchronous API lets Chrome's deeply pipelined WebGL implementation match the performance of single-threaded and/or single-process WebGL implementations, though the code has to be changed to know about and take advantage of the extension.
A note on the examples cited so far, the most common one, object picking, should be done with an occlusion query, not with a getBufferDataAsync.

Here is an alternative proposal using query semantics:
  1. GET_BUFFER_SUB_DATA_ASYNC_WEBGL constant to be used by gl.beginQuery
  • getBufferSubDataAsync(target, offset, buffer)
Only those two primitives would need to be introduced to make it fully asynchronous, example:
var ext = gl.getExtension('WEBGL_get_buffer_sub_data_async');
var buffer = new Float32Array(1234);
var query = gl.createQuery();

function readBuffer(){
    gl.beginQuery(ext.GET_BUFFER_SUB_DATA_ASYNC_WEBGL, query);
    extension.getBufferSubDataAsync(target, 0, buffer);
    gl.endQuery(query);
}

function bufferReady(){
   return gl.getQueryObject(query, gl.QUERY_RESULT_AVAILABLE);
}

readBuffer();
function raf(){
    if(bufferReady()){
      doSomethingWithData();
      readBuffer();
    }
    requestAnimationFrame(raf);  
}
raf();
In addition to this being compatible with query semantics, this also offers the chance to complete many readbacks with a single query. For instance.

function readBuffer(){
    gl.beginQuery(ext.GET_BUFFER_SUB_DATA_ASYNC_WEBGL, query);
    extension.getBufferSubDataAsync(target1, 0, buffer1);
    extension.getBufferSubDataAsync(target2, 0, buffer2);
    extension.getBufferSubDataAsync(target3, 0, buffer3);
    gl.endQuery(query);
}