[Public WebGL] using the same context with multiple canvases

Florian Bösch [email protected]
Wed Mar 25 08:17:25 PDT 2015

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(){

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

More information about the public_webgl mailing list