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

Re: [Public WebGL] How to set a canvas backing store to display units?

On Fri, Jun 15, 2012 at 4:38 PM, James Robinson <jamesr@google.com> wrote:
Does anyone see any issues with an "allowHighRes" option to getContext("webgl")?  This wouldn't violate the Canvas spec, since it's only making WebGL give an additional guarantee ("if allowHighRes is not set, the backing store will not be higher resolution than the canvas's natural dimensions"), it avoids lying to Canvas (by setting its width/height to device pixels instead of the required CSS pixels), and avoids the need for CSS hacks (with the problems Ian and I have described).  It also allows giving the browser control over whether or not to actually use a high-res backing store, as Canvas intends; if you use window.devicePixelRatio (a currently unstandardized function, I believe), there's no way to do that short of the browser putting a false value in that attribute.

Canvas 2d is (mostly) a vector API, so you can write canvas 2d code that does not care how many pixels are in the backing store and it will Just Work.

That is definitely not true for OpenGL or WebGL - in general it is not possible to write code that works correctly that does not care about how many pixels are actually in the backing store.  I think this is the fundamental difference between 2d canvas and WebGL and not something we can gloss over with an option or attribute.

As Florian says, allowHighRes doesn't mean you don't care about the backing store resolution.  It's just the opposite: it's a declaration that your application *does* draw the distinction between canvas.width and gl.drawingBufferWidth, and won't break if they differ, so it's safe for the browser to give you a high-res backing store.

On Fri, Jun 15, 2012 at 5:01 PM, Ben Vanik <benvanik@google.com> wrote:
If an attribute were added I'd prefer it to be a pixel scaling ratio ala 'backingPixelRatio' - that way one could pass window.devicePixelRatio to always get a native 1:1 backing store, or if they wanted to render at a lower resolution (performance/quality tradeoff) they easily could by supplying a different value. Just as with all context attributes the implementation could ignore it or change it and it's up to the application to query and see what they got (aka still don't use canvas.width/height).

If we want to allow setting a specific resolution, independently of the canvas resolution, then that should be done separately, eg. by adding "width" and "height" attributes to getContext's argument.  (Actually, there's a more general problem: you should be able to resize the backing store without resetting the context, which is what happens if you change the width or height argument of the canvas.  That will allow quickly switching to fullscreen without reloading the whole context, for example.  This wants a gl.resizeDrawingBuffer method.)

I didn't mention this before since I don't want to sidetrack the discussion--if we want to talk about this, it probably belongs in another thread.

Because most people's apps are broken w.r.t. backing dimension differences, I'd say that the spec should be updated to say that if an application doesn't pass in a value for 'backingPixelRatio' (or whatever) indicating that they know what they are doing and a backing store could not be allocated due to MAX_TEXTURE_SIZE issues, the GL context creation should just fail. Users would get (assuming app authors were thorough) a better failure message than just garbage rendering that would occur otherwise.

I don't think there's any benefit to a hard failure.  That doesn't help the applications that will break--either way they'll break.  All it'll do is artificially break the ones that would have otherwise worked.

Glenn Maynard