<div dir="ltr">The problem isn't just the promise allocation, it's also the closure allocation. And while you can avoid that in some cases, you can't avoid it in all cases. And beyond that, the further problem of registering callbacks to do stuff would be that it lifts rendering logic out of the requestAnimationFrame loop and occurs... whenever. Which isn't a proper way to render. So in practice you'd end up attaching a callback just to collect the result and put it in a variable you'll check for not being null at the start of the next requestAnimationFrame invocation. Of course when you do that, the entire exercise of providing a callback is moot. Since that'd be the most common usage pattern that everybody would recommend based on sound reasoning about the predictability of rendering in a requestAnimationFrame loop, that makes promises/callbacks entirely moot and the wrong thing to do.</div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jan 6, 2017 at 1:52 PM, Maksims Mihejevs <span dir="ltr"><<a href="mailto:max@playcanvas.com" target="_blank">max@playcanvas.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Why not to use classic callbacks with (err, response) arguments?</div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On 6 January 2017 at 00:01, Kenneth Russell <span dir="ltr"><<a href="mailto:kbr@google.com" target="_blank">kbr@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span>On Thu, Jan 5, 2017 at 2:55 AM, Maksims Mihejevs <span dir="ltr"><<a href="mailto:max@playcanvas.com" target="_blank">max@playcanvas.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Thank you for answer, this examples make sense.<div><br></div><div>The only concern as mentioned before are: Promises. There is no a single use of promises in WebGL, and there is a reason why they should not be used in real-time applications if they can be avoided (which is the case).</div><div><br></div><div>If possible Fence (Sync Objects) were involved in design process? Could something like this be achieved by using more generic functionality in GL such as Sync Objects?</div></div></blockquote><div><br></div></span><div>Promises were chosen for a particular reason. Even if a primitive like mapBufferRange were exposed in WebGL, a typed array would still need to be allocated as the return result. There's no provision in the ECMAScript specification for "re-pointing" a typed array at a new backing store, although Chrome's V8 team proposed this a while back. Mapping a buffer's range at the OpenGL ES level returns a void*, and that would need to be exposed to ECMAScript. Passing in an already-allocated typed array wouldn't work in the current form of the APIs.</div><div><br></div><div>Given that an allocation would be needed anyway, returning a Promise is much more web-friendly. It avoids the need for the application to deal with sync objects, and potentially inconsistent states of the returned typed array. getBufferSubDataAsync lets the application specify where it wants the returned data to be copied.</div><div><br></div><div>-Ken</div><div><div class="m_3788624672667373827h5"><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><br></div><div>Kind Regards,<br>Max</div></div><div class="m_3788624672667373827m_-1512901501874305807HOEnZb"><div class="m_3788624672667373827m_-1512901501874305807h5"><div class="gmail_extra"><br><div class="gmail_quote">On 4 January 2017 at 18:55, Kai Ninomiya <span dir="ltr"><<a href="mailto:kainino@google.com" target="_blank">kainino@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Max,<div><br></div><div>In my demo [1] there are 3 different possible readback paths:</div><div>* readPixels to CPU [2]</div><div>* readPixels to PBO + getBufferSubData [3]</div><div>* readPixels to PBO + getBufferSubDataAsync [4]</div><div><br></div><div>As you said, getBufferSubData(/Async) can be used for reading back any buffer data (such as transform feedback or GPGPU shader results). PBO is necessary (AFAIK) for async readback from framebuffer data (note: an async readPixels wouldn't be as useful as it would block any operation which writes to the framebuffer).</div><div><br></div><div>-Kai</div><div><br></div><div>[1] <a href="https://github.com/kainino0x/getBufferSubDataAsync-Demo/" target="_blank">https://github.com/kainino<wbr>0x/getBufferSubDataAsync-Demo/</a></div><div><div>[2] <a href="https://github.com/kainino0x/getBufferSubDataAsync-Demo/blob/master/index.html#L245" target="_blank">https://github.com/kainino<wbr>0x/getBufferSubDataAsync-Demo/<wbr>blob/master/index.html#L245</a></div></div><div>[3] <a href="https://github.com/kainino0x/getBufferSubDataAsync-Demo/blob/master/index.html#L261" target="_blank">https://github.com/kainino<wbr>0x/getBufferSubDataAsync-Demo/<wbr>blob/master/index.html#L261</a></div><div>[4] <a href="https://github.com/kainino0x/getBufferSubDataAsync-Demo/blob/master/index.html#L280" target="_blank">https://github.com/kainino<wbr>0x/getBufferSubDataAsync-Demo/<wbr>blob/master/index.html#L280</a></div></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660HOEnZb"><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660h5"><br><div class="gmail_quote"><div dir="ltr">On Wed, Jan 4, 2017 at 5:09 AM Maksims Mihejevs <<a href="mailto:max@playcanvas.com" target="_blank">max@playcanvas.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">From PlayCanvas side, we express a need for async glReadPixels path too. We and our users have been using it in many ways, some of the ways:<div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">1. GPU picking: ID encoded in unique colour, reading pixel under mouse.</div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">2. GPU screen to world: reading pixel from depth texture, and using frustum with math reconstructing world position.</div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">3. Render Target to another Canvas. In Editor we have thumbnail previews for materials, models, cubemaps and other assets. We render them into render target in main context and then reading pixels to create ImageData so it can be put to another canvas using putImageData.</div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">4. Some custom algorithms to generate large amounts of computation heavy data saved into texture, then read on CPU - this depends per case. Sometimes async approach is viable there, sometimes it is not.</div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">In many cases glReadPixels is called per each frame, like for picking, and easily can drop frame rate due to blocking nature.</div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">I've noticed that PBOs are mentioned in WebGL 2.0 spec, but not much info apart of just that mention: <a href="https://www.khronos.org/registry/webgl/specs/latest/2.0/#4.2" class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg" target="_blank">https://www.khronos.o<wbr>rg/registry/webgl/specs/latest<wbr>/2.0/#4.2</a></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">PBOs would allow to get render target data into buffers without stalling GPU pipeline, and then read them.</div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">How does <span style="font-size:12.8px" class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">getBufferSubDataAsync relates to PBOs?</span></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><span style="font-size:12.8px" class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></span></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><span style="font-size:12.8px" class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">Cheers,<br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">Max</span></div></div><div class="gmail_extra m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><div class="gmail_quote m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">On 4 January 2017 at 05:27, Kenneth Russell <span dir="ltr" class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><<a href="mailto:kbr@google.com" class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg" target="_blank">kbr@google.com</a>></span> wrote:<br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><blockquote class="gmail_quote m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">Apologies for not discussing this extension on public_webgl before introducing it as a draft in the WebGL extension registry.<div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">The cost of synchronous glReadPixels has been a longstanding problem in WebGL. The Chrome browser specifically has a particularly deep graphics pipeline, and draining it with a synchronous call each frame imposes a too-great performance penalty. This has forced applications to rewrite certain algorithms when porting to WebGL.</div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">getBufferSubDataAsync is a direct parallel to getBufferSubData, and solves these performance pitfalls in Chrome. We've gathered data from two test cases so far, a GPU-based picking algorithm and a GPGPU global illumination algorithm, and the results look good. We will present this data on public_webgl soon, when making a case for moving the extension forward.</div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">-Ken</div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></div></div></div></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948m_2078170786563980359HOEnZb m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948m_2078170786563980359h5 m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><div class="gmail_extra m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><div class="gmail_quote m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">On Mon, Jan 2, 2017 at 2:27 PM, Maksims Mihejevs <span dir="ltr" class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><<a href="mailto:max@playcanvas.com" class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg" target="_blank">max@playcanvas.com</a>></span> wrote:<br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><blockquote class="gmail_quote m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">Worth mentioning that promises are extremely bad for GC and real-time applications, they do not provide a developer enough control to structure logic so to avoids any allocations.<div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">Promises - are not good for real-time at all, and lead to issues with GC. Any API in WebGL that is meant to be used in real-time applications should not be based on API's that are not real-time friendly.</div></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948m_2078170786563980359m_4190148138542956147HOEnZb m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948m_2078170786563980359m_4190148138542956147h5 m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><div class="gmail_extra m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><div class="gmail_quote m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">On 2 January 2017 at 20:49, Florian Bösch <span dir="ltr" class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><<a href="mailto:pyalot@gmail.com" class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg" target="_blank">pyalot@gmail.com</a>></span> wrote:<br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><blockquote class="gmail_quote m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">Upon thinking about this extension, I don't think it should exist at all. Ideally the mapBuffer semantic would be exposed. But even if it isn't, it shall not be that an extension is required to express functionality already found in the core functionality of the underlying ES specification.<div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">Furthermore, getBufferSubDataAsync does not adequately express the reality of map/flush/unmap, and hides the fact that unmap/flush are still synchronizing calls happening. However getBufferSubDataAsync obstructs appropriate code dealing with proper insertion of synchronization points.</div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">In addition, it would lead to allocating promises once or many times per frame, and since tracking would be required in some instances, would also lead to allocating a closure once or many times a call. An issue that map buffer range does not exhibit.</div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">Due to the lack of discussion of this feature, I believe a great disservice is done to WebGL 2 by the introduction of these ideas/APIs and I strongly suggest to withdraw this from draft immediately and go back to the drawing board.</div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></div></div></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948m_2078170786563980359m_4190148138542956147m_2552245989050067793HOEnZb m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948m_2078170786563980359m_4190148138542956147m_2552245989050067793h5 m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><div class="gmail_extra m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><div class="gmail_quote m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">On Mon, Jan 2, 2017 at 5:48 PM, Florian Bösch <span dir="ltr" class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><<a href="mailto:pyalot@gmail.com" class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg" target="_blank">pyalot@gmail.com</a>></span> wrote:<br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><blockquote class="gmail_quote m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">This extension <a href="https://www.khronos.org/registry/webgl/extensions/WEBGL_get_buffer_sub_data_async/" class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg" target="_blank">https://www.khronos.<wbr>org/registry/webgl/extensions/<wbr>WEBGL_get_buffer_sub_data_asyn<wbr>c/</a> has been introduced and elevated to draft without any public discussion.<div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">In a nutshell it proposes a new WebGL2 function called getBufferSubDataAsync which returns a promise that will be called eventually with the buffer data.</div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">I think there are several problems:</div><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><ol class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><li class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">The extension process states that "<i class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">Extensions move through four states during their development: <b class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">proposed</b>, draft, community approved, and Khronos ratified</i><font color="#000000" face="sans-serif" size="3" class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"><i class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">"</i>. </font>This extension never moved through the proposal stage.</li><li class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">The extension introduces promises to the WebGL API. This requires a more fundamental discussion.</li><li class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">A discussion if this extension is required if WebWorkers can access the same context as the main thread has not happened.</li></ol><div class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg">This extension should be in proposal status, and the necessary discussions should happen first.</div></div></div>
</blockquote></div><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></div>
</div></div></blockquote></div><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></div>
</div></div></blockquote></div><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></div>
</div></div></blockquote></div><br class="m_3788624672667373827m_-1512901501874305807m_-3013862173660000660m_1329979230134286948gmail_msg"></div>
</blockquote></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div></div></div><br></div></div>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>