[Public WebGL] using the same context with multiple canvases

Ashley Gullen [email protected]
Wed Mar 25 10:54:20 PDT 2015

But is it possible it could be optimised? I guess implementers would need
to comment. I think it should be theoretically possible to have a global
command buffer such that a drawImage() with a WebGL canvas can be buffered
as well instead of forcing a flush, and perform a GPU-accelerated copy.
Also there should be no need to keep resizing the canvas buffer: as I
described in my post, a single buffer at the maximum necessary size should
do it, and only needs viewport and scissor rectangle updates.

If all that was working optimally, would there still need to be new
features for this?

On 25 March 2015 at 15:11, Florian Bösch <[email protected]> wrote:

> The drawImage idea has some issues:
>    - It's currently not hardware accelerated (and I'm not sure it can be).
>    - It induces a sync stall because you have a sync-point (drawImage)
>    and in order for that to work, the browser has to run the GL commands up to
>    that point.
>    - If you need to render several different resolutions (that's almost
>    always the case) you'll end up resizing the canvases drawing buffer several
>    times each frame.
> I don't think it's an adequate workaround. A proper solution is to be able
> to setup drawing buffers to draw to, and to connect them to a canvas, and
> whatever you draw while one is bound, is what ends up being displayed in
> that canvas.
> On Wed, Mar 25, 2015 at 4:02 PM, Ashley Gullen <[email protected]> wrote:
>> It's possible to render a WebGL-rendered canvas to a 2D context canvas
>> with drawImage(). So it seems to me the workaround is just to have one
>> off-screen WebGL context that does all the real rendering, and then
>> drawImage the result to a 2D canvas in the document. This seems to me to
>> have several advantages:
>> - works today (nothing more to be specced)
>> - GPU-accelerated copying (assuming it's possible for drawImage() to be
>> GPU-accelerated when passed a WebGL canvas, regardless of whether real
>> implementations do it today - if they do not then this should be added)
>> - no need to share resources between contexts or load resources twice,
>> since there is only one context
>> - can update multiple canvases per frame simply by rendering multiple
>> views in one rAF and copying them out to their respective 2D canvases
>> during rendering
>> If some canvases are different sizes, then the WebGL context just needs
>> to be as big as the largest. It can change its viewport and add a scissor
>> rectangle to save fillrate during rendering too, and drawImage can specify
>> the source area to render from the source WebGL canvas.
>> This seems to work OK to me, but perhaps I have missed something? I can
>> see it would be a performance improvement if a single draw call could draw
>> to two canvases at once, perhaps from different views, but the above
>> solution seems workable and AFAICT in theory can stay GPU-side without any
>> readback.
>> This does not cover rendering from a worker, which I do still think is a
>> valuable addition but appears separate to this particular email thread.
>> Ashley
>> On 25 March 2015 at 13:52, Javi Agenjo <[email protected]> wrote:
>>> I just wanted to say that I rely in the same solution as Florian for my
>>> materials editor, I considered for a long time using a secondary canvas,
>>> but that implies that I must store the Images of every texture (instead of
>>> removing them once uploaded to VRAM) in case another Canvas needs those
>>> textures, so that increases the RAM I need for the whole application.
>>> I still think that some kind of middle ground solution for those cases
>>> would be great, not sharing the same resources but allowing cloning data
>>> from one context to another directly, like passing the handler of another
>>> texture to the texImage2D even if it those come from the same WebGL
>>> Context. (I don't know if anyone has considered that option).
>>> On Wed, Mar 25, 2015 at 8:46 AM, Florian Bösch <[email protected]> wrote:
>>>> Just yesterday I ran into that problem again (for a PBR material
>>>> manager) where I'd like to show previews of materials as rendered on a
>>>> sphere.
>>>> Since the main canvas is supersampled and fxaa'ed It'd be expensive to
>>>> update via readback, so that one is rendered from the context as usual. The
>>>> previews are also ssaed, but the thumbnails are only 100x100 pixels, so
>>>> each time a user touches any control (slider, color picker etc.) they're
>>>> rendered off-screen to an fbo and readback to be put into the thumbnails 2D
>>>> canvas.
>>>> I could probably substitute the thumbnails "off-line" canvas 2D with a
>>>> second GL canvas for the duration of modification of that material. And
>>>> while that may work well, it's not a solution to usecases that require more
>>>> than 1-2 canvases to be updated simultaneously (and neither is the readback
>>>> and copy in solution).
>>>> I run into that sort of problem every couple of months. It's quite
>>>> annoying.
>>>> On Mon, Mar 23, 2015 at 9:29 PM, Aleksandar Rodic <
>>>> [email protected]> wrote:
>>>>> The workaround I came up with was a canvas wrapper which migrates the
>>>>> real canvas and its GL context at render time. The canvases which are
>>>>> not rendering show static stand-in canvas with a copy of the image which
>>>>> was last rendered.
>>>>> This approach works great if you only update one canvas at a time. Rendering
>>>>> to multiple canvases simultaneously causes expensive canvas migrations
>>>>> (copying image data).
>>>>> Aki
>>>>> On Mon, Mar 23, 2015 at 11:04 AM Mitchell Williams <
>>>>> [email protected]> wrote:
>>>>>> If I understand the issue, it sure would be nice if this worked.
>>>>>> I tried to render the scene from a camera to another window (such as
>>>>>> when 3DS Max can view a scene in perspective view, and that scene contains
>>>>>> a camera which we can see the scene from the camera's view in another
>>>>>> window).
>>>>>> As an alternative, I rendered the scene as a texture map, but all
>>>>>> contained within a single canvas.
>>>>>> This would be nice to render a scene to multiple canvases.
>>>>>> Mitch
>>>>>> On Mon, Mar 23, 2015 at 12:06 AM, Florian Bösch <[email protected]>
>>>>>> wrote:
>>>>>>> The topic of how to draw to multiple canvases from a single context
>>>>>>> (from either the JS main thread or a worker) has not yet been resolved
>>>>>>> (correct me if I'm wrong).
>>>>>>> A possible resolution seems to be the canvas.setContext method.
>>>>>>> However, this seems to to be under specified, as just having a WebGL
>>>>>>> context is not sufficient, you also need a drawing buffer which carries
>>>>>>> attributes such as stencil, depth, bit-depth, MSAA, etc., and the WebGL 2
>>>>>>> specification doesn't seem to contain anything about how to create either a
>>>>>>> WebGL 2 context or a drawing buffer on its own (It just specifies that a
>>>>>>> getContext call needs to do both).
>>>>>>> Regardless of specification status or respective completeness, no
>>>>>>> implementation of setContext is available, let alone anything to create
>>>>>>> WebGL contexts and drawing buffers on their own to be used.
>>>>>>> I'll posit that this isn't an acceptable situation. I'll reiterate
>>>>>>> that quite frequently applications that do provide any kind of UI (like
>>>>>>> sketchfab, verold, goo, fabric) need to put WebGL driven content into many
>>>>>>> places inside that UI that isn't a single viewport. That content might find
>>>>>>> itself CSS transformed, composited, scrolled in/out of view, inside an
>>>>>>> overflow: scroll container, sandwiched between html elements etc. And that
>>>>>>> content might need to be updated at each animation frame.
>>>>>>> I'm frankly mystified why a topic we've been talking about for well
>>>>>>> over 3 years and have been promised specifications/solutions for, that is
>>>>>>> widely recognized as an important issue to solve, is nearly unspecified and
>>>>>>> completely unsolved.
>>>>>> --
>>>>>> Mitch Williams
>>>>>> Check out my book "*WebGL Hotshot*" available at:
>>>>>> https://www.packtpub.com/web-development/webgl-hotshot
>>>>>> 310-809-4836 (outside line)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://khronos.org/pipermail/public_webgl_khronos.org/attachments/20150325/cc8ce472/attachment.html>

More information about the public_webgl mailing list