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

Re: [Public WebGL] getContext multiple context language

On 1/26/2010 1:26 PM, Kenneth Russell wrote:
On Tue, Jan 26, 2010 at 1:09 PM, Vladimir Vukicevic
<vladimir@mozilla.com> wrote:
On 1/26/2010 1:04 PM, Vangelis Kokkevis wrote:

On Tue, Jan 26, 2010 at 12:41 PM, Kenneth Russell<kbr@google.com> wrote:
On Mon, Jan 25, 2010 at 4:00 PM, Vladimir Vukicevic
<vladimir@mozilla.com> wrote:
Ok, here's some updated text... how's this look?

object getContext(in DOMString contextId, in optional any attributes)

'contextId' must be a string naming a canvas rendering context to be
returned.  For example, this specification defines the '2d' context,
if requested, will return either a reference to an object implementing
CanvasRenderingContext2D or null, if a 2D context cannot be created at
time.  Other specifications may define their own contexts, which would
return different objects.

If getContext() is called with a contextId that the implementation
and such a context can be created, a reference to an object implementing
context API is returned and the new context is added to the list of
contexts for this canvas.  If contextId is not supported or it cannot be
created, null is returned.  The optional 'attributes' parameter must be
either null, or an object specific to the context being requested.  A
or unspecified value for the 'attributes' parameter is equivalent to
requesting default attributes for the given context.  Any unknown
should be ignored by the context.

If the canvas has at least one active context and getContext() is called
with a contextId that names an already-active context, it must return
same resulting context object provided that the attributes are identical
all previous requests for that context ID. If the attributes are not
identical, getContext() must raise an INVALID_STATE_ERR exception. (XXX
INVALID_STATE the right thing here? or is SYNTAX_ERR better?) Deciding
which attributes are identical is up to the specific context being
requested, but should mean that the requested attributes and their
are the same as in all previous getContext() calls with this contextId.
I think it would be better if the attributes were ignored for the
second and subsequent requests for a given contextId. The context
creation attributes, at least in the case of WebGL, are a request,
rather than a requirement, of capabilities. If a given platform
happens to not support multisampling, then the return value of
WebGLRenderingContext.getContextAttributes() will contain "false" for
its "antialias" attribute, regardless of whether the user requested
antialiasing during the Canvas.getContext() call.
One thing that I have on my todo list (it's actually done, just need to make
sure I don't screw up the svn line endings) is to change the webgl
attributes object a bit -- we changed 'antialias' to 'antialiasHint', and
made the other non-Hint attributes requirements... that is, if you request
stencil, you either get a context with a stencil buffer, or null. For the
Hint attributes, you can get anything, but you indicate your preference.
I thought from earlier discussions that we were going to stay closer
to WGL's (and Mac OS X's) approach to the matching of the attributes
than that of GLX. In WGL, the pixel format best matching the requested
attributes is returned, while in GLX, if any one of the requested
attributes can't be satisfied, glXChooseVisual / glXChooseFBConfig
fails. GLX's behavior is too stringent in my experience. If we do
this, then it isn't necessary to change the naming of any of the
attributes in WebGLContextAttributes.

In particular, I don't like the idea that we are mandating the
presence of the stencil buffer by default. This would mean that all
current WebGL implementations are not spec compliant.

That's a good point; but I'd rather fix that by changing the defaults in the spec. Things like stencil and depth buffer seem like hard requirements for an app to me; I guess if a stencil buffer isn't available an app could use a different algorithm in some cases, but if the app does have that option then it could just retry the getContext() call. I realize that this gets into the somewhat ugly gl attribs loops that are found in C, but it's either that or requiring every app to ensure that, for example, it got a depth buffer. Seems that the simplest code would be for an app to request some basic capabilities, such as depth and maybe stencil, and require that it gets those; antialiasing is the outlier here, since the app would run just fine without AA... thus the 'Hint' status.

One thing that I didn't do here but might be a good idea is to move
getContextAttributes(contextId) to the canvas itself, as opposed to putting
it on the context. That seems to be better symmetry.
Perhaps. For convenience though it seems helpful to retain
getContextAttributes() on the context object itself.

If we require that the attributes must be identical during all
requests, then exactly what version of the attributes need to be
passed? The originally requested ones, which might not have been able
to be honored, or the actual attributes that were satisfied by the

For this reason I strongly think that it would be a mistake to pay
attention to the attributes on second and subsequent getContext()
calls. Here is suggested re-wording:

"If getContext() is called with a contextId that names an
already-active context, it must return the same resulting context
object. In this case, the attributes, if any, are ignored."

I agree with Ken's suggestion.  If the point of being able to call
getContext() multiple times is to avoid having to pass the context object
around then requiring every call to use the same arguments seems to negate
that benefit (you would have to pass the arguments around instead).  It also
possibly creates an expectation that by passing a different set of arguments
you could modify an existing context which we know it's not what happens.

It would be simpler, but the latter bit is exactly what worries me -- if the attributes are just silently ignored, then the user might think that a switch took place.

What about a third alternative: attributes are invalid on a getContext()
call for an already-active context? That is, any subsequent getContext call
must not specify any attributes?
I think this will lead to problems when composing multiple libraries
that all use WebGL, so I still think the attributes should just be
ignored on the second and subsequent getContext() calls. Well-written
libraries will check the context attributes and ensure that they got
all of the features they require; but the vast majority of libraries
that don't will still work, and interoperate cleanly.

Hmm, that's exactly the problem that I was trying to solve by requiring the attributes to always be passed... that is, if library A requests some attributes, and library B requests other attributes, library B won't have any option but to fail if it inspects the attributes after the fact.. or it would have ignored them in the first place.

However, really, I want to strongly discourage people from using getContext(); I'd like authors to call getContext once and then pass around the context object. The language that's in there currently about requiring the same attributes is an oblique way at encouraging that. If we didn't already have code using getContext("2d") all over the place in rendering loops, I'd push for making it illegal to call getContext more than once with the same context name. I don't think the point of being able to call getContext() multiple times is necessarily to avoid having to pass around the context... you'd still have to pass around the canvas element.

I still think the safest option is to require that the same set of attributes is specified in each call -- silent-ignore behaviour for something like this seems wrong, and my suggested error-if-specified-at-all behaviour is really just a bandaid for that problem.

We can try to craft another alternative:

- First call to getContext -- unspecified attributes means defaults, specified as given.
- Subsequent calls to getContext -- unspecified attributes means "give me what's there", specified as given, error if specified isn't a subset of currently active attributes.

That doesn't discourage using getContext() multiple times, but it gets rid of any silent-ignore behaviour, and gives libraries a way to interoperate if they have no specific attribute requests.

    - Vlad

You are currently subscribe to public_webgl@khronos.org.
To unsubscribe, send an email to majordomo@khronos.org with
the following command in the body of your email: