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?
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.
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.
I've never though about that. It's actually a good question.
You should use requestAnimationFrame instead of setTimeout.
http://paulirish.com/2011/requestanimationframe-for-smart-animating/
http://paulirish.com/2011/requestanimationframe-for-smart-animating/
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).
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?
**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.
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.
thank you all so much!!!)!
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.
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.
Thank you, texel. I understand now
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?
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.
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.
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.
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.
texel: Doesn't setInterval rely on the frame being rendered in the allotted time?
you don't want two frames to be rendered at the same time because rendering it takes more than 16ms
@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:
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);
}
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 ).
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 ).
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 ?