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

Re: [Public WebGL] Issues with sharing resources across contexts

This doesn't solve the cases Ben brought up. Namely the ability to read from the same texture at the same time in multiple workers.

The Acquire/Release does solve that problem since more than one context can do a READ_ONLY acquire at the same time.

On Fri, Aug 24, 2012 at 2:48 PM, Kenneth Russell <kbr@google.com> wrote:
On Fri, Aug 24, 2012 at 11:15 AM, Florian Bösch <pyalot@gmail.com> wrote:
> On Fri, Aug 24, 2012 at 7:52 PM, Gregg Tavares (社用) <gman@google.com> wrote:
>> or similar that would mean sharing resources on the main page is not
>> needed.
> That's exactly my thinking, it would simplify the design of the resource
> sharing because you wouldn't have to consider main page canvasii
> compositing.
>> Would this work
>> var canvas1 = document.createElement("canvas");
>> var canvas2 = document.createElement("canvas");
>> var gl1 = canvas1.getContext("webgl");
>> var gl2 = canvas2.getContext("webgl");
>> //now both canvases are webgl canvases
>> // swap them just for fun
>> gl1.bindFramebuffer(gl.FRAMEBUFFER, canvas2);
>> gl2.bindFramebuffer(gl.FRAMEBUFFER, canvas1);
>> It seems like a little bit of a waste to have to create the second context
>> just so the canvas is a WebGL canvas
>> Also, ti seems like overloading the meaning of bindFramebuffer might not
>> be the best method since there all various operations you can do to
>> currently bound framebuffer. So maybe it should be something like
>> gl.bindBackbuffer(canvas)
>> or
>> gl.bindCanvas(canvas)
>> and then like normal, calling
>> gl.bindFramebuffer(gl.FRAMEBUFFER,null)
>> renders to the current backbuffer/canvas with all the limits that normally
>> entails (can't call framebufferRenderbuffer or framebufrferTexture2D on it)
> Semantically that all works for me, I find I wouldn't have a preference if
> we call this attaching a buffer to an FBO or binding a different
> frontbuffer.
> There's one area where the FBO semantic does have an advantage though. If
> you display partials (like say albedo of a scene) and then re-use the filled
> depth buffer to render something else (like say deferred lighting) and you
> have, for some reason, the desire to show both on the page (It's not
> contrieved, I promise, I have such an example right now, releasing it in the
> next few days). Since there isn't a way to attach (or even explicitly
> obtain) the depth buffer for use on the front, you couldn't wire your
> rendering together to share it. So what you'd end up doing would be to
> render to an FBO and then sample that FBO to blit to the canvas. It's still
> way better than the alternatives, just slightly inelegant (if you could do
> it more directly). On the other hand, if you feel the API is much cleaner
> with the bind frontbuffer semantic, I don't think that's a big drawback.

This is an interesting direction and for some use cases would
eliminate the need for share groups. However, I'm concerned that it
isn't an extensible path to go down for at least a couple of reasons:

1) It isn't compatible with using WebGL in a worker. At present there
is no way to use HTMLCanvasElements, or any other DOM element, from a
worker, and it seems that enabling that is a very long road to go down
with the HTML5 standards groups.
2) As Florian points out, it only supports use of the canvas as an
output surface. I think there are likely to be a lot of use cases
where it's desirable to use the rendered output as a texture for
another rendering stage.
3) It doesn't address all of the use cases that share groups do, and
if share groups were introduced later, they might make this API

Here is a suggestion toward resolving the problems of using OpenGL /
WebGL resources shared between multiple contexts. What if, in WebGL,
it were only legal to bind a given OpenGL object to a single context
at once? This would essentially implement the acquire/release
semantics proposed above, but without adding any new APIs. As an
example, if a texture was bound to context 1, attempting to bind it to
context 2 would produce an OpenGL error, and the bind would fail. This
would mean that each object essentially would have a context which is
its "owner". By and large, this can be implemented with a single
compare-and-swap operation. It's similar to how "fast locking" schemes
work in multithreaded virtual machines for languages like Java.

Binding a container object that refers to other objects would have to
obey the same rule. If fbo1 had texture1 as its color attachment, and
context2 bound texture1 to one of its texture units, then it would be
illegal for context1 to bind fbo1 until context2 unbound texture1.
Same for program objects which refer to shader objects. This is a
little more difficult to implement (not a simple compare-and-exchange
per object any more) but I think still feasible within the WebGL
implementation without too high a cost.

This wouldn't address all of the problems associated with resource
sharing. In particular, since the ES 2.0 spec requires a glFinish() in
context1 before its rendering results into textures are guaranteed to
be visible by context2, I'm not sure how it could be guaranteed that
all of context1's work was visible in context2. If context2 bound an
object that was most recently "dirtied" by context1, what would really
be required is a glFinish() issued in context1, which could be
difficult for the WebGL implementation to enforce.

Any thoughts on this general idea? I don't think it would impose too
many compatibility issues when porting multithreaded or multi-context
code to WebGL, and would at least provide consistent and testable
behavior for more situations.