[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 Tue, Jun 12, 2012 at 5:11 PM, Glenn Maynard <glenn@zewt.org> wrote:
On Tue, Jun 12, 2012 at 6:12 PM, Gregg Tavares (çç) <gman@google.com> wrote:
> So now that there are a few hd-dpi devices any thoughts has to how to set a canvas's backing store to 1x1 to display pixels?
> Ideally it would be as simple as
> widthInCSSUnits = canvas.clientWidth;
> heightInCSSUnits = canvas.clientHeight;
> canvas.width = convertCSSUnitsToDeviceUnits(widthInCSSUnits);
> canvas.height =convertCSSUnitsToDeviceUnits(widthInCSSUnits);

These properties are already in CSS units, not device pixels. If you say "canvas.width = 100; canvas.height = 150;" on eg. an iPhone Retina display (two device pixels to one CSS pixel), the backing store created should be 200x300. This is how HTMLCanvasElement is specced, and it's how 2D canvas already works, so it's how WebGL should work as well. The size of the underlying buffer is exposed with drawingBufferWidth and drawingBufferHeight, and aren't necessarily the same (otherwise there'd be no need for those properties).

That might work but that's not why these properties exist. They exist because of GL_MAX_TEXURE_SIZE. You ask for canvas.width = 4123 but your GL only has GL_MAX_TEXTURE_SIZE = 2048 then drawingBufferWidht will be 2048 not the 4123 you asked for.


This isn't a perfect system: it's easy for people developing only on 1:1 systems to get things wrong. In WebGL's case, you'd need to use drawingBufferHeight rather than canvas.height any time you use readPixels, as well as if you're creating renderbuffers that you mean to be the same resolution as the backing store. 2D canvas has the same issues. This is annoying, but I don't think WebGL should deviate by itself; if this issue is to be improved, it should be done uniformly across all context types (on whatwg).

That aside, the language in the HTMLCanvasElement spec probably needs some adjustment. It says that @width and @height determine the coordinate space, which only makes sense for 2D canvas. For WebGL, this probably should say "the size of the viewport" (eg. the value you pass to gl.viewport is canvas.width/canvas.height, not gl.drawingBufferWidth and gl.drawingBufferHeight). If you think this needs to be clarified, it probably needs to be raised on whatwg, too.

Yes, there's some issues there. You need to know the number of device pixels in the backing store for WebGL so canvas can't automatically give you a 2x backing store for WebGL. Any program using gl.viewport or gl.scissor will break.


Glenn Maynard