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

Re: [Public WebGL] Addition to WebGLContextLostEvent wrt extensions

On Sun, Apr 11, 2010 at 11:45 PM, Cedric Vivier <cedricv@neonux.com> wrote:
On Sat, Apr 10, 2010 at 04:45, Gregg Tavares <gman@google.com> wrote:
On Sat, Apr 10, 2010 at 1:12 AM, Chris Marrin <cmarrin@apple.com> wrote:
Sounds like your concern is what happens if you lose the context near the start of your asset loading and it gets restored before most have loaded. Then you'd see most but not all assets loaded and the error would (possibly) be less obvious. That's a good concern.

Though I understand Gregg's concerns I think the discussed racy scenario isn't possible with minimally carefully written code.
Consider this pseudo-code (using textures here but it would be similar with external shaders etc) :

tex_metal = gl.createTexture();
img = new Image();
img.src = "">
img. { handleLoadedTexture(img, tex_metal); }

function handleLoadedTexture(image, texture) {
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texImage2D(gl.TEXTURE_2D, 0, image);

When an asset has completed loading after context has been lost and restored, the associated WebGL object  (here WebGLTexture tex_metal) has already been invalidated, which means the data cannot be loaded in GL since ctx.bindTexture will generate an INVALID_OPERATION error as the WebGL object created in previously valid context is invalid.
In the end it results in the same behavior as with Resetable+reset() : all-or-nothing visible.

Afaik the racy scenario is only possible with code similar to this :

img = new Image();
img.src = "">
img. { handleLoadedTexture(img); }

function handleLoadedTexture(image) {
    var texture = gl.createTexture(); //! WebGL object created in the event handler
    engine.registerTexture("metal", texture); // some mechanism to inform upstream code that this texture object is to be used as metal texture
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texImage2D(gl.TEXTURE_2D, 0, image);

This latter example is indeed racy but as far as I can see it would have similar issues as well with Resetable+reset() model.
Since it already requires added "complexity" to inform the 'engine' of the newly created WebGL objects I think that adding safeguards are not a problem, frameworks can handle this if they really prefer to do asynchronous loading this way, simple apps can (should?) use former 'safe' example.

These are great examples. I don't follow your conclusion though.  In the first example getting GL_INVALID_OPERATION in no way informs you that you happened to have lost the context for a moment during initialization. In the second example you'd get no error for the 1 texture case. You'd get errors for 2 more or textures assuming some of them were created before the context was lost and others after it was restored and again you'd just get GL_INVALID_OPERATION.

Where is with the Resetable/Reset method you'd get GL_CONTEXT_LOST on all those operations and any other operations until you choose to reset.


I think it would be possible and reasonable to keep the context invalid until the WebGLContextRestored event were serviced. That means the context would stay invalid forever if the author did not handle the WebGLContextRestored event, which is a good thing. And it would make the error obvious, as in your scenario.

Yes that would be ideal imho, but is this actually possible with current DOM2 Event implementations ?

If not easily possible/implementable then Resetable+ctx.resetContext() might well be a safer solution; I suggest though resetContext() to be a method of the WebGLContextResetableEvent interface. This way the method does not "pollute" the WebGLContext interface, does not need to return a boolean, and by-design prevents bad practice like "if (gl.isContextLost()) gl.resetContext()" in the main 'loop'.