[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 Thu, Jun 14, 2012 at 5:51 PM, Glenn Maynard <glenn@zewt.org> wrote:
On Wed, Jun 13, 2012 at 10:08 PM, Gregg Tavares (社用) <gman@google.com> wrote:
What do you mean with won't cause major problems? If the canvas is specified in CSS units but the browser chooses the backing store in device units then every sample on http://glsl.heroku.com breaks on an HD-DPI system because gl.FragCoord will be in device units and "resolution" will be in CSS units (since it's set by canvas.width and canvas.height) currently.

No breakage is good, but it's not in the same league as *every* (nearly) application being broken, which is what will happen if viewport takes backing store pixels and it starts to make a difference.  If it takes CSS pixels, then most applications will continue to work as-is, in both the texture size limitation and HD backbuffer cases.

Now, another option is to make gl.viewport and friends take backing store pixels (skipping the CSS pixel compatibility stuff), and to make HD backbuffers opt-in, leaving canvas.width/height alone.  This essentially means that the opt-in declares that your program has been adjusted to send backing store pixels (you've made the necessary s/canvas.height/gl.drawingBufferHeight/ adjustments).  This means fewer programs will support HD rendering (which, by Canvas's design, is supposed to be implicit), but it's much saner than trying to changing what canvas.height and canvas.width--parts of an API that WebGL doesn't own--mean.

(In that case, most applications would still end up broken in the reduced-backing-store scenario.  It's certainly a lower surface-area approach, since it doesn't introduce any new methods or resampling algorithms.)

By the way, that aside I agree there are certain cases where it's useful to say "don't use a different size backing store unless you absolutely have to", eg. when using WebGL for image processing or computation, which will never be displayed in a document.  This could be done with either an opt-in or an opt-out.

If you want it 1x1 with an HD-DPI display you set it 

     canvas.width = desiredWidth * window.devicePixelRatio
     canvas.height = desiredHeight * window.devicePixelRatio

and everything just magically works.

That seems the far saner way to go.

It's not how Canvas works.  If you want Canvas to change, then feel free to propose it on webapps or whatwg.  I doubt this will get traction; it would break the use case of laying out <canvas> elements as part of markup.  I assume you're not suggesting that canvas.width/height change meaning when canvas.getContext("webgl") is called--that would cause the visible size of the canvas in the document to change (and it'd be very bizarre and inconsistent behavior).

Glenn Maynard

I'm suggesting this

<canvas id="foo" width="400" height="300">

That displays on the page in 400x300 CSS pixels (note at this point here is no backing store)

If you do:

    canvas = document.getElementById("canvas");
    ctx = get.getContext("2d")

the backing store for allocated any size the browser wants

If you do

    canvas = document.getElementById("canvas");
    ctx = get.getContext("webgl")

the backing store allocated for webgl is 400x300 

That's it. Nothing changes except the WebGL spec says WebGL contexts must allocate a backbuffer canvas.width,canvas.height. No DPI adjusting allowed.

If the user sets the width to 800x600 they'll get an 800x600 canvas and an 800x600 backbuffer. If they want it HD-DPI they can set the css width to 400px by 300px. That's the same as it is today.