Saturday, 19 September 2020

Canvas Double Buffering

In the past I did a bit of Html Canvas programming (for example: this), and I never needed to resort to double buffering to avoid flickering. I did not pay much attention to it at the time, but the other day I came across some discussion as to whether double buffering was necessary. Though you can find some discrepancies and some samples claiming to cause flickering, the main answer is that No, you don't need to implement double buffering, which leads us to something more interesting, why not?

The fiddle in this answer is rather instructive, but what the author says Lucky for us every canvas implementation implements it (double buffering) behind-the-scenes for you. could be misleading.

If we have an understanding of how the event loop works in the Browser (or in node), we know that user interactions, timeouts, requestAnimationFrame... enqueue tasks in a macrotask queue (for the current discussion we can omit the microtask queue), and that the event loop will take tasks from that queue one by one, executing the corresponding javascript code, and updating the DOM (rendering) after each task is completed. This "updating the DOM after the ask is completed" is essential for this explanation. From the article:

Rendering never happens while the engine executes a task. It doesn’t matter if the task takes a long time. Changes to the DOM are painted only after the task is complete.

So if we are drawing animations to a canvas (normally based on requestAnimationFrame), each animation frame javascript code will run as part of a Task, and when that frame code is completed, the rendering will happen. So all the sequential drawing calls that we do to the Canvas Context (clear the canvas, draw a rectangle, draw a circle...) won't be visible until the whole sequence of drawing operations is complete (the task is complete) and then the rendering-drawing takes place.

I don't think the Canvas element uses a second (hidden) canvas to draw on it during the Task (javascript) execution phase, and then draws that Canvas on screen during the rendering phase, I just think that all those drawing operations are stored, and then, during the rendering phase, they are painted to the canvas.

No comments:

Post a Comment