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

Re: [Public WebGL] Help with the WebGL Context Lost specification

Note that this message uses HTML formatting.  Careful use of formatting helps spec readability a lot, and I strongly recommend reading this message in its formatted form, even if you normally view email in plain text.

Sorry that this became so long.

On Sat, Nov 12, 2011 at 6:23 AM, Gregg Tavares (wrk) <gman@google.com> wrote:
We're trying to finalize the WebGL specification for how context lost is handled

Not being a spec writer and not being familiar with every nuance of the HTML5 specs we're having a hard time figuring out the exact wording to attempt to make it 100% clear what needs to happen

Based on Cedric's changes my latest attempt is here:


I'd previously sketched out language for context creation, context loss and context restoration during earlier discussions, but they never came to any decision so I never finished them.  This is based on one version of that.  I do think those three things should be specced together, since they're tightly linked.

(cut here)

Each WebGLRenderingContext has a drawing buffer lost flag, which is initially unset.
Each WebGLRenderingContext has an associated canvas, set upon creation, that is a canvas.
Each WebGLRenderingContext has context creation parameters, set upon creation, which is an object.

To fire a WebGL context event named e means that an event using the WebGLContextEvent interface, with its type attribute initialized to e, and its isTrusted attribute initialized to true, is to be dispatched at the given object.

When the getContext() method of a canvas element is to return a new object for the contextId webgl, the user agent must perform the following steps:

1. Create a new WebGLRenderingContext object, context.
2. Let context's canvas be the context the getContext() method is associated with.
3. If getContext() was invoked with a second argument, options, let context's context creation parameters be options, otherwise let it be the empty object, {}.
4. Create a drawing buffer using the settings specified in context's context creation parameters, and associate the drawing buffer with context.
5. Return context.

When the user agent detects that the drawing buffer associated with a WebGLRenderingContext context has been lost, it must run the following steps:

1. Let canvas be the canvas object associated with context.
2. If context's webgl context lost flag is set, abort these steps.
3. Set context's webgl context lost flag.
4. Invalidate all WebGLObject instances, such as textures and buffers, that have been created by this context (ie. is queries return false).
5. Queue a task to perform the following steps:
5.1. Fire a WebGL context event named "webglcontextlost" at canvas, with its statusMessage attribute set to "".
5.2. If the event's canceled flag is not set, abort these steps.
5.3. Perform the following steps asynchronously.
5.4. Await a restorable drawing buffer.
5.5. Restore the drawing buffer.

When the user agent is to restore the drawing buffer, it must queue a task to run the following steps:

1. Let canvas be the canvas object associated with the WebGLRenderingContext.
2. If canvas's webgl context lost flag is not set, abort these steps.
3. Create a drawing buffer using the settings specified in context's context creation parameters, and associate the drawing buffer with context, discarding any previous drawing buffer.
4. Clear canvas's webgl context lost flag.
5. Fire a WebGL context event named "webglcontextrestored" at canvas, with its statusMessage attribute set to "".

(cut here)


Formatting above roughly emulates the rendering of HTML specs, highlighting flags, variables, types and algorithms.  Algorithms should be links (either to the algorithm, or to a normative reference); they're not actually italicized in HTML specs.

Using abstract flags like webgl context lost flag allows being much more precise about its side-effects.  Instead of these algorithms needing to monkey-patch things which are defined elsewhere ("now that the context is lost, these things happen..."), the definitions for the things affected by the flag simply use it directly.  This way, each function's definition isn't scattered around in a bunch of different places.  This removes eg. "isContextLost returns true"; instead, isContextLost's definition would say "Return true if webgl context lost flag is set, otherwise return false."  If you don't want to adjust every call spec to handle the "are no-ops" and "return null" cases (that would be precise but tedious), then perhaps the beginning of 5.13 would be an appropriate place to put those.

Step 4 ("invalidate...") is loose.  It would be more precise to set a flag on each object (eg. a lost object flag), and (as above) where queries, etc. are defined, say "if the lost object flag is set, return false; otherwise...".

I've used "drawing buffer" to refer to the underlying OpenGL context, to avoid using the word "context" for multiple things.  (HTML specs regularly do this, intentionally using different terms to make separate concepts easier to distinguish.)

Canceled flag is defined in DOM4.  http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#events
Return a new object for contextId is defined in HTML. http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#getcontext-return

The events here aren't actually "fire a simple event", since it uses the WebGLContextEvent interface.  I've defined "fire a WebGL context event" for this.  This also fixes WebGLContextEvent not actually being used.  The language comes from DOM4.

The "interrupting" nature of losing a context is something that most web APIs are very careful to never allow.  Since it's (practically) unavoidable here, careful attention should be given to what its visible effects are.  I havn't yet done this.  Setting webgl context lost flag, and "invalidating instances", should happen atomically from the perspective of _javascript_ code.  There may be no language in HTML specs to copy for this, since other APIs never do this.  It should appear to the caller as if we take a lock at step 2 (of context loss), release it after step 4, and all other WebGL entry points hold that lock.  I mention this now, but let's iron out the simpler parts first.

Context creation parameters are another missing detail.  This should probably be specified as a WebIDL dictionary, in the way that Event initializers are, and a copy should be stored to prevent it from being changed by the caller later.  We can come back to that later, too.

(There are probably more details, but this has gone too long as is so I'll stop here for discussion.)

Glenn Maynard