[whatwg] Challenging canvas.supportsContext

Benoit Jacob jacob.benoit.1 at gmail.com
Thu Sep 5 18:39:51 PDT 2013


(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.)

Some partial inline responses below.

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.


> 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.


>
>
> On Wed, 19 Jun 2013, Benoit Jacob wrote:
> >
> > I'd like to question the usefulness of canvas.supportsContext. I tried to
> > think of an actual application use case for it, and couldn't find one.
>
> The use case is libraries like Modernizr that want to do feature detection
> up-front, but don't want a high performance hit on startup.
>
>
> > 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. More below.


>
>
> > 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.

So my best hope is that application developers don't use
probablySupportsContext.

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.

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.


>
> 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.


>
>
> > 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.


>
>
> > 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.


>
> > 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.

Benoit



More information about the whatwg mailing list