[whatwg] Challenging canvas.supportsContext

Ian Hickson ian at hixie.ch
Fri Sep 27 15:07:40 PDT 2013

On Thu, 5 Sep 2013, Benoit Jacob wrote:
> 2013/9/3 Ian Hickson <ian at hixie.ch>
> >
> > The long and short of this is that I renamed "supportsContext()" to 
> > "probablySupportsContext()". It's already implemented in WebKit
> And that's the real cost of having accepted supportsContext too early in 
> the HTML spec.

I'm not sure I would characterise it as a cost.

> > Fundamentally, it addresses a need that none of the other proposals 
> > addressed: how to know whether or not you can expect to be able to do 
> > 3D. It's not 100% reliable, but then neither would actually attempting 
> > to create a context, because creating a context is so expensive on 
> > some platforms that some UAs are going to move to doing it lazily
> The only conformant way to do lazy context creation would be to have 
> getContext return lost contexts, but given that only a tiny minority of 
> real-world code cares about that concept, that's not going to be 
> feasible in the foreseeable future. Maybe in a few years, 
> optimistically.

You could implement lazy context creation by just returning optimistically 
and if you later find you can't actually create what was requested, 
pretending you lost the context.

Or, the spec could be changed.

But yes, that's the problem. That's why we need this feature.

> > On Wed, 19 Jun 2013, Benoit Jacob wrote:
> >
> > > However, that only shifts the question to: what is the reason for 
> > > them to expose such APIs? In the end, I claim that the only thing 
> > > that we should recognize as a reason to add a feature to the HTML 
> > > spec, is *application* use cases.
> >
> > Oh well the use case for knowing whether or not 3D is supported on a 
> > particular device is straight-forward: you want to know which set of 
> > assets and logic to download and run.
> Application developer wants things. But these are not necessarily good 
> ideas, because they may not reflect how things really work.


> > > So let's look at the naive application usage pattern for supportsContext:
> > >
> > >   if (canvas.supportsContext("webgl")) {
> > >     context = canvas.getContext("webgl");
> > >   }
> > >
> > > The problem is that the same can be achieved with just the 
> > > getContext call, and checking whether it succeeded.
> >
> > Suppose you have an app that has a 3D feature, but it's not 
> > immediately used upon startup. For example, a preview window that is 
> > displayed on request. You want to preload all the code to run the 
> > preview window, but you need to load different code based on whether 
> > the device can do 3D or not. So the use case is more:
> >
> >    if (canvas.supportsContext("webgl"))
> >      load3DCode();
> >    else
> >      load2DCode();
> >
> >    // 3D code:
> >    function run() {
> >      context = canvas.getContext("webgl");
> >      // ...
> >    }
> If now application developers call probablySupportsContext, it returns 
> true, they start downloading the WebGL assets, but getContext("webgl") 
> fails, their application startup experience will be wose, which will 
> pressure browser developers to optimize the accuracy of 
> probablySupportsContext, but that's going to be hard and unrewarding.

This is a rare case, and it's a rare case that can happen even with using 
getContext() twice instead of probablySupportsContext() and getContext().

> Instead, they should do their actual getContext call --- the one 
> creating the context that they will actually want to use --- right at 
> the beginning of their application startup, and download the right 
> assets based on the outcome of that getContext.

Sure, but we've repeatedly heard application developers say that's not 
going to happen, so...

> The downside of course is that assets download becomes gated on getContext
> returning. But in practice that's not too bad:
>  - Only the first getContext in a browser sessing can be really slow (say
> 100 ms), subsequent ones tend to take less than 5 ms --- not that much
> compared to the time to download big assets.
>  - If any assets are shared between the two code paths, they can be
> downloaded first while getContext is running.

We might not consider it too bad, but we have heard other people say it's 
too bad.

> > You don't want to pay the cost of creating a throw-away 3D context on 
> > startup just to know which scripts to load. It defeats the whole point 
> > of not loading all the code up-front.
> I'm not talking about having any throw-away 3d contexts just for 
> testing. I understand that modernizr has an API that would force it to 
> be implemented in that way. In my view, that makes it a bad API. There 
> should be only one context, the one that we actually want to use.

Well, as much as I agree with you, we still have to take author needs into 
account. Take the example I gave above, with a preview window. The 
<canvas> that you'll be drawing on might not exist yet. The entire 
fragment of the document, or indeed, the entire <iframe> containing the 
relevant document, might not exist yet.

> > > Outside of exceptional cases (out of memory...), the slow path in 
> > > getContext is the *success* case, and again, in that case a real 
> > > application would want to actually *use* that context.
> >
> > Not necessarily, as noted above. The <canvas> you're going to draw to 
> > might not even exist at the point you need to know if it's 3D or not.
> Precisely, that's my point: don't cater to the pathological 
> use-a-separate-throwaway-context use case, instead assume that people 
> are smart and that if the first getContext succeeds, they will use that 
> context.

Assuming that people are "smart" when they have told us explicitly that 
they want to do something "not smart" is not a winning strategy.

Also, I don't think "smart" is the right way to think of this. Consider 
someone who is using a self-contained 3D library that creates the <canvas> 
and handles lost contexts and so on. They also have a totally separate 2D 
library that creates its own <canvas> and so forth. And they have a 
sniffing library that they use to decide which to use. Realistically, it's 
quite likely that these libraries have never heard of each other and do 
not support handing off canvas elements and contexts to each other. The 
person writing this code might not know anything about contexts, either. 
It's not that they're not "smart", it's that they don't know this stuff.

> > > Keep in mind that supportsContext can't guarantee that if it returns 
> > > true, then a subsequent getContext will succeed.
> >
> > Sure. getContext() can't guarantee that if it returns a context, the 
> > context will work forever, either.
> Indeed, there is some non-determinism inherent to how GPUs work.
> I'm just talking about not adding more non-determinism to it.

I don't think this adds more, really. If probablySupportsContext() returns 
true, then most of the time, so will getContext(). Just like if 
getContext() returned non-null, it likely will again.

> > > Given such deep problems, I think that the usefulness bar for 
> > > accepting supportsContext into the spec should be quite high.
> >
> > The problem is that there's no alternative solution.
> As I've been advocating, there is a more reasonable alternative which is 
> not to have anything else than getContext.

That is only a reasonable alternative if we ignore the feedback we're 
getting from Web developers.

> (I want to be clear that the long delay hinders my ability to continue 
> this conversation. I'm just one regular Mozilla developer --- I'm not 
> supposed to be spending a lot of time discussing the canvas standard, 
> and right now, I can't really afford to. Back when I started this thread 
> in june, I did have some time to invest in a long conversation on this. 
> Right now I don't.)

Feel free to wait until you have time to reply. Fundamentally, I can't 
reply to all incoming mail immediately; I reply to it mostly on a 
first-come-first-served basis, grouped by threads. Sometimes I have a few 
months of lag. I don't know what I could do about this.

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