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

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

Before we discard this idea for this reason: I suspect that the
biggest improvements in animation smoothness on the main thread will
come from introducing one, not many, worker threads which can access
WebGL. GPUs today are batch processors; better scalability won't be
achieved by splitting up and issuing work from multiple CPU threads
and multiple OpenGL contexts. The primary improvement for current
WebGL apps would be to populate objects like textures without blocking
CPU execution on the main thread. Therefore it might be a better idea
to introduce a small semantic change like this one, instead of a more
complex readers/writer locking API. However, I do believe that a
readers/writer lock could be added in a backward compatible manner,
where if only one context were in the share group, calls to acquire
would not be mandatory.


On Fri, Aug 24, 2012 at 2:53 PM, Gregg Tavares (社用) <gman@google.com> wrote:
> 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
>> obsolete.
>> 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.
>> -Ken

You are currently subscribed to public_webgl@khronos.org.
To unsubscribe, send an email to majordomo@khronos.org with
the following command in the body of your email:
unsubscribe public_webgl