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

Re: [Public WebGL] using the same context with multiple canvases



On 10/17/2012 9:20 PM, Benoit Jacob wrote:
Agree that sharing a single context between canvases seems like a more workable approach than the opposite -- it will lead to less memory overhead (no need to have N OpenGL contexts for N canvases, and no need to rely on OpenGL share groups).

Some random thoughts:

- what happened to the previously discussed idea of an idea like this:

   gl.bindFramebuffer(othercanvas);

Yep, I prefer this instead of a new setCanvas call as well.  You should be able to treat canvases as just framebuffers whose configuration you can't modify. Note that we already made this easy on ourselves by having WebGLFramebuffer be an object... so things like getting the currently bound framebuffer work naturally, just returning a Canvas element object instead of a WebGLFramebuffer :)

- a big problem with the approach of having to getContext before telling that you want to use another existing context, is that it will force the browser to create a drawing buffer which you may turn out to never use. We need an API that avoids such waste by allowing to avoid creating drawing buffers. The earlier-discussed bindFramebuffer(canvas) proposal, applied to a new canvas that doesn't already have a context on it, was a possible way to solve that problem.

I think you actually want both -- you want to do getContext() on the second canvas, giving it the existing context as part of the params.  Brandon's proposal of 'attach' would work well here.

- I have a feeling that allowing multiple sets of context attributes is going to be a headache. If we settle on an API that formally allows specifying different context attribs, I'd at least recommend requiring the all the attributes to agree across all canvases, at least as a first step -- we can always relax that later, but if we allow it from the start, we won't be able to change it anymore.

If we take the view that each canvas operates like a framebuffer, then the attribs will be used to configure the framebuffer for that canvas.  For example, you may want one canvas that has depth but no alpha, and another where you need alpha but don't care about depth.

So, for example:

var gl = canvas1.getContext("webgl", { depth: true, alpha: false });
var gl2 = canvas2.getContext("webgl", { attach: ctx, depth: false, alpha: true });
assert(gl === gl2);

gl.clearColor(1, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

ctx.bindFramebuffer(ctx.FRAMEBUFFER, canvas2);
gl.clearColor(0, 1, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);

/* null always returns to the canvas that created the context,
 * but the canvas object is an alias -- these two lines are identical:
 */
ctx.bindFramebuffer(ctx.FRAMEBUFFER, null);
ctx.bindFramebuffer(ctx.FRAMEBUFFER, canvas1);


From Gregg's email:
After the cal to cavnas2.setContext(ctx1) what does ctx2 do? Does it still draw to cavnas2 as well? Does it get GL_INVALID_FRAMEBUFFER_OPERATION if a draw/clear function is called and no FBO is bound? Does it become lost? What does ctx1.canvas reference and what does ctx2.canvas reference? What does ctx1.getContextAttributes() return? The attributes for canvas1 or canvas2? 

My thoughts... ctx1/ctx2 should be equivalent, so no need to specify draw/clear with no binding behaviour, different loss behaviour, etc.  ctx.canvas always references the creating canvas; we don't really have much need to get the canvas from the context anyway.  (We can and maybe should introduce something like ctx.getAttachedCanvases() or something?)  ctx.getContextAttibutes() we can extend to be ctx.getContextAttributes(canvas), with default of null being the original canvas (i.e. canvas1).

    - Vlad


- Likewise, allowing canvases from different principals is going to be a source of pain, so I'd make it a requirement that canvases sharing a context must be on the same principal.

Benoit

On 12-10-17 09:04 PM, Gregg Tavares (社用) wrote:
I'd like to pursue this idea further that Florian brought up which is that, for drawing to multiple canvases, rather than share resources across contexts it would be much nicer to just be able to use the same context with multiple canvases. Something like

    ctx1 = canvas1.getContext("webgl");
    ctx1.clearColor(0,1,0,1);
    ctx1.clear(gl.COLOR_BUFFER_BIT);
    canvas2.setContext(ctx1);
    ctx1.clear(gl.COLOR_BUFFER_BIT);

Clear's both canvas1 and canvas2 to green

Issues: Under the current WebGL the only way to setup a canvas is by calling getContext(..., contextCreationParameters). Whether the canvas is RGB or RGBA, has depth or stencil, is premultiplied or not, has it's backbuffer preserved or not, etc..

Which leads to some questions.

Is the current API okay. You'd create 2 contexts still but just use one of them as in

    ctx1 = canvas1.getContext("webgl". { alpha: true } );
    ctx2 = canvas1.getContext("webgl". { alpha: false } );
    ctx1.clearColor(0,1,0,1);
    ctx1.clear(gl.COLOR_BUFFER_BIT);
    canvas2.setContext(ctx1);
    ctx1.clear(gl.COLOR_BUFFER_BIT);

After the cal to cavnas2.setContext(ctx1) what does ctx2 do? Does it still draw to cavnas2 as well? Does it get GL_INVALID_FRAMEBUFFER_OPERATION if a draw/clear function is called and no FBO is bound? Does it become lost? What does ctx1.canvas reference and what does ctx2.canvas reference? What does ctx1.getContextAttributes() return? The attributes for canvas1 or canvas2? 

I think arguably being able to setContext on a canvas is the right way to solve drawing to multiple canvas with the same resources but there are some unfortunate existing API choices.

Thoughts?