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

Re: [Public WebGL] Addition to WebGLContextLostEvent wrt extensions





On Fri, Apr 16, 2010 at 4:35 PM, Cedric Vivier <cedricv@neonux.com> wrote:
On Fri, Apr 16, 2010 at 14:27, Gregg Tavares <gman@google.com> wrote:
I disagree that it's a bad example. Its a very normal and common OpenGL pattern.  And I don't see how making reset only accessable inside the event helps anything. Using events will make the example 3-5x larger. I don't see that as "simple".

Consider :

function start() {
load();
canvas.addEventListener("webglcontextrestorable", function (evt) { evt.restoreContext(); load(); });
setRenderCallback(mainLoop, 60hz);
}
function mainLoop() {
//...
}


This has actually 50% less code and removes conditional branches, not 3-5x larger and not more complex in any way.
And no, I don't see how attempting to reset context manually in the main loop simplifies anything with regards to asynchronous resource loading, such callbacks may still complete while the context is lost and has not been yet restored... it should not be a problem anyways, callback will just fail fast and another loading will be initiated when context is restored.

Can you write that sample?

The problem as I see it is with ContextRestored, my async functions all need to be tracked and dealt with since I have no control whether they complete on the restored context or the lost context.  That's what I meant by 3x-5x.

With Reset, once I get to mainLoop I know all the async init functions have finished and every one of them was on the lost context so I know I can safely call reset and start them all over and they will all happen on the new restored context.

If I'm missing the simple solution for that with ContextRestored then a sample would make that much clearer.

Here's the async version with reset

function start() {
  asyncInit(callbackWhenAllLoadingHasFinished());
}

function callbackWhenAllLoadingHasFinished(
  setRenderCallback(mainLoop, 60);

}

function mainLoop() {
  if (context.isContextLost()) {
    if (context.reset()) {
      clearRenderCallback();
      start();
    }
  }
}
 


By following the logic that events are complicated and unnecessary (since there is a "normal and common OpenGL pattern" that do not need them) then we could go as far as saying that WebGL should not provide LostEvent and RestorableEvent in the first place ?
Indeed developers could very well only use the technique in your example to simulate the events : poll isContextLost() at every frame then when context is lost possibly run some code (equivalent to the LostEvent handler) and then start an timer that tries to restore the context at periodic intervals.

Even if it's a "normal and common OpenGL pattern" which works well for game loops on desktop and/or specific devices, this does not apply in the context of WebGL imho because _javascript_ development is inherently event-based (ie. a WebGL "game loop" is actually not a loop - events might and will happen between renders) and the technique is not as generic as events :
- it does not work well with non-interactive apps that do not render frequently (the app would not have polled and would not know the context has been lost => the canvas would remain black until the next render is scheduled - if ever)
- it does not allow WebGL implementations to use efficient platform-specific mechanisms (e.g PM events) to avoid any polling when possible.

Nothing about reset() requires polling (if polling = constantly checking or lost context). 
 


There is another possibility we haven't discussed yet, which would not use events at all yet avoid polling and the need for a manual reset() :

interface WebGLRenderer {
    void contextLost(in WebGLContext context);
    void contextRestored(in WebGLContext context);
    void render(in WebGLContext context);
}

This is again inspired from Android's GLSurfaceView, using an interface like this provides synchronization guarantees that events cannot, the spec can define that the render function is invoked only after contextRestored when context is restorable.

I don't see how that helps. You still have the issue of the context getting lost and restored during initialization.
 


Regards,