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

Re: [Public WebGL] Queries in WebGL 2.0

I am not super well versed in knowledge of GC operation in browsers, though my understanding is that long-lived JS objects don't cause much GC pressure. Even though WebGL does have the high level WebGLBuffer, WebGLTexture, WebGLShader etc. objects, at least in Emscripten compiled GL code, these objects are generally not created and deleted at high frequency at all. If one needs, say, dynamic textures, one might create and reuse them from a custom maintained pool. From the high level interface objects, the WebGLUniformLocation type is the most painful, since there can be hundreds of these per program, and we need to maintain a big table of int<->WebGLUniformLocation assignment mappings for them, though these mappings are also very persistent across application frames.

The large amount of per-frame GC pressure comes from the functions that take in a BufferDataSource or ArrayBufferView WebIDL parameters. In WebGL 1 these are buffer{Sub}Data, compressedTex{Sub}Image2D, readPixels, tex{Sub}Image2D, uniform{1,2,3,4}{i,f}v, uniformMatrix{2,3,4}fv and vertexAttrib{1,2,3,4}fv. The GC pressure is because one needs to prepare a suitable typed array view that is of correct size. In Emscripten we represent memory as a linear heap, so we don't have such typed arrays ready that would be long-lived in memory, but need to create them on demand. Some of these functions are called with very high frequency, often multiple times per each draw, uniform{1,2,3,4}{i,f}v and uniformMatrix{2,3,4}fv being the most common, followed by bufferSubData and texSubImage2D. This would create thousands of temporary JS typed array view allocations per frame, so we create these kind of pooling hacks for the most commonly sized small views: https://github.com/kripken/emscripten/blob/incoming/src/library_gl.js#L71 and https://github.com/kripken/emscripten/blob/incoming/src/library_gl.js#L2669. This scheme alleviates the problem, but trades it for some lost performance, since we need to copy the data over, as shown in the second link.

For compiled GL code case, if each of these functions that took in an array buffer (view) would have a variant that additionally takes in offset and length, that would lift all of this shuffling altogether, since we could just point the array buffer view parameter to the asm.js HEAP and provide the subrange in the heap in the function call.

In any case, did not mean to derail this topic, except to voice that we definitely value having the 1:1 C-like mapping wherever possible, since that ensures there's as little performance and features lost in the runtime GLES->WebGL translation layer as possible, compared to native. In my opinion, having JS'y APIs (in addition) is ok, as long as that API is suitable for functioning as a compilation target as well, or if there is an additional C-like API in parallel.

2016-04-27 18:17 GMT+03:00 Kirill Dmitrenko <dmikis@yandex-team.ru>:
I'm not defending my point (completely agree with you guys). But WebGL API might already create a considerable pressure on GC due to the fact that every GL entity is wrapped in it's own JS object, doesn't it?
27.04.2016, 17:12, "Florian Bösch" <pyalot@gmail.com>:
On Wed, Apr 27, 2016 at 3:08 PM, juj j <jujjyl@gmail.com> wrote:
It would be very nice to have an allocation-free variant of the API
+1 the WebGL API should be zero GC (assuming no create/delete/forget trashing is done by the application itself), I'd consider it a bug if it isn't.
Kirill Dmitrenko
Yandex Maps Team