pouët.net

javascript canvas context vs blits

category: code [glöplog]
 
I don't understand when a canvas context in javascript gets 'blitted' to the browser. How does it understand when a 'frame' is done? just long delay between draw operations? It's really kinda smart, I can clear and draw repeatedly and on all browsers there is no flicker. anyone know the mechanics of it?
added on the 2011-12-29 17:33:50 by sigflup sigflup
I'm pretty sure the browser doesn't 'blit' the canvas context. It just draws some vector graphics whenever you tell it to. It doesn't have any understanding of a 'frame' at all. That's also why you'll have to clear the canvas by hand on every frame.
added on the 2011-12-29 17:41:37 by paldepind paldepind
here take this for example https://devio.us/~sigflup/wait/ in main.js's draw_timer why doesn't fillRect ever get shown before the line-paths? it always get's updated to the browser's window after these two things and never between them. I'm wondering why it never does an update between.
added on the 2011-12-29 17:53:25 by sigflup sigflup
I've never though about that. It's actually a good question.
added on the 2011-12-29 18:01:33 by paldepind paldepind
You should use requestAnimationFrame instead of setTimeout.
http://paulirish.com/2011/requestanimationframe-for-smart-animating/
added on the 2011-12-29 18:31:14 by mrdoob mrdoob
And, answering your question... isn't it that the whole code is executed/computed using a backbuffer, and then blitted into the visible rectangle once it's done and then doing the same 20ms later (as per your setTimeout call).
added on the 2011-12-29 18:33:37 by mrdoob mrdoob
Maybe it (meaning the browser; this may not be true for all browsers) treats everything inside a single timeout callback as a single frame, and buffers it until the code returns from the callback?
added on the 2011-12-29 18:44:59 by nitro2k01 nitro2k01
**quick reply**: Yes, there is a back buffer, and it is blitted to the front buffer when the function doing the draw calls falls out of scope.

Oh, and please, pretty please, don't use the shim for requestAnimationFrame Mr.Doob linked to. That one yields artificially bad performance in browsers not supporting requestAnimationFrame yet. This shim for requestAnimationFrame addresses this very flaw in Paul Irish's shim.
added on the 2011-12-29 21:18:54 by p01 p01
thank you all so much!!!)!
added on the 2011-12-29 21:44:18 by sigflup sigflup
It is about how a browser executes code and manages the DOM:

1) While Javascript is executing, no redraws (visual updates to the screen) will happen*

2) Just after Javascript ends execution, the DOM is updated if needed, and a redraw happens. In the case there has been changes to any canvas element, its back buffer will be blitted now.

3) After the redraw, the browser waits for events and/or timeouts/intervals to happen. When any of then happens, the related event listener/timeout callback is executed and the browser goes to point 1) again.

*Note: while "classic" Javascript is single threaded, the recent Web Worker technology allows multiple threads of Javascript, but as web workers doesn't have access to the DOM, the sequence I've exposed remains the same.
added on the 2011-12-30 03:31:09 by texel texel
Thank you, texel. I understand now
added on the 2011-12-30 04:09:49 by sigflup sigflup
Its pretty awesome how fluent js runs on mobilephones..
p01: as far as I understand it, as long as the requestAnimationFrame call is done the first thing on the render loop, the simpler shim should be cool too. isn't it?
added on the 2012-01-02 17:45:00 by mrdoob mrdoob
I believe setInterval is better suited for animation than setTimeout.

Concretely, the exact behaviour expected from p01's link, should be done automatically with a setInverval(foo, 16), and without the overhead of doing maths and setting new timeouts.

added on the 2012-01-02 19:24:11 by texel texel
Mr.doob: Should be cool enough, yes! Although I have seen bug reports about "web demos" being significantly slower in Opera solely because of that shim.

The spec is a quite open wrt the frame rate you should get using rAF.

On desktop browsers, people seem to expect rAF to yield 60fps ( which is only possible if the code around the rAF takes less than 17ms of course ).

But then there is implementation details like the one in Firefox that makes rAF yield a frame rate of 1000/(16+N) fps where N is the time spent by the callback of rAF ( in which case Paul's shim is perfect ). AFAIK Webkit's implementation doesn't have this.
added on the 2012-01-02 20:12:37 by p01 p01
texel: Doesn't setInterval rely on the frame being rendered in the allotted time?
added on the 2012-01-03 06:35:44 by nitro2k01 nitro2k01
you don't want two frames to be rendered at the same time because rendering it takes more than 16ms
added on the 2012-01-03 11:11:08 by _-_-__ _-_-__
@nitro2k01:

Please read this:
http://ejohn.org/blog/how-javascript-timers-work/

There is something I'm not sure, and I believe it is browser dependant, and it is if after a redraw in a buffer, the browser waits sync or async for vsync to send the buffer to vram.

The ideal IMHO would be to do it async and with a double buffer, and then update the buffer to vram, but I don't really know that far how it works... and as I said, it is probably browser dependant.

If it is done sync, it would change a lot how setInterval works for animations, as it would be different depending on when setInterval was set during the time from frame to frame.

Ad Mr. Doob pointed out, it would be better to set the interval/timeouts as the first thing after a redraw... I would do this to ensure it works good:
Code: var animationInterval; function animationLoop() { // some code here } function ini() { // some changes in the DOM should be added here to ensure a redraw window.setTimeout(function () { animationInterval = setInterval(animationLoop, 16); }, 0); }
added on the 2012-01-03 11:48:20 by texel texel
texel: All your questions about vsync and co are not only browser dependent, they are also platform dependent, and also driver depedent to some extent now with HW acceleration. Since most browser engines are built to be portable, it's safe to assume that most of them use a back buffer in their own pixel format ( normally as close to the metal as possible ) and blit it to vram ASAP in case of CSS induced reflow/redraw and at least once the function falls out of scope in case of JS induced reflow/redraw.

Also IINM, setTimeout and setInterval were de facto standards and only properly specified ~2 years ago.

FWIW I do prefer setTimeout over setInterval for it gives a little more control with it's 4ms cap ( as opposed to 10ms ).
added on the 2012-01-03 14:23:57 by p01 p01
Now that I think about Mozilla's current implementation of rAF, I just don't difference with setInterval or setTimeout. Yes there is the throttling but mmmmh which browser doesn't throttle them already ?
added on the 2012-01-03 14:26:36 by p01 p01

login