w3ctag / design-reviews

W3C specs and API reviews
Creative Commons Zero v1.0 Universal
332 stars 56 forks source link

Review OffscreenCanvas, including ImageBitmapRenderingContext #141

Closed junov closed 6 years ago

junov commented 8 years ago

Requesting that the TAG review the ImageBitmapRenderingContext interface spec'ed here: https://html.spec.whatwg.org/multipage/scripting.html#the-imagebitmap-rendering-context

greggman commented 6 years ago

Here's yet another use case that's not working

Lets say you'd prefer to run at a smooth fps below 60fps instead of a janky sometimes 60 and sometimes something slower

So you do something like

  let then = 0;
  function loop(time) {
    time *= 0.001;
    const elapsed = time - then;
    if (elapsed > 1 / 15) {
      then = time;
      render();
      gl.commit();
    }
    requestAnimationFrame(loop);
  }
  requestAnimationFrame(loop);

http://jsfiddle.net/greggman/y36aujrf/

apparently this is not supposed to work?!??! It flickers like crazy in Chrome and the bug report response is "works as intended". Really?

kenrussell commented 6 years ago

It looks like when requestAnimationFrame was added to workers (which is still in progress in https://github.com/whatwg/html/pull/3677 ), the behavior chosen was to automatically commit frames for OffscreenCanvas contexts which are modified in the rAF callback. This behavior was probably chosen in order to behave most similarly to rAF on the main thread.

In this definition it's an error to call commit() from inside a rAF callback on a worker. The spec and implementations should be updated to throw an exception from commit() in this case, to make it clearer.

Thanks for putting together your examples. Per your Chrome bug report http://crbug.com/859275 , here's a revised version of your resizing example which removes the call to commit() and which works well:

http://jsfiddle.net/gmpkvu30/2/

and a revised version of your 15 FPS animation example which removes the call to commit() and which works well:

http://jsfiddle.net/y36aujrf/3/

commit() can usefully be used within setTimeout() callbacks on a worker, and also within WebAssembly threads, where it's basically the only way to get frames out for display. Yes, in this case events aren't processed on the thread, but WebAssembly threads will expect to use the heap's SharedArrayBuffer to transfer data in and out.

travisleithead commented 6 years ago

Note, we've taken a look at this issue jointly with #288, please refer to that issue for our latest comments.

travisleithead commented 6 years ago

Let's consolidate our discussion into #288. Closing this issue.

slightlyoff commented 6 years ago

Just to clarify from the F2F discussion today, we're happy with the shape off ImageBitmapRenderingContext and OffscreenCanvas, modulo the discussion of commit(), which is what's addressed over in #288. Thanks again to everyone who has participated here and has helped to improve our level of understanding of this complex space.

Swoorup commented 10 months ago

@greggman

I'm not sure if this belongs here but I don't know where else to post it sooo...

I'm hoping OffscreenCanvas allows one WebGL context to be used to efficiently update multiple canvases and it's not clear to me how that is solved in the current proposal or if it's even supposed to.

I am reading this thread, to gain an understanding of doing multiple canvas rendering and am a bit confused as to what is the best way of doing this right now?

greggman commented 10 months ago

For WebGL see this for some ideas on multiple canvases. Even on WebGPU, which is designed from the ground up to render to multiple canvases, the technique at the bottom of that article is the fastest technique.

For more details on multiple canvas you should probably ask on stackoverflow or some other more general help forum/discussion

Swoorup commented 10 months ago

For WebGL see this for some ideas on multiple canvases. Even on WebGPU, which is designed from the ground up to render to multiple canvases, the technique at

I am already using that technique, the only caveat being is there is a certain lag/sync issue when scrolling. From your earlier answer, I was instead pondering about drawing to a large canvas (where views are allocated to certain offset) rather than constantly switching draw textures/buffers and then generating a bitmap, and subsequently rendering the parts of the image using ctx.drawImage(bmp, x, y).