[whatwg] [canvas] Proposal for supportsContext

Ian Hickson ian at hixie.ch
Mon Oct 22 16:36:33 PDT 2012

On Mon, 10 Sep 2012, Dean Jackson wrote:
> I propose adding a new method to HTMLCanvasElement:
> interface HTMLCanvasElement : HTMLElement {
>   boolean supportsContext(DOMString contextId, any... arguments);
> };
> supportsContext takes the same parameters as getContext, and simply 
> returns true if the corresponding call to getContext would have returned 
> a valid context, false otherwise.
> The justification for this method is that it is sometimes expensive to 
> create a context. Many authors test for a canvas feature by trying to 
> create a context, examining the return value, and doing something 
> different if the context was null. This is ok in most cases, but there 
> are some instances where we don't want to create a context unless the 
> page is really going to make use of it.
> To give a real world example, the popular tool Modernizr tests for the 
> availability of WebGL by attempting to create a WebGL context. This can 
> happen even on pages that have no intention of using WebGL - an author 
> has just inserted Modernizr into their page and is using it to test for 
> another feature. As I said, creating a context is not a free operation. 
> In fact, on shipping Safari (Mountain Lion) this causes us to switch to 
> a more powerful GPU on systems that have two graphics processors.


On Mon, 10 Sep 2012, Tobie Langel wrote:
> What about enabling feature detection by providing a method per context?
> interface HTMLCanvasElement : HTMLElement {
>   object get2DContext();
>   object getWebGLContext(any... args);
> };
> That way, developers can use idiomatic JS for feature testing like
> pretty much everywhere else on the Web platform:
> if (canvas.get2DContext) {
>   // do stuff with 2D canvas
> }

I think that ship has sailed, what with there being multiple 
implementations of the old way.

On Mon, 10 Sep 2012, Ashley Gullen wrote:
> On the other hand I would love to see a supportsContext function which can
> tell if WebGL is software rendered (i.e. Swiftshader in Chrome).  There's
> been a lot of discussion about that and how to define it, but in our
> experience 2D games rendered with Swiftshader are far slower than rendered
> with a software-rendered 2D canvas.  We have production code in the wild
> which detects Swiftshader by its supported WebGL extensions.  I'd love to
> replace this even with something vendor specific, like:
> canvas.supportsContext("webgl", { "-webkit-allowswiftshader": false })
> Despite the hardness to define it, I do feel there is a practical need for
> this.

Interesting idea.

I've made supportsContext() take the same arguments as getContext(), but 
obviously "-webkit-allowswiftshader" would be a proprietary value so it's 
not specced.

On Mon, 10 Sep 2012, Ashley Gullen wrote:
> I think browser makers would still be tempted to implement
> supportsContext() in terms of creating a context and seeing if there's an
> error, since that's the only way to be 100% sure the answer is correct.

Obviously browser vendors can do what they want... but one would guess 
that at least Apple won't do that since they requested the feature for the 
very purpose of not doing that. So this:

> This does not really solve anything.

...seems like unwarranted cynicism. :-)

> Also, realistically, any web app actually interested in using WebGL will 
> first create a WebGL context, and if that fails then fall back to 
> something else, so I'm not sure Modernizr actually need a better test 
> for this than their new fixed code.

Well there's still a use case for feature-test code pre-emptively figuring 
out what is supported, presumably.

> Perhaps an approach could be taken similarly to HTMLMediaElement's
> canPlayType().  supportsContext() could return a string, which is one of:
> "probably" - the context appears to be supported (but this is not a
> guarantee)
> "maybe" - it is impossible to tell whether the context is supported without
> creating it.
> "" (empty string) - the context is definitely not supported.
> This avoids returning a simple true/false which implies some kind of
> guarantee in the true case.

I don't really understand the difference between "maybe" and "probably" in 
this case.

> "slow" or "software-rendered" or "emulated" or some other term that 
> needs careful definition: context can definitely be created but uses 
> software rendering, e.g. meaning Chrome's SwiftShader will be used for 
> WebGL, or possibly that the user's system does not support 
> hardware-accelerated canvas "2d".  Since this can apply simultaneously 
> with "yes", perhaps it could also return "yes emulated" or similar.

That's an interesting idea. Not sure if it's better or worse than the 
proprietary flags mentioned earlier... it's probably not as fine-grained 
in practice.

On Mon, 10 Sep 2012, Glenn Maynard wrote:
> If you really want to protect users from the behavior of pages, you'd 
> really need to make creating the context cheap.  For example, don't 
> switch to a high-power GPU until the page actually draws something, 
> and--since many pages use both Canvas and WebGL for one-shot 
> rendering--be sure to switch back to the low-power GPU after some idle 
> time.

That does seem like a somewhat better implementation strategy, if viable, 
but doesn't preclude the supportsContext() feature.

Ian Hickson               U+1047E                )\._.,--....,'``.    fL
http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'

More information about the whatwg mailing list