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

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



I'm liking that approach. If you change the static createContext() to just being the WebGLRenderingContext constructor you'd match what Web Audio does ('new WebGLRenderingContext()' like 'new AudioContext()'), which is cool. It also matches what I'd believe the semantics of WebGL-in-a-worker would look like, where there's no <canvas> to create a context from.


On Thu, Oct 18, 2012 at 9:40 AM, Chris Marrin <cmarrin@apple.com> wrote:

On Oct 17, 2012, at 6:04 PM, Gregg Tavares (社用) <gman@google.com> 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.

I like the idea of sharing a context across canvases, although I think there are issues with all the proposals that have been made in this thread.

What we're really talking about here is making it possible to have multiple framebuffers in the context be attached to canvases. In the WebKit implementation, the framebuffer associated with the canvas is just another FBO which we send out to the page as needed. These FBO's do have a specially prepared RenderBuffers, but that's all done at setup time.

For us the getContext call does two completely separate things. It creates an actual GL context, and then creates an FBO associated with the canvas for which the context was created. So separating those two functions would be easy.

So maybe we keep getContext() as a composite operation (and for compatibility). But then we create two new methods on the WebGLRenderingContext:

WebGLRenderingContext createContext();
WebGLCanvasFrameBuffer createCanvas(HTMLCanvasElement, WebGLContextAttributes);
void bindCanvasFrameBuffer(WebGLCanvasFrameBuffer);
WebGLCanvasFrameBuffer currentCanvasFrameBuffer();

So this:

ctx = WebGLRenderingContext.createContext();
canvasFB = ctx.createCanvas(canvas, attrs);
ctx.bindCanvasFrameBuffer(canvasFB);

Would be the same as:

ctx = canvas.getContext("webgl", attrs);
canvasFB = ctx.currentCanvasFrameBuffer();

This essentially inverts the current API, which I like because it avoids any changes to the HTMLCanvasElement API. It also avoids adding parameters to WebGLContextAttributes, which would not be a very strongly typed approach.

This would also allow us to create a WebGL context not associated with any canvas, allowing pure offscreen rendering.