Re: [whatwg] Challenging canvas.supportsContext
On Thu, 5 Sep 2013, Benoit Jacob wrote: 2013/9/3 Ian Hickson i...@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. Certainly. 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*
Re: [whatwg] Challenging canvas.supportsContext
(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 i...@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
Re: [whatwg] Challenging canvas.supportsContext
On 4 Sep 2013, at 10:47 am, Boris Zbarsky bzbar...@mit.edu wrote: On 9/3/13 7:13 PM, Ian Hickson wrote: Wouldn't checking for window.WebGLRenderingContext be just as unreliable then? I don't understand why it's ok to be able to test that, but why probablySupportsContext() wouldn't be ok. I'm a lot more OK with the probablySupportsContext naming than supportsContext here. I will update WebKit to probablySupportsContext asap. Dean
Re: [whatwg] Challenging canvas.supportsContext
The long and short of this is that I renamed supportsContext() to probablySupportsContext(). It's already implemented in WebKit (and dino says he's going to rename it in the implementation also). 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 and so you're back to exactly the same level of reliability as this API. Plus, it'd be a lot more awkward as an API. 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. 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); // ... } 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. 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. 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. The spec doesn't require it to, either. So if the existence of supportsContext misleads application developers into no longer checking for getContext failures, then we'll just have rendered canvas-using applications a little bit more fragile. That's a risk, yes. Another problem with supportsContext is that it's untestable, at least when it returns true; it is spec-compliant to just implement it as returning whether the JS interface for the required canvas context exists, which is quite useless. That would indeed be useless. 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. On Wed, 19 Jun 2013, Tab Atkins Jr. wrote: This is missing the point. You don't want to wait until it's actually time to create the context. Unless you torture your code flow, by the time you're creating a context you should already know that the context is supported. The knowledge of which context to use is most useful well before that, when you're first entering the app. Plus, it doesn't matter how late you do the detection - if you do a straight *detection* at all rather than an initialization (that is, if you throw away the context you've just created for testing), you'll still incur the start-up costs of spinning up a context. Doing that early or late doesn't matter too much - it's bad either way. Indeed. Like @supports, the supportsContext() method can be easy and reliable with a very simple definition for supports - it returns true if calling getContext() with the same arguments would return a context rather than erroring, and false otherwise. No capacity for lying there without breaking sites. At least, no capacity beyond the same one that getContext() has in the first place, namely that it might return a useful object that later stops working. On Wed, 19 Jun 2013, Kenneth Russell wrote: Additionally, though, application developers wanted to be able
Re: [whatwg] Challenging canvas.supportsContext
On 9/3/13 7:13 PM, Ian Hickson wrote: Wouldn't checking for window.WebGLRenderingContext be just as unreliable then? I don't understand why it's ok to be able to test that, but why probablySupportsContext() wouldn't be ok. I'm a lot more OK with the probablySupportsContext naming than supportsContext here. -Boris
Re: [whatwg] Challenging canvas.supportsContext
2013/7/31 Ian Hickson i...@hixie.ch On Wed, 31 Jul 2013, Benoit Jacob wrote: Ping --- I thought that there was sufficient agreement in this thread, around the fact that supportsContext, as currently spec'd and currently implementable, is a feature without a valid use case, that removing it from the spec is the right thing to do at this point. It's on my list of e-mail to get to. Sorry about the delay. I'm currently about six months behind on feedback that isn't blocked on other things. In this particular case, I should note that we have at least one implementation, and we have no alternative solution to the problem for which the feature was added. So it's not as clear cut as it might seem. As discussed in this thread, the alternative solution is to call getContext and check if it succeeded; I was arguing that if one wants something reliable and tightly spec'd, there is no alternative to doing the same amount of work; and I was also arguing against the notion that something more loosely spec'd (as supportsContext currently is) was useful to have. Benoit (Note that decisions for WHATWG specs aren't made based on consensus. Even if everyone agrees on something, if there's one more compelling argument to the contrary, that's the one that's going to win.) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Challenging canvas.supportsContext
On Fri, 2 Aug 2013, Benoit Jacob wrote: 2013/7/31 Ian Hickson i...@hixie.ch On Wed, 31 Jul 2013, Benoit Jacob wrote: Ping --- I thought that there was sufficient agreement in this thread, around the fact that supportsContext, as currently spec'd and currently implementable, is a feature without a valid use case, that removing it from the spec is the right thing to do at this point. It's on my list of e-mail to get to. Sorry about the delay. I'm currently about six months behind on feedback that isn't blocked on other things. In this particular case, I should note that we have at least one implementation, and we have no alternative solution to the problem for which the feature was added. So it's not as clear cut as it might seem. As discussed in this thread, the alternative solution is to call getContext and check if it succeeded That's not an alternative, that's the problem that this method was trying to fix in the first place. I was arguing that if one wants something reliable and tightly spec'd, there is no alternative to doing the same amount of work; and I was also arguing against the notion that something more loosely spec'd (as supportsContext currently is) was useful to have. Right -- that's why it's not clear cut. It's not just this is bad, we should drop it, or this is redundant, we should drop it, the questions are more subtle ones: is this problem worth solving, is the solution good enough, will it be implemented enough to be worth it, etc. I haven't studied the thread in enough detail yet to make an educated argument one way or the other. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Challenging canvas.supportsContext
Ping --- I thought that there was sufficient agreement in this thread, around the fact that supportsContext, as currently spec'd and currently implementable, is a feature without a valid use case, that removing it from the spec is the right thing to do at this point. Benoit 2013/7/18 Benoit Jacob jacob.benoi...@gmail.com The thread seems to have settled down. I still believe that supportsContext, in its current form, should be removed from the HTML spec, because as currently spec'd it could be implemented as just returning whether WebGLRenderingContext is defined. I also still believe that it will be exceedingly hard to spec supportsContext in a way that makes it useful as opposed to just calling getContext. Emails in this thread have conveyed the idea that it is already useful to return whether WebGL is at least not blacklisted, regardless of whether actual context creation would succeed. That, however, is impossible to specify, and depends too much on details of how some current browsers and platforms work: - driver blacklists will hopefully be a thing of the past, eventually. - on low-end mobile devices, the main cause of WebGL context creation failure is not blacklists, but plain OpenGL context creation failures, or non-conformant OpenGL behavior, or OOM'ing right after context creation. For these reasons, justifying supportsContext by driver blacklisting seems like encoding short-term contingencies into the HTML spec, which we shouldn't do. Besides, even if we wanted to do that, there would remain the problem that that's impossible to spec in a precise and testable way. For these reasons, I still think that supportsContext should be removed from the spec. Benoit 2013/6/19 Benoit Jacob jacob.benoi...@gmail.com Dear list, 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. It also doesn't seem like any valid application use case was given on this list when this topic was discussed around September 2012. The closest thing that I could find being discussed, was use cases by JS frameworks or libraries that already expose similar feature-detection APIs. 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. 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. In other words, I'm saying that no matter what JS libraries/frameworks may offer for feature detection, in the end, applications don't want to just *detect* features --- applications want to *use* features. So they'll just pair supportsContext calls with getContext calls, making the supportsContext calls useless. There is also the argument that supportsContext can be much cheaper than a getContext, given that it only has to guarantee that getContext must fail if supportsContext returned false. But this argument is overlooking that in the typical failure case, which is failure due to system/driver blacklisting, getContext returns just as fast as supportsContext --- as they both just check the blacklist and return. 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. Keep in mind that supportsContext can't guarantee that if it returns true, then a subsequent getContext will succeed. The spec doesn't require it to, either. So if the existence of supportsContext misleads application developers into no longer checking for getContext failures, then we'll just have rendered canvas-using applications a little bit more fragile. Another problem with supportsContext is that it's untestable, at least when it returns true; it is spec-compliant to just implement it as returning whether the JS interface for the required canvas context exists, which is quite useless. Given such deep problems, I think that the usefulness bar for accepting supportsContext into the spec should be quite high. So, is there an application use case that actually benefits from supportsContext? Cheers, Benoit
Re: [whatwg] Challenging canvas.supportsContext
On Wed, Jul 31, 2013 at 4:26 PM, Benoit Jacob jacob.benoi...@gmail.com wrote: Ping --- I thought that there was sufficient agreement in this thread, around the fact that supportsContext, as currently spec'd and currently implementable, is a feature without a valid use case, that removing it from the spec is the right thing to do at this point. Yours is not the only outstanding email thread: http://www.whatwg.org/issues/data.html It'll be okay ;-) -- http://annevankesteren.nl/
Re: [whatwg] Challenging canvas.supportsContext
On Wed, 31 Jul 2013, Benoit Jacob wrote: Ping --- I thought that there was sufficient agreement in this thread, around the fact that supportsContext, as currently spec'd and currently implementable, is a feature without a valid use case, that removing it from the spec is the right thing to do at this point. It's on my list of e-mail to get to. Sorry about the delay. I'm currently about six months behind on feedback that isn't blocked on other things. In this particular case, I should note that we have at least one implementation, and we have no alternative solution to the problem for which the feature was added. So it's not as clear cut as it might seem. (Note that decisions for WHATWG specs aren't made based on consensus. Even if everyone agrees on something, if there's one more compelling argument to the contrary, that's the one that's going to win.) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Challenging canvas.supportsContext
On Wed, Jul 31, 2013 at 11:05 AM, Ian Hickson i...@hixie.ch wrote: (Note that decisions for WHATWG specs aren't made based on consensus. Even if everyone agrees on something, if there's one more compelling argument to the contrary, that's the one that's going to win.) Though of course, what's considered compelling or not is often a judgement call. So what you are saying is that decisions for WHATWG specs are often made by the person editing the spec. / Jonas
Re: [whatwg] Challenging canvas.supportsContext
The thread seems to have settled down. I still believe that supportsContext, in its current form, should be removed from the HTML spec, because as currently spec'd it could be implemented as just returning whether WebGLRenderingContext is defined. I also still believe that it will be exceedingly hard to spec supportsContext in a way that makes it useful as opposed to just calling getContext. Emails in this thread have conveyed the idea that it is already useful to return whether WebGL is at least not blacklisted, regardless of whether actual context creation would succeed. That, however, is impossible to specify, and depends too much on details of how some current browsers and platforms work: - driver blacklists will hopefully be a thing of the past, eventually. - on low-end mobile devices, the main cause of WebGL context creation failure is not blacklists, but plain OpenGL context creation failures, or non-conformant OpenGL behavior, or OOM'ing right after context creation. For these reasons, justifying supportsContext by driver blacklisting seems like encoding short-term contingencies into the HTML spec, which we shouldn't do. Besides, even if we wanted to do that, there would remain the problem that that's impossible to spec in a precise and testable way. For these reasons, I still think that supportsContext should be removed from the spec. Benoit 2013/6/19 Benoit Jacob jacob.benoi...@gmail.com Dear list, 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. It also doesn't seem like any valid application use case was given on this list when this topic was discussed around September 2012. The closest thing that I could find being discussed, was use cases by JS frameworks or libraries that already expose similar feature-detection APIs. 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. 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. In other words, I'm saying that no matter what JS libraries/frameworks may offer for feature detection, in the end, applications don't want to just * detect* features --- applications want to *use* features. So they'll just pair supportsContext calls with getContext calls, making the supportsContext calls useless. There is also the argument that supportsContext can be much cheaper than a getContext, given that it only has to guarantee that getContext must fail if supportsContext returned false. But this argument is overlooking that in the typical failure case, which is failure due to system/driver blacklisting, getContext returns just as fast as supportsContext --- as they both just check the blacklist and return. 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. Keep in mind that supportsContext can't guarantee that if it returns true, then a subsequent getContext will succeed. The spec doesn't require it to, either. So if the existence of supportsContext misleads application developers into no longer checking for getContext failures, then we'll just have rendered canvas-using applications a little bit more fragile. Another problem with supportsContext is that it's untestable, at least when it returns true; it is spec-compliant to just implement it as returning whether the JS interface for the required canvas context exists, which is quite useless. Given such deep problems, I think that the usefulness bar for accepting supportsContext into the spec should be quite high. So, is there an application use case that actually benefits from supportsContext? Cheers, Benoit
Re: [whatwg] Challenging canvas.supportsContext
On Mon, 24 Jun 2013 23:31:59 +0200, Dean Jackson d...@apple.com wrote: Also, the presence of window.WebGLRenderingContext doesn't necessarily indicate that WebGL is supported. On iOS for example, that object is available in Safari but calling getContext('webgl') fails. The supportsContext method would allow authors to easily detect this case. Since supportsContext is not supported in Safari on iOS, authors cannot use it to detect this case at all. We could say in the spec that if a UA knows it cannot create a specific context, it must hide the corresponding interface object. This does basically the same thing as supportsContext, except that it would also work for pages that already do feature detection based on the interface object. -- Simon Pieters Opera Software
Re: [whatwg] Challenging canvas.supportsContext
On 25/06/2013, at 5:54 PM, Simon Pieters sim...@opera.com wrote: On Mon, 24 Jun 2013 23:31:59 +0200, Dean Jackson d...@apple.com wrote: Also, the presence of window.WebGLRenderingContext doesn't necessarily indicate that WebGL is supported. On iOS for example, that object is available in Safari but calling getContext('webgl') fails. The supportsContext method would allow authors to easily detect this case. Since supportsContext is not supported in Safari on iOS, authors cannot use it to detect this case at all. I think you missed the point. I know it's not there, which is why we suggested adding it :) We could say in the spec that if a UA knows it cannot create a specific context, it must hide the corresponding interface object. This does basically the same thing as supportsContext, except that it would also work for pages that already do feature detection based on the interface object. Showing or hiding interface objects is not something I want to do. Others on this thread said the same thing. Dean
Re: [whatwg] Challenging canvas.supportsContext
On Tue, 25 Jun 2013 21:01:27 +0200, Dean Jackson d...@apple.com wrote: Showing or hiding interface objects is not something I want to do. It's possible that I missed it, but, why not? There is precedent for doing so. For instance, in Opera 11, the WebSocket constructor was absent unless WebSockets were enabled in opera:config. This allowed feature detection like the following to work: var supports_websockets = WebSocket in window; Also, the HTML spec actually requires it: [[ When support for a feature is disabled (e.g. as an emergency measure to mitigate a security problem, or to aid in development, or for performance reasons), user agents must act as if they had no support for the feature whatsoever, and as if the feature was not mentioned in this specification. For example, if a particular feature is accessed via an attribute in a Web IDL interface, the attribute itself would be omitted from the objects that implement that interface — leaving the attribute on the object but making it return null or throw an exception is insufficient. ]] http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#extensibility -- Simon Pieters Opera Software
Re: [whatwg] Challenging canvas.supportsContext
On Tue, Jun 25, 2013 at 3:28 PM, Simon Pieters sim...@opera.com wrote: On Tue, 25 Jun 2013 21:01:27 +0200, Dean Jackson d...@apple.com wrote: Showing or hiding interface objects is not something I want to do. It's possible that I missed it, but, why not? There is precedent for doing so. For instance, in Opera 11, the WebSocket constructor was absent unless WebSockets were enabled in opera:config. This allowed feature detection like the following to work: var supports_websockets = WebSocket in window; Also, the HTML spec actually requires it: [[ When support for a feature is disabled (e.g. as an emergency measure to mitigate a security problem, or to aid in development, or for performance reasons), user agents must act as if they had no support for the feature whatsoever, and as if the feature was not mentioned in this specification. For example, if a particular feature is accessed via an attribute in a Web IDL interface, the attribute itself would be omitted from the objects that implement that interface — leaving the attribute on the object but making it return null or throw an exception is insufficient. ]] This is done if the feature is being disabled completely at page load time, with no chance of it coming back: you simply don't put the interface into the environment. WebGL is different, since it might go away after the page is already loaded (eg. the GPU blacklist is updated); going in and trying to remove the interface after the page is loaded would be weird. It might also become available after previously being unavailable (eg. video drivers are updated), in which case you'd have to go in and insert the interface. It also doesn't provide any way to query arguments to getContext, eg. to see if null would be returned if a particular option is provided, which supportsContext allows. (I don't know if there are any cases where this actually happens, since most options are best effort and don't cause context creation to fail if they're not available.) -- Glenn Maynard
Re: [whatwg] Challenging canvas.supportsContext
On Tue, Jun 25, 2013 at 10:28 PM, Simon Pieters sim...@opera.com wrote: On Tue, 25 Jun 2013 21:01:27 +0200, Dean Jackson d...@apple.com wrote: Showing or hiding interface objects is not something I want to do. It's possible that I missed it, but, why not? I have the same question. The whole hasFeature and isSupported disasters of DOM2 (or was it 3?) lead to us advocating, and a lot of websites switching to, patterns like: if (window.indexedDB) { x = indexedDB.open(...); ... } and if (window.WebSocket) { x = new WebSocket(...); } I.e. testing for features by checking if the DOM calls are available, not by creating separate functions that are supposed to tell you if a given feature is there or not. Granted, this is somewhat different since the interface object would act like a proxy to see if a feature is there, even though you generally don't use the feature through the interface object. But it's an interface object that should naturally be there if you implement the feature, and naturally not there if you don't. / Jonas
Re: [whatwg] Challenging canvas.supportsContext
On Wed, 26 Jun 2013 01:39:01 +0200, Glenn Maynard gl...@zewt.org wrote: This is done if the feature is being disabled completely at page load time, with no chance of it coming back: you simply don't put the interface into the environment. WebGL is different, since it might go away after the page is already loaded (eg. the GPU blacklist is updated); going in and trying to remove the interface after the page is loaded would be weird. It might also become available after previously being unavailable (eg. video drivers are updated), in which case you'd have to go in and insert the interface. That's a good point. But the above also means that supportsContext is not useful in such cases since the environment can have changed between the time supportsContext is called and the time you want to create a context. It also doesn't provide any way to query arguments to getContext, eg. to see if null would be returned if a particular option is provided, which supportsContext allows. (I don't know if there are any cases where this actually happens, since most options are best effort and don't cause context creation to fail if they're not available.) Right. -- Simon Pieters Opera Software
Re: [whatwg] Challenging canvas.supportsContext
On Wed, Jun 26, 2013 at 1:39 AM, Glenn Maynard gl...@zewt.org wrote: On Tue, Jun 25, 2013 at 3:28 PM, Simon Pieters sim...@opera.com wrote: On Tue, 25 Jun 2013 21:01:27 +0200, Dean Jackson d...@apple.com wrote: Showing or hiding interface objects is not something I want to do. It's possible that I missed it, but, why not? There is precedent for doing so. For instance, in Opera 11, the WebSocket constructor was absent unless WebSockets were enabled in opera:config. This allowed feature detection like the following to work: var supports_websockets = WebSocket in window; Also, the HTML spec actually requires it: [[ When support for a feature is disabled (e.g. as an emergency measure to mitigate a security problem, or to aid in development, or for performance reasons), user agents must act as if they had no support for the feature whatsoever, and as if the feature was not mentioned in this specification. For example, if a particular feature is accessed via an attribute in a Web IDL interface, the attribute itself would be omitted from the objects that implement that interface — leaving the attribute on the object but making it return null or throw an exception is insufficient. ]] This is done if the feature is being disabled completely at page load time, with no chance of it coming back: you simply don't put the interface into the environment. WebGL is different, since it might go away after the page is already loaded (eg. the GPU blacklist is updated); going in and trying to remove the interface after the page is loaded would be weird. It might also become available after previously being unavailable (eg. video drivers are updated), in which case you'd have to go in and insert the interface. I don't think any of the current proposals supports that use case. For that to be really supported we'd need some sort of event that is fired whenever support for WebGL is dynamically added or removed. Pages having to continuously poll .supportsContext() is not a real solution. Has any browser actually expressed interest in supporting that use case? / Jonas
Re: [whatwg] Challenging canvas.supportsContext
On Tue, Jun 25, 2013 at 6:48 PM, Simon Pieters sim...@opera.com wrote: On Wed, 26 Jun 2013 01:39:01 +0200, Glenn Maynard gl...@zewt.org wrote: This is done if the feature is being disabled completely at page load time, with no chance of it coming back: you simply don't put the interface into the environment. WebGL is different, since it might go away after the page is already loaded (eg. the GPU blacklist is updated); going in and trying to remove the interface after the page is loaded would be weird. It might also become available after previously being unavailable (eg. video drivers are updated), in which case you'd have to go in and insert the interface. That's a good point. But the above also means that supportsContext is not useful in such cases since the environment can have changed between the time supportsContext is called and the time you want to create a context. That's inherent however it's done, since it's usually impossible to guarantee this; too much is out of the control of the browser. Even if you call getContext(gl) twice in a row, one might succeed and the other fail. That doesn't mean it's not useful, but it does mean it's harder to use correctly. For example, if Google Maps wants to show an enable WebGL maps button only if WebGL is available, supportsContext() can be useful to tell whether to show the button. That's useful even if it's not perfect: if that hides the button correctly for 99% of users, and gives a button that shows sorry, WebGL didn't actually work! for the remaining 1%, then that's an improvement over a useless button for 100% of users. If they want to show the button in the uncommon case of WebGL becoming available later on, they'd also want to recheck support periodically (eg. on focus or something). This is all far from perfect--web APIs try hard to avoid this sort of nondeterministic behavior. I don't know enough about the costs of actually creating a context to know whether it's worth it. But, I disagree that being imperfect means it's not useful at all. (FWIW, if I remember correctly, the basic idea of supportsContext was to discourage badly-written libraries, used on pages that don't even care about WebGL, from always creating a context just to fill in a feature support table, causing lots of pages to create and immediately discard rendering contexts all the time.) On Tue, Jun 25, 2013 at 6:46 PM, Jonas Sicking jo...@sicking.cc wrote: I don't think any of the current proposals supports that use case. For that to be really supported we'd need some sort of event that is fired whenever support for WebGL is dynamically added or removed. Pages having to continuously poll .supportsContext() is not a real solution. Has any browser actually expressed interest in supporting that use case? I recall the driver blacklist issue coming up before, where WebGL is available when the page is loaded, but is disabled later due to a background update to the blacklist. Sorry, it was years ago and I don't recall who that discussion was with. https://www.khronos.org/webgl/public-mailing-list/archives/1104/msg00136.htmlis the closest reference to the discussion I can find. -- Glenn Maynard
Re: [whatwg] Challenging canvas.supportsContext
2013/6/21 Benoit Jacob jacob.benoi...@gmail.com Any other application use cases? Anyone? I believe that if no unquestionable application use case can be given, then this function should be removed from the spec. Benoit
Re: [whatwg] Challenging canvas.supportsContext
On 25/06/2013, at 5:56 AM, Benoit Jacob jacob.benoi...@gmail.com wrote: 2013/6/21 Benoit Jacob jacob.benoi...@gmail.com Any other application use cases? Anyone? I believe that if no unquestionable application use case can be given, then this function should be removed from the spec. I think I was the person who proposed the method, and we just implemented it in WebKit. I'm not going to oppose removal, but I do think it is still fairly useful. Tab mentioned many of the things I had in mind (analogous to @supports, possibly better described as maybe and no, etc). Maybe convenient is a better word? I don't really buy the argument that it is useless for feature detection because even if supportsContext('webgl') returned true, you don't know if you can actually use WebGL until you create a context. Obviously pages will have to be written to support failing calls to getContext. They have to do this with or without this API. Also, the presence of window.WebGLRenderingContext doesn't necessarily indicate that WebGL is supported. On iOS for example, that object is available in Safari but calling getContext('webgl') fails. The supportsContext method would allow authors to easily detect this case. One could also imagine a vendor extension context type that is impossible to detect via DOM properties, and is unable to avoid lazy instantiation. Anyway, it seems most people want to remove it, so I'm not going to fight. Dean
Re: [whatwg] Challenging canvas.supportsContext
Did any email in this thread having provided any valid application use case? I can't see many application use cases being mentioned at all, and the most of the ones that were have been rebuked as far as I can see. The most serious remaining one, that I can see, is the Chrome Web Store. However: - it is a case where reliability is particularly important, which goes in favor of an actual getContext; - this kind of application inherently requires browser-specific APIs anyway (at least for the time being --- we can revisit when it's no longer the case), so having a standard API for this particular feature is less valuable than elsewhere. Any other application use cases? Keep in mind that this is all in sharp contrast with every single other canvas / 2d / webgl API feature that I can think of, for which application use cases are abundant. Benoit 2013/6/19 Benoit Jacob jacob.benoi...@gmail.com Dear list, 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. It also doesn't seem like any valid application use case was given on this list when this topic was discussed around September 2012. The closest thing that I could find being discussed, was use cases by JS frameworks or libraries that already expose similar feature-detection APIs. 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. 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. In other words, I'm saying that no matter what JS libraries/frameworks may offer for feature detection, in the end, applications don't want to just * detect* features --- applications want to *use* features. So they'll just pair supportsContext calls with getContext calls, making the supportsContext calls useless. There is also the argument that supportsContext can be much cheaper than a getContext, given that it only has to guarantee that getContext must fail if supportsContext returned false. But this argument is overlooking that in the typical failure case, which is failure due to system/driver blacklisting, getContext returns just as fast as supportsContext --- as they both just check the blacklist and return. 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. Keep in mind that supportsContext can't guarantee that if it returns true, then a subsequent getContext will succeed. The spec doesn't require it to, either. So if the existence of supportsContext misleads application developers into no longer checking for getContext failures, then we'll just have rendered canvas-using applications a little bit more fragile. Another problem with supportsContext is that it's untestable, at least when it returns true; it is spec-compliant to just implement it as returning whether the JS interface for the required canvas context exists, which is quite useless. Given such deep problems, I think that the usefulness bar for accepting supportsContext into the spec should be quite high. So, is there an application use case that actually benefits from supportsContext? Cheers, Benoit
Re: [whatwg] Challenging canvas.supportsContext
On 6/19/13 5:27 PM, Paul Irish wrote: I agree that supportsContext is only useful if it's more accurate that !!window.WebGLRenderingContext. So that's an interesting question. Should UAs simply not have window.WebGLRenderingContext in situations in which supportsContext would return false? -Boris
Re: [whatwg] Challenging canvas.supportsContext
On 6/19/13 6:04 PM, Kenneth Russell wrote: supportsContext() can give a much more accurate answer than !!window.WebGLRenderingContext. I can only speak for Chromium, but in that browser, it can take into account factors such as whether the GPU sub-process was able to start, whether WebGL is blacklisted on the current card, whether WebGL is disabled on the current domain due to previous GPU resets, and whether WebGL initialization succeeded on any other page. window.WebGLRenderingContext can take things like that into account too, in Gecko. For what it's worth. -Boris
Re: [whatwg] Challenging canvas.supportsContext
On Wed, Jun 19, 2013 at 3:24 PM, Kenneth Russell k...@google.com wrote: On Wed, Jun 19, 2013 at 3:06 PM, James Robinson jam...@google.com wrote: On Wed, Jun 19, 2013 at 3:04 PM, Kenneth Russell k...@google.com wrote: On Wed, Jun 19, 2013 at 2:20 PM, Brandon Benvie bben...@mozilla.com wrote: On 6/19/2013 2:05 PM, James Robinson wrote: What would a page using Modernizr (or other library) to feature detect WebGL do if the supportsContext('webgl') call succeeds but the later getContext('webgl') call fails? I don't have an example, I was just explaining how Mozernizr is often used. I'm also failing to see the utility of the supportsContext() call. It's impossible for a browser to promise that supportsContext('webgl') implies that getContext('webgl') will succeed without doing all of the expensive work, so any correctly authored page will have to handle a getContext('webgl') failure anyway. Given this, it would seem supportsContext is completely useless. The whole purpose of a feature detection check is to detect if a feature actually works or not. Accuracy is more important than cost. supportsContext() can give a much more accurate answer than !!window.WebGLRenderingContext. I can only speak for Chromium, but in that browser, it can take into account factors such as whether the GPU sub-process was able to start, whether WebGL is blacklisted on the current card, whether WebGL is disabled on the current domain due to previous GPU resets, and whether WebGL initialization succeeded on any other page. All of these checks can be done without the heavyweight operation of actually creating an OpenGL context. That's true, but the answer still doesn't promise anything about what getContext() will do. It may still return null and code will have to check for that. What's the use case for calling supportsContext() without calling getContext()? Any application which has a complex set of fallback paths. For example, - Preference 1: supportsContext('webgl', { softwareRendered: true }) - Preference 2: supportsContext('2d', { gpuAccelerated: true }) - Preference 3: supportsContext('webgl', { softwareRendered: false }) - Fallback: 2D canvas How would those checks work? In Chrome for example there are opaque heuristics for gpu accelerated 2d. So now you'd need supportsContext('2d', {gpuAccelerated: true, width: someWidth, height: someHeight, intendedUse: line drawing }); I agree that ideally, if supportsContext returns true then -- without any other state changes that might affect supportsContext's result -- getContext should return a valid rendering context. It's simply impossible to guarantee this correspondence 100% of the time, but if supportsContext's spec were tightened somehow, and conformance tests were added which asserted consistent results between supportsContext and getContext, would that address your concern? -Ken
Re: [whatwg] Challenging canvas.supportsContext
On Thu, Jun 20, 2013 at 10:22 AM, Boris Zbarsky bzbar...@mit.edu wrote: On 6/19/13 5:27 PM, Paul Irish wrote: I agree that supportsContext is only useful if it's more accurate that !!window.WebGLRenderingContext. So that's an interesting question. Should UAs simply not have window.WebGLRenderingContext in situations in which supportsContext would return false? I've suggested that in the past, and the response was that it's harder to do (don't recall in which engine, probably WebKit). It would seem pretty weird if the interface appears and disappears from window over the life of the page, as WebGL support comes and goes (eg. the driver blacklist or system graphics drivers are updated). Also, supportsContext() takes arguments, so you can find out if context creation would fail with a particular set of options. You can't do that by hiding or displaying an interface. -- Glenn Maynard
Re: [whatwg] Challenging canvas.supportsContext
On 6/20/13 9:40 PM, Glenn Maynard wrote: I've suggested that in the past, and the response was that it's harder to do (don't recall in which engine, probably WebKit). It would seem pretty weird if the interface appears and disappears from window over the life of the page, as WebGL support comes and goes (eg. the driver blacklist or system graphics drivers are updated). Yeah, appearing/disappearing stuff is a no-go. If we need this state to change over the lifetime of a page, then it shouldn't be an object-detection-check, for sure. In that case we're back to having a method. -Boris
[whatwg] Challenging canvas.supportsContext
Dear list, 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. It also doesn't seem like any valid application use case was given on this list when this topic was discussed around September 2012. The closest thing that I could find being discussed, was use cases by JS frameworks or libraries that already expose similar feature-detection APIs. 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. 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. In other words, I'm saying that no matter what JS libraries/frameworks may offer for feature detection, in the end, applications don't want to just * detect* features --- applications want to *use* features. So they'll just pair supportsContext calls with getContext calls, making the supportsContext calls useless. There is also the argument that supportsContext can be much cheaper than a getContext, given that it only has to guarantee that getContext must fail if supportsContext returned false. But this argument is overlooking that in the typical failure case, which is failure due to system/driver blacklisting, getContext returns just as fast as supportsContext --- as they both just check the blacklist and return. 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. Keep in mind that supportsContext can't guarantee that if it returns true, then a subsequent getContext will succeed. The spec doesn't require it to, either. So if the existence of supportsContext misleads application developers into no longer checking for getContext failures, then we'll just have rendered canvas-using applications a little bit more fragile. Another problem with supportsContext is that it's untestable, at least when it returns true; it is spec-compliant to just implement it as returning whether the JS interface for the required canvas context exists, which is quite useless. Given such deep problems, I think that the usefulness bar for accepting supportsContext into the spec should be quite high. So, is there an application use case that actually benefits from supportsContext? Cheers, Benoit
Re: [whatwg] Challenging canvas.supportsContext
On Wed, Jun 19, 2013 at 11:17 AM, Benoit Jacob jacob.benoi...@gmail.com wrote: 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. The problem that supportsContext() solves, and which was brought up repeatedly during the drive to add this, is that spinning up contexts can be expensive. ~TJ
Re: [whatwg] Challenging canvas.supportsContext
2013/6/19 Tab Atkins Jr. jackalm...@gmail.com On Wed, Jun 19, 2013 at 11:17 AM, Benoit Jacob jacob.benoi...@gmail.com wrote: 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. The problem that supportsContext() solves, and which was brought up repeatedly during the drive to add this, is that spinning up contexts can be expensive. I tried to address this very argument in my above email; maybe I wasn't clear enough. 1. If supportsContext() fails, then getContext() fails just as fast. In that case, supportsContext isn't any faster. 2. If supportsContext succeeds, then the application is going to want to proceed with calling getContext, so nothing is achieved by supportsContext being cheaper than getContext. If you disagree with that argument, then I would like, again, to hear about what would be an application use case that actually benefits from supportsContext. Benoit
Re: [whatwg] Challenging canvas.supportsContext
On 6/19/13 2:17 PM, Benoit Jacob wrote: The closest thing that I could find being discussed, was use cases by JS frameworks or libraries that already expose similar feature-detection APIs. However, that only shifts the question to: what is the reason for them to expose such APIs? I _think_ the issue is poorly-designed detection APIs that do the detection even if the consumer of the framework/library doesn't care about that particular feature. That means that right now those frameworks are doing a getContext() call but then no one cares that they did. There is also the argument that supportsContext can be much cheaper than a getContext, given that it only has to guarantee that getContext must fail if supportsContext returned false. But this argument is overlooking that in the typical failure case, which is failure due to system/driver blacklisting, getContext returns just as fast as supportsContext I think the argument here is that the common case for getContext is in fact more and more the success case. So the framework/library is wasting time successfully creating a context that no one actually cares about. If the above is correct, I agree with Benoit: the right fix is to fix the libraries to do the getContext() lazily when someone actually asks whether WebGL is enabled. If I'm wrong, then I'd like to understand what problem we _are_ trying to solve. That is, what the cases are that want to check that they can create a context but not actually create one. -Boris
Re: [whatwg] Challenging canvas.supportsContext
On Wed, Jun 19, 2013 at 11:29 AM, Boris Zbarsky bzbar...@mit.edu wrote: On 6/19/13 2:17 PM, Benoit Jacob wrote: The closest thing that I could find being discussed, was use cases by JS frameworks or libraries that already expose similar feature-detection APIs. However, that only shifts the question to: what is the reason for them to expose such APIs? I _think_ the issue is poorly-designed detection APIs that do the detection even if the consumer of the framework/library doesn't care about that particular feature. That means that right now those frameworks are doing a getContext() call but then no one cares that they did. There is also the argument that supportsContext can be much cheaper than a getContext, given that it only has to guarantee that getContext must fail if supportsContext returned false. But this argument is overlooking that in the typical failure case, which is failure due to system/driver blacklisting, getContext returns just as fast as supportsContext I think the argument here is that the common case for getContext is in fact more and more the success case. So the framework/library is wasting time successfully creating a context that no one actually cares about. If the above is correct, I agree with Benoit: the right fix is to fix the libraries to do the getContext() lazily when someone actually asks whether WebGL is enabled. If I'm wrong, then I'd like to understand what problem we _are_ trying to solve. That is, what the cases are that want to check that they can create a context but not actually create one. This is missing the point. You don't want to wait until it's actually time to create the context. Unless you torture your code flow, by the time you're creating a context you should already know that the context is supported. The knowledge of which context to use is most useful well before that, when you're first entering the app. Plus, it doesn't matter how late you do the detection - if you do a straight *detection* at all rather than an initialization (that is, if you throw away the context you've just created for testing), you'll still incur the start-up costs of spinning up a context. Doing that early or late doesn't matter too much - it's bad either way. Like @supports, the supportsContext() method can be easy and reliable with a very simple definition for supports - it returns true if calling getContext() with the same arguments would return a context rather than erroring, and false otherwise. No capacity for lying there without breaking sites. ~TJ
Re: [whatwg] Challenging canvas.supportsContext
Looking back at the previous discussion: http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2012-September/037229.html (and succeeding emails) http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2012-October/037693.html Accurate feature detection in libraries like Modernizr was mentioned as a key use case: http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2012-September/037249.html Additionally, though, application developers wanted to be able to ask questions like is software rendering supported for WebGL: http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2012-September/037232.html I think this second use case is valid. One could imagine a graphing or charting library which would use low-power, software-rendered WebGL if available, but otherwise would fall back to using CanvasRenderingContext2D. I'd like to see supportsContext remain in the spec. -Ken On Wed, Jun 19, 2013 at 12:34 PM, Tab Atkins Jr. jackalm...@gmail.com wrote: On Wed, Jun 19, 2013 at 11:29 AM, Boris Zbarsky bzbar...@mit.edu wrote: On 6/19/13 2:17 PM, Benoit Jacob wrote: The closest thing that I could find being discussed, was use cases by JS frameworks or libraries that already expose similar feature-detection APIs. However, that only shifts the question to: what is the reason for them to expose such APIs? I _think_ the issue is poorly-designed detection APIs that do the detection even if the consumer of the framework/library doesn't care about that particular feature. That means that right now those frameworks are doing a getContext() call but then no one cares that they did. There is also the argument that supportsContext can be much cheaper than a getContext, given that it only has to guarantee that getContext must fail if supportsContext returned false. But this argument is overlooking that in the typical failure case, which is failure due to system/driver blacklisting, getContext returns just as fast as supportsContext I think the argument here is that the common case for getContext is in fact more and more the success case. So the framework/library is wasting time successfully creating a context that no one actually cares about. If the above is correct, I agree with Benoit: the right fix is to fix the libraries to do the getContext() lazily when someone actually asks whether WebGL is enabled. If I'm wrong, then I'd like to understand what problem we _are_ trying to solve. That is, what the cases are that want to check that they can create a context but not actually create one. This is missing the point. You don't want to wait until it's actually time to create the context. Unless you torture your code flow, by the time you're creating a context you should already know that the context is supported. The knowledge of which context to use is most useful well before that, when you're first entering the app. Plus, it doesn't matter how late you do the detection - if you do a straight *detection* at all rather than an initialization (that is, if you throw away the context you've just created for testing), you'll still incur the start-up costs of spinning up a context. Doing that early or late doesn't matter too much - it's bad either way. Like @supports, the supportsContext() method can be easy and reliable with a very simple definition for supports - it returns true if calling getContext() with the same arguments would return a context rather than erroring, and false otherwise. No capacity for lying there without breaking sites. ~TJ
Re: [whatwg] Challenging canvas.supportsContext
On 6/19/13 3:43 PM, Kenneth Russell wrote: Accurate feature detection in libraries like Modernizr was mentioned as a key use case: http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2012-September/037249.html Right, this is the use case that's not really making sense to me. The fact that Modernizr was doing this _eagerly_ sounds like a bug in Modernizr to me... Additionally, though, application developers wanted to be able to ask questions like is software rendering supported for WebGL: That's definitely something that new API would be needed to address, yes. -Boris
Re: [whatwg] Challenging canvas.supportsContext
On 6/19/13 3:34 PM, Tab Atkins Jr. wrote: This is missing the point. You don't want to wait until it's actually time to create the context. Unless you torture your code flow, by the time you're creating a context you should already know that the context is supported. The knowledge of which context to use is most useful well before that, when you're first entering the app. But supportsContext doesn't give any guarantee that the getContext will succeed. Plus, it doesn't matter how late you do the detection - if you do a straight *detection* at all rather than an initialization (that is, if you throw away the context you've just created for testing) OK, but why are we making that assumption? I guess if people insist on doing that, then we do in fact need something that will basically try to guess whether getContext might succeed. Like @supports, the supportsContext() method can be easy and reliable with a very simple definition for supports - it returns true if calling getContext() with the same arguments would return a context rather than erroring, and false otherwise. Just so we're clear, this is _not_ what supportsContext is specified to do. As specced, it will return false if you know for a fact that getContext would return null. It will return true if you think that getContext might not return null. This means that a true return doesn't really mean squat about what getContext will do. And the reason for that is that you can't tell whether getContext will return null until you try to do it, given how getContext is specced. -Boris
Re: [whatwg] Challenging canvas.supportsContext
On 6/19/2013 12:46 PM, Boris Zbarsky wrote: On 6/19/13 3:43 PM, Kenneth Russell wrote: Accurate feature detection in libraries like Modernizr was mentioned as a key use case: http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2012-September/037249.html Right, this is the use case that's not really making sense to me. The fact that Modernizr was doing this _eagerly_ sounds like a bug in Modernizr to me... The point of using Modernizr or something like it is to detect availability of features on page load, and then conditionally load polyfills/alternate fallback implementations. It specifically does need to do eager detection to be useful. It can't wait until the first usage to do feature detection; it needs to be done up front when preparing dependencies for the main application. This is also why Modernizr provides a custom build tool. It allows for users to only do the feature detection on features they know they need to care about, because each check has some cost that needs to be paid early on in a page load.
Re: [whatwg] Challenging canvas.supportsContext
On 6/19/13 4:22 PM, Brandon Benvie wrote: The point of using Modernizr or something like it is to detect availability of features on page load, and then conditionally load polyfills/alternate fallback implementations. It specifically does need to do eager detection to be useful. It can't wait until the first usage to do feature detection; it needs to be done up front when preparing dependencies for the main application. I see. For this use case, the current definition of supportsContext is of limited utility, unless you make some assumptions about behavior that the spec does not require -Boris
Re: [whatwg] Challenging canvas.supportsContext
On Wed, Jun 19, 2013 at 1:22 PM, Brandon Benvie bben...@mozilla.com wrote: On 6/19/2013 12:46 PM, Boris Zbarsky wrote: On 6/19/13 3:43 PM, Kenneth Russell wrote: Accurate feature detection in libraries like Modernizr was mentioned as a key use case: http://lists.whatwg.org/**pipermail/whatwg-whatwg.org/** 2012-September/037249.htmlhttp://lists.whatwg.org/pipermail/whatwg-whatwg.org/2012-September/037249.html Right, this is the use case that's not really making sense to me. The fact that Modernizr was doing this _eagerly_ sounds like a bug in Modernizr to me... The point of using Modernizr or something like it is to detect availability of features on page load, and then conditionally load polyfills/alternate fallback implementations. It specifically does need to do eager detection to be useful. It can't wait until the first usage to do feature detection; it needs to be done up front when preparing dependencies for the main application. What would a page using Modernizr (or other library) to feature detect WebGL do if the supportsContext('webgl') call succeeds but the later getContext('webgl') call fails? I'm also failing to see the utility of the supportsContext() call. It's impossible for a browser to promise that supportsContext('webgl') implies that getContext('webgl') will succeed without doing all of the expensive work, so any correctly authored page will have to handle a getContext('webgl') failure anyway. - James This is also why Modernizr provides a custom build tool. It allows for users to only do the feature detection on features they know they need to care about, because each check has some cost that needs to be paid early on in a page load.
Re: [whatwg] Challenging canvas.supportsContext
2013/6/19 Boris Zbarsky bzbar...@mit.edu On 6/19/13 3:34 PM, Tab Atkins Jr. wrote: This is missing the point. You don't want to wait until it's actually time to create the context. Unless you torture your code flow, by the time you're creating a context you should already know that the context is supported. The knowledge of which context to use is most useful well before that, when you're first entering the app. But supportsContext doesn't give any guarantee that the getContext will succeed. Plus, it doesn't matter how late you do the detection - if you do a straight *detection* at all rather than an initialization (that is, if you throw away the context you've just created for testing) OK, but why are we making that assumption? I guess if people insist on doing that, then we do in fact need something that will basically try to guess whether getContext might succeed. Like @supports, the supportsContext() method can be easy and reliable with a very simple definition for supports - it returns true if calling getContext() with the same arguments would return a context rather than erroring, and false otherwise. Just so we're clear, this is _not_ what supportsContext is specified to do. As specced, it will return false if you know for a fact that getContext would return null. It will return true if you think that getContext might not return null. This means that a true return doesn't really mean squat about what getContext will do. And the reason for that is that you can't tell whether getContext will return null until you try to do it, given how getContext is specced. Yes, it seems that supportsContext being under-specified allows for confusion to happen, as it is given different meanings in different emails in this thread, that are mutually incompatible: From Tab's 1st email: *The problem that supportsContext() solves, and which was brought up* * repeatedly during the drive to add this, is that spinning up contexts* * can be expensive.* From Tab's 2nd email: *Like @supports, the supportsContext() method can be easy and reliable* * with a very simple definition for supports - it returns true if* * calling getContext() with the same arguments would return a context* * rather than erroring, and false otherwise.* The incompatibility is that the second quote's requirement can only be met if supportsContext(webgl) actually creates an OpenGL context --- which is incompatible with the first quote, which requires supportsContext to be significantly quicker than getContext, which can only be achieved by not actually creating an OpenGL context. (Replace OpenGL context by Direct3D device or whichever concept applies to the operating system at hand). Benoit -Boris
Re: [whatwg] Challenging canvas.supportsContext
On 6/19/2013 2:05 PM, James Robinson wrote: What would a page using Modernizr (or other library) to feature detect WebGL do if the supportsContext('webgl') call succeeds but the later getContext('webgl') call fails? I don't have an example, I was just explaining how Mozernizr is often used. I'm also failing to see the utility of the supportsContext() call. It's impossible for a browser to promise that supportsContext('webgl') implies that getContext('webgl') will succeed without doing all of the expensive work, so any correctly authored page will have to handle a getContext('webgl') failure anyway. Given this, it would seem supportsContext is completely useless. The whole purpose of a feature detection check is to detect if a feature actually works or not. Accuracy is more important than cost.
Re: [whatwg] Challenging canvas.supportsContext
On Wed, Jun 19, 2013 at 2:20 PM, Brandon Benvie bben...@mozilla.com wrote: On 6/19/2013 2:05 PM, James Robinson wrote: I'm also failing to see the utility of the supportsContext() call. It's impossible for a browser to promise that supportsContext('webgl') implies that getContext('webgl') will succeed without doing all of the expensive work, so any correctly authored page will have to handle a getContext('webgl') failure anyway. Given this, it would seem supportsContext is completely useless. The whole purpose of a feature detection check is to detect if a feature actually works or not. Accuracy is more important than cost. Hmm, I guess I agree. That sucks, but you're right - it's much more important that you *actually* be able to generate a context when the feature-detect says you can. ~TJ
Re: [whatwg] Challenging canvas.supportsContext
On the Modernizr side, an old version did indeed create a context for feature detection. For the past two years we have advocated the soft `WebGLRenderingContext in window` test instead. There, of course, is some gap between the results of that detect and how successful a getContext call will be, but I don't have data those false positive rates. A use case of a Modernizr user is to detect WebGL and show a browser prompt if it's not detected. From my understanding nearly no developer re-use the same context for both detection and use. I asked mrdoob, developer of three.js if supportsContext would be useful to the project.. He said they currently create 2 webgl contexts because, API-wise is not easy to reuse the context that you created for checking if it was available. Well, it's not pretty, at least I know the Chrome Web Store had a usecase for detection without context creation: they wanted to not show apps in the marketplace that couldn't run on the user's machine. I agree that supportsContext is only useful if it's more accurate that !!window.WebGLRenderingContext. On Wed, Jun 19, 2013 at 2:05 PM, James Robinson jam...@google.com wrote: On Wed, Jun 19, 2013 at 1:22 PM, Brandon Benvie bben...@mozilla.com wrote: On 6/19/2013 12:46 PM, Boris Zbarsky wrote: On 6/19/13 3:43 PM, Kenneth Russell wrote: Accurate feature detection in libraries like Modernizr was mentioned as a key use case: http://lists.whatwg.org/**pipermail/whatwg-whatwg.org/** 2012-September/037249.html http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2012-September/037249.html Right, this is the use case that's not really making sense to me. The fact that Modernizr was doing this _eagerly_ sounds like a bug in Modernizr to me... The point of using Modernizr or something like it is to detect availability of features on page load, and then conditionally load polyfills/alternate fallback implementations. It specifically does need to do eager detection to be useful. It can't wait until the first usage to do feature detection; it needs to be done up front when preparing dependencies for the main application. What would a page using Modernizr (or other library) to feature detect WebGL do if the supportsContext('webgl') call succeeds but the later getContext('webgl') call fails? I'm also failing to see the utility of the supportsContext() call. It's impossible for a browser to promise that supportsContext('webgl') implies that getContext('webgl') will succeed without doing all of the expensive work, so any correctly authored page will have to handle a getContext('webgl') failure anyway. - James This is also why Modernizr provides a custom build tool. It allows for users to only do the feature detection on features they know they need to care about, because each check has some cost that needs to be paid early on in a page load.
Re: [whatwg] Challenging canvas.supportsContext
On Wed, Jun 19, 2013 at 2:20 PM, Brandon Benvie bben...@mozilla.com wrote: On 6/19/2013 2:05 PM, James Robinson wrote: What would a page using Modernizr (or other library) to feature detect WebGL do if the supportsContext('webgl') call succeeds but the later getContext('webgl') call fails? I don't have an example, I was just explaining how Mozernizr is often used. I'm also failing to see the utility of the supportsContext() call. It's impossible for a browser to promise that supportsContext('webgl') implies that getContext('webgl') will succeed without doing all of the expensive work, so any correctly authored page will have to handle a getContext('webgl') failure anyway. Given this, it would seem supportsContext is completely useless. The whole purpose of a feature detection check is to detect if a feature actually works or not. Accuracy is more important than cost. supportsContext() can give a much more accurate answer than !!window.WebGLRenderingContext. I can only speak for Chromium, but in that browser, it can take into account factors such as whether the GPU sub-process was able to start, whether WebGL is blacklisted on the current card, whether WebGL is disabled on the current domain due to previous GPU resets, and whether WebGL initialization succeeded on any other page. All of these checks can be done without the heavyweight operation of actually creating an OpenGL context. -Ken
Re: [whatwg] Challenging canvas.supportsContext
On Wed, Jun 19, 2013 at 3:04 PM, Kenneth Russell k...@google.com wrote: On Wed, Jun 19, 2013 at 2:20 PM, Brandon Benvie bben...@mozilla.com wrote: On 6/19/2013 2:05 PM, James Robinson wrote: What would a page using Modernizr (or other library) to feature detect WebGL do if the supportsContext('webgl') call succeeds but the later getContext('webgl') call fails? I don't have an example, I was just explaining how Mozernizr is often used. I'm also failing to see the utility of the supportsContext() call. It's impossible for a browser to promise that supportsContext('webgl') implies that getContext('webgl') will succeed without doing all of the expensive work, so any correctly authored page will have to handle a getContext('webgl') failure anyway. Given this, it would seem supportsContext is completely useless. The whole purpose of a feature detection check is to detect if a feature actually works or not. Accuracy is more important than cost. supportsContext() can give a much more accurate answer than !!window.WebGLRenderingContext. I can only speak for Chromium, but in that browser, it can take into account factors such as whether the GPU sub-process was able to start, whether WebGL is blacklisted on the current card, whether WebGL is disabled on the current domain due to previous GPU resets, and whether WebGL initialization succeeded on any other page. All of these checks can be done without the heavyweight operation of actually creating an OpenGL context. That's true, but the answer still doesn't promise anything about what getContext() will do. It may still return null and code will have to check for that. What's the use case for calling supportsContext() without calling getContext()? - James -Ken
Re: [whatwg] Challenging canvas.supportsContext
On Wed, Jun 19, 2013 at 3:06 PM, James Robinson jam...@google.com wrote: On Wed, Jun 19, 2013 at 3:04 PM, Kenneth Russell k...@google.com wrote: On Wed, Jun 19, 2013 at 2:20 PM, Brandon Benvie bben...@mozilla.com wrote: On 6/19/2013 2:05 PM, James Robinson wrote: What would a page using Modernizr (or other library) to feature detect WebGL do if the supportsContext('webgl') call succeeds but the later getContext('webgl') call fails? I don't have an example, I was just explaining how Mozernizr is often used. I'm also failing to see the utility of the supportsContext() call. It's impossible for a browser to promise that supportsContext('webgl') implies that getContext('webgl') will succeed without doing all of the expensive work, so any correctly authored page will have to handle a getContext('webgl') failure anyway. Given this, it would seem supportsContext is completely useless. The whole purpose of a feature detection check is to detect if a feature actually works or not. Accuracy is more important than cost. supportsContext() can give a much more accurate answer than !!window.WebGLRenderingContext. I can only speak for Chromium, but in that browser, it can take into account factors such as whether the GPU sub-process was able to start, whether WebGL is blacklisted on the current card, whether WebGL is disabled on the current domain due to previous GPU resets, and whether WebGL initialization succeeded on any other page. All of these checks can be done without the heavyweight operation of actually creating an OpenGL context. That's true, but the answer still doesn't promise anything about what getContext() will do. It may still return null and code will have to check for that. What's the use case for calling supportsContext() without calling getContext()? Any application which has a complex set of fallback paths. For example, - Preference 1: supportsContext('webgl', { softwareRendered: true }) - Preference 2: supportsContext('2d', { gpuAccelerated: true }) - Preference 3: supportsContext('webgl', { softwareRendered: false }) - Fallback: 2D canvas I agree that ideally, if supportsContext returns true then -- without any other state changes that might affect supportsContext's result -- getContext should return a valid rendering context. It's simply impossible to guarantee this correspondence 100% of the time, but if supportsContext's spec were tightened somehow, and conformance tests were added which asserted consistent results between supportsContext and getContext, would that address your concern? -Ken
Re: [whatwg] Challenging canvas.supportsContext
On Wed, Jun 19, 2013 at 3:24 PM, Kenneth Russell k...@google.com wrote: That's true, but the answer still doesn't promise anything about what getContext() will do. It may still return null and code will have to check for that. What's the use case for calling supportsContext() without calling getContext()? Any application which has a complex set of fallback paths. For example, - Preference 1: supportsContext('webgl', { softwareRendered: true }) - Preference 2: supportsContext('2d', { gpuAccelerated: true }) - Preference 3: supportsContext('webgl', { softwareRendered: false }) - Fallback: 2D canvas I agree that ideally, if supportsContext returns true then -- without any other state changes that might affect supportsContext's result -- getContext should return a valid rendering context. It's simply impossible to guarantee this correspondence 100% of the time, but if supportsContext's spec were tightened somehow, and conformance tests were added which asserted consistent results between supportsContext and getContext, would that address your concern? It seems like this falls into the canPlayType() bucket, where you can definitely give negatives, but your positives are at best hopeful. Maybe we should just have it do the same thing, and return maybe or probably rather than a boolean true? ~TJ
Re: [whatwg] Challenging canvas.supportsContext
On Wed, Jun 19, 2013 at 3:24 PM, Kenneth Russell k...@google.com wrote: On Wed, Jun 19, 2013 at 3:06 PM, James Robinson jam...@google.com wrote: On Wed, Jun 19, 2013 at 3:04 PM, Kenneth Russell k...@google.com wrote: supportsContext() can give a much more accurate answer than !!window.WebGLRenderingContext. I can only speak for Chromium, but in that browser, it can take into account factors such as whether the GPU sub-process was able to start, whether WebGL is blacklisted on the current card, whether WebGL is disabled on the current domain due to previous GPU resets, and whether WebGL initialization succeeded on any other page. All of these checks can be done without the heavyweight operation of actually creating an OpenGL context. That's true, but the answer still doesn't promise anything about what getContext() will do. It may still return null and code will have to check for that. What's the use case for calling supportsContext() without calling getContext()? Any application which has a complex set of fallback paths. For example, - Preference 1: supportsContext('webgl', { softwareRendered: true }) - Preference 2: supportsContext('2d', { gpuAccelerated: true }) - Preference 3: supportsContext('webgl', { softwareRendered: false }) - Fallback: 2D canvas I'm assuming you have (1) and (3) flipped here and both supportsContext() and getContext() support additional attributes to dictate whether a software-provided context can be supplied. In that case, in order to write correct code I'd still have to attempt to fetch the contexts before using them, i.e.: var ctx = canvas.getContext('webgl', { 'allowSoftware': false}); if (ctx) { doPreference1(ctx); return; } ctx = canvas.getContext('2d', {'allowSoftware': false}); if (ctx) { doPreference2(ctx); // etc how could I simplify this code using supportsContext() ? I agree that ideally, if supportsContext returns true then -- without any other state changes that might affect supportsContext's result -- getContext should return a valid rendering context. It seems overwhelmingly likely that one of the state changes that might affect the result will be attempting to instantiate a real context. It's simply impossible to guarantee this correspondence 100% of the time, but if supportsContext's spec were tightened somehow, and conformance tests were added which asserted consistent results between supportsContext and getContext, would that address your concern? I don't see how supportsContext() could be as accurate as getContext() without doing all of the work getContext() does. If it's not 100% accurate, when is it useful? - James -Ken
Re: [whatwg] Challenging canvas.supportsContext
On Wed, Jun 19, 2013 at 3:39 PM, James Robinson jam...@google.com wrote: On Wed, Jun 19, 2013 at 3:24 PM, Kenneth Russell k...@google.com wrote: On Wed, Jun 19, 2013 at 3:06 PM, James Robinson jam...@google.com wrote: On Wed, Jun 19, 2013 at 3:04 PM, Kenneth Russell k...@google.com wrote: supportsContext() can give a much more accurate answer than !!window.WebGLRenderingContext. I can only speak for Chromium, but in that browser, it can take into account factors such as whether the GPU sub-process was able to start, whether WebGL is blacklisted on the current card, whether WebGL is disabled on the current domain due to previous GPU resets, and whether WebGL initialization succeeded on any other page. All of these checks can be done without the heavyweight operation of actually creating an OpenGL context. That's true, but the answer still doesn't promise anything about what getContext() will do. It may still return null and code will have to check for that. What's the use case for calling supportsContext() without calling getContext()? Any application which has a complex set of fallback paths. For example, - Preference 1: supportsContext('webgl', { softwareRendered: true }) - Preference 2: supportsContext('2d', { gpuAccelerated: true }) - Preference 3: supportsContext('webgl', { softwareRendered: false }) - Fallback: 2D canvas I'm assuming you have (1) and (3) flipped here and both supportsContext() and getContext() support additional attributes to dictate whether a software-provided context can be supplied. In that case, in order to write correct code I'd still have to attempt to fetch the contexts before using them, i.e.: var ctx = canvas.getContext('webgl', { 'allowSoftware': false}); if (ctx) { doPreference1(ctx); return; } ctx = canvas.getContext('2d', {'allowSoftware': false}); if (ctx) { doPreference2(ctx); // etc how could I simplify this code using supportsContext() ? I agree that ideally, if supportsContext returns true then -- without any other state changes that might affect supportsContext's result -- getContext should return a valid rendering context. It seems overwhelmingly likely that one of the state changes that might affect the result will be attempting to instantiate a real context. In my experience, in Chromium, creation of the underlying OpenGL context for a WebGLRenderingContext almost never fails in isolation. Instead, more general failures happen such as the GPU process failing to boot, or creation of all OpenGL contexts (including the compositor's) failing. These failures would be detected before the app calls supportsContext('webgl'). For this reason I believe supportsContext's answer can be highly accurate in almost every situation. It's simply impossible to guarantee this correspondence 100% of the time, but if supportsContext's spec were tightened somehow, and conformance tests were added which asserted consistent results between supportsContext and getContext, would that address your concern? I don't see how supportsContext() could be as accurate as getContext() without doing all of the work getContext() does. If it's not 100% accurate, when is it useful? This is a specious question. My point is that the answer can be accurate enough to be useful, and I'm personally willing to sign up to make the implementation follow a stricter spec. -Ken - James -Ken
Re: [whatwg] Challenging canvas.supportsContext
2013/6/19 Kenneth Russell k...@google.com In my experience, in Chromium, creation of the underlying OpenGL context for a WebGLRenderingContext almost never fails in isolation. Instead, more general failures happen such as the GPU process failing to boot, or creation of all OpenGL contexts (including the compositor's) failing. These failures would be detected before the app calls supportsContext('webgl'). For this reason I believe supportsContext's answer can be highly accurate in almost every situation. In Mozilla code, we fail WebGL context creation if any GL error occurs during initialization, where we have to make a number of specific OpenGL calls (e.g. querying many constants, enabling point sprites...). So it is perfectly possible for WebGL specifically to fail on a given device where OpenGL compositing works, without being specifically blacklisted, and currently we can rely on these automatic checks rather than having to curate a blacklist for these problems, which is very nice. Another way in which WebGL specifically can fail, is that some driver bugs cause errors that we may want to ignore in our compositor code but not in WebGL. To give an example, on many Vivante GPU drivers, which are very common in Chinese mobile devices, the first eglMakeCurrent call on a newly created context can return false without any actual EGL error [1]. A browser may want to ignore this error in its compositor to be able to run nonetheless on such devices, but without WebGL support. To summarize, blacklisting is not the only reason why WebGL specifically may fail, and this is particularly concrete on low-end mobile devices. Checking whether any WebGL context creation succeeded in the current browser session is a very useful data point indeed, but doesn't help with the _first_ context creation (which seems particularly relevant for the Chrome Web Store use case mentioned earlier). Benoit [1] https://bugzilla.mozilla.org/show_bug.cgi?id=771774#c2