[Public WebGL] using the same context with multiple canvases

Javi Agenjo [email protected]
Wed Mar 25 10:10:51 PDT 2015

I really like that approach, its clean, clear and powerful.

On Wed, Mar 25, 2015 at 4:17 PM, Florian Bösch <[email protected]> wrote:

> Here's how I think it should work:
> var gl = new WebGLContext();
> var db1 = gl.createDrawingBuffer({antialias:true, stencil:false, ...});
> var db2 = gl.createDrawingBuffer({antialias:false, stencil:true, ...});
> var canvas1 = document.createElement('canvas');
> var canvas2 = document.createElement('canvas');
> canvas1.drawingBuffer = db1;
> canvas2.drawingBuffer = db2;
> var draw = function(){
>   gl.bindDrawinBuffer(db1);
>   gl.draw...
>   gl.bindDrawingBuffer(db2);
>   gl.draw...
>   requestAnimationFrame(draw);
> }
> On Wed, Mar 25, 2015 at 4:11 PM, 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/705fd665/attachment.html>

More information about the public_webgl mailing list