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

Re: [Public WebGL] Addition to WebGLContextLostEvent wrt extensions

On Tue, Apr 6, 2010 at 7:03 PM, Cedric Vivier <cedricv@neonux.com> wrote:
On Tue, Apr 6, 2010 at 16:08, Gregg Tavares <gman@google.com> wrote:

for (var ii = 0; ii < 1000; ++ii) {
  var tex = ctx.createTexture();
  ctx.bindTexture(ctx.TEXURE_2D, ctx);
  ctx.texImage2D(ctx.TEXTURE_2D, 0, someArrayOf16x16Imgs[ii]);

Assume that at ii = 120 the context is lost.
Assume that at ii = 140 the context is restored.

If the context magically restores itself on WebGLContextRegainedEvent or WebGLContextRestoredEvent then how do I know that textures 120 through 139 are bad and how do I now get rid of 140 to 999 so I can restart my app by calling my init function?

I don't think this is an issue at all in WebGL due to the simple single-threaded event model of _javascript_.
Afaik contrary to C-like signals which are preemptive, once the loop is started it will have to finish before _javascript_ can handle any WebGLContextLostEvent or WebGLContextRestored event.
If the context is lost at 120, the loop will continue and quickly generate GL errors at every subsequent call until it stops; then when the current _javascript_ chunk has been completed the registered WebGLContextLostEvent handler will be ran then the WebGLContextRestored handler, which will likely restart the whole loop again (assuming this loop is in e.g init).

The WebGLContextLostEvent and WebGLContextRestored event may be single threaded but GL itself is not. The user can press the hibernate button at any time.  If the model is WebGL restores its self which is what WebGLContextRestored suggests that this is a real case. I can keep trying to come up with examples where the context going from bad to good without app control is bad idea.

*) ctx.isContextLost() : Good, also useful. Let's me distinguish between gl.getError() == gl.INVALID_OPERATION as a true error and as a response to a lost context. Personally I'd prefer gl.getError() return gl.CONTEXT_LOST but that would require getting the OpenGL ES people to add an enum where as ctx.isContextLost() let's us avoid asking for the new enum value to be added.

gl.CONTEXT_LOST error sounds like a great idea!
It makes error checking simpler and faster (one check instead of two, at least).
Wouldn't it be a good idea to reserve one block or two for WebGL usage anyways? Whether it is for CONTEXT_LOST or for future additions (including for WebGL-specific extensions).

The suggested solution is that ctx.getActiveUniform has to return some kind of dummy WebGLActiveInfo if the context is lost.
This same issue is true in other places.  ctx.readPixels must always turn a WebGLArray even if the context is lost.
ctx.getParameter, ctx.getBufferParameter, ctx.getFramebufferAttachmentParameter, ctx.getShaderParameter, ctx.getUniform, get.getVertexAttrib all have this issue as well.

Actually readPixels should return a zero-length array, it would make user code simpler and more robust (e.g devs might forget to check nullity and start a loop "i < array.length" on it for instance - with zero-length array all null reference expressions are avoided and correctly written code should not even have to bear out of bounds errors).

The problem with a zero length array is it has to be programmed for and it doesn't match OpenGL.  In OpenGL I'd do this

   static const char buffer[8*8*3];

   glReadPixels(0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, buffer);

   // do something with 8x8 RGB pixels.
   printf ("the red value of pixel at 7x7 is %d\n", buffer[(7*8+7)*3]);

Most programs don't care if there was an error. The buffer will be zero or the contents of the last successful glReadPixels.

In WebGL the same should be true.

   var buf = ctx.readPixels(0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE);
   document.write("the read value of pixel at 7x7 is " + buffer[(7*8+7)*3]);

It seems to me, in the spirit of GL that should not throw because (7*8+7)*3 is out of range nor should it return undefined. This is not hard.  Otherwise, lots of experienced GL authors are going to be writing code that will break in subtle edge cases. Handling lost context is hard enough but not that hard. But if certain WebGL calls require tests that are not required in OpenGL then it seems like there will be lots of incorrect programs.

For this particular case of readPixels the WebGL implementations are already required to return out of range pixels as 0,0,0(0) so if an implementation can internally consider the valid range to be 0,0 if the context is lost and the code that's already handling the required out of range pixels will do the right thing.

For other cases the "dummy object" sounds like a possible solution though it sounds confusing indeed.

Yes, testing conformance will be even harder without a way to force a lost context.