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

Re: [Public WebGL] Behavior of WebGL canvas when it can't make a backbuffer of the requested size?




----- Original Message -----
> On Nov 8, 2010, at 8:17 PM, Mark Callow wrote:
> 
> > I, for one, am not prepared to sign off on something like this based
> > on what feels like a very sketchy description and no explanation of
> > how an application is supposed to handle this situation. Furthermore
> > I share Cedric's concern that most authors will not handle it.
> >
> > In native GL app's I let my resize event handler deal with resizing
> > things to whatever size the window system or user has permitted. If
> > I understand correctly, in the WebGL case the resize events are
> > based on the canvas size, therefore special handling is needed for
> > this error condition. How exactly does the application handle the
> > condition.
> 
> There is no resize event for Canvas because sizing it is synchronous.
> You set the width and height and the canvas is created with those
> dimensions. For complete handling the author would then have to make
> the getDrawingBufferDimensions() call and use that for viewport
> settings, etc.

One common pattern that I can see is:

  canvas.width = large_value;
  canvas.height = large_value;
  cx = canvas.getContext("webgl");
  size = cx.getDrawingBufferDimensions();
  if (size.width < canvas.width)
    canvas.width = size.width;
  if (size.height < canvas.height)
    canvas.height = size.height;

  The two .width/.height sets to size.* shouldn't cause a resize (since the backbuffer is already that size), and from that point on the developer can continue to use canvas.width/canvas.height just like they normally would have.  (Or just store the right values in local variables, to avoid having to get dom attributes for this!)

I think the above is by far the simplest thing to implement, describe, and use.  Let's say instead we went with throwing an exception:

ok = false;
desired_w = large_value;
desired_h = large_value;
while (!ok) {
  try {
    canvas.width = desired_w;
    canvas.height = desired_h;
  } catch (e) {
    // what now? You have no GL context yet, so can't query the viewport dimensions.  So..
    canvas.width = 1;
    canvas.height = 1;
    cx = canvas.getContext("webgl");
    new_dim = cx.getParameter(MAX_VIEWPORT_...);
    if (desired_w == new_dim) {
      alert("failed");
      break;
    }

    desired_w = new_dim;
    desired_h = new_dim;
  }
}

That's awful, and has zero advantages that I can see.

> But you bring up a good point. If the author does "canvas.width =
> 1000; canvas.height = 500;" will the canvas get resized twice? In
> other words, what are our rules for when the canvas gets resized? Is
> there a way for us to optimize the sizing? Maybe we could delay
> resizing the canvas until either the size is queried, or a WebGL call
> is made. 

The canvas unfortunately has to be resized twice.  I've sent mail to whatwg that this is really undesirable, and suggested that the canvas element just get a setSize() method that would set both width and height at the same time.

One related comment -- I think that we should clamp the canvas back buffer dimensions, *but* for on-screen display we need to scale up to the original requested canvas size, even if it's inefficient.  I think this is better than actually changing the physical layout dimensions of the canvas element as well, but I could probably go either way.

    - Vlad
-----------------------------------------------------------
You are currently subscribed to public_webgl@khronos.org.
To unsubscribe, send an email to majordomo@khronos.org with
the following command in the body of your email: