[Public WebGL] using the same context with multiple canvases

Florian Bösch [email protected]
Wed Mar 25 11:03:37 PDT 2015


Jobs that fall on drawing buffers to manage aren't managed, such as alpha,
depth, stencil, antialias, premultipliedAlpha, preserveDrawingBuffer and
whatever new ones WebGL 2 might bring.

On Wed, Mar 25, 2015 at 6:54 PM, Ashley Gullen <[email protected]> wrote:

> 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/d2a6250f/attachment.html>


More information about the public_webgl mailing list