CHIP-8 emulation with C# and Blazor - part 3
Hi All and welcome back to the third article of our CHIP-8 Emulation Series! Last time we started writing a functional CHIP-8 emulator using Blazor Webassembly.
We saw how we can hook up the rendering using an HTML Canvas in Blazor, but we quickly realized that it was not exactly super fast.
The main reason behind it is that we’re updating the Canvas data at each call to RenderFrame(). And that’s expensive.
What if we can do it in the UpdateFrame() method instead? Well, turns out we can, more or less.
We are going to use a “double-buffering” technique, and for it we’ll create 2 separate Canvases, one “on-screen” and another one “off-screen”. The latter will hold the actual frame, and will be updated at each call to UpdateFrame(). If you remember from our last article, this method will be called directly by our emulated CPU, each time it receives the 0xD opcode. This does happen with a way lower frequency than our screen refresh (eg. RenderFrame()), allowing us to achieve an higher frame-rate.
Let’s take a look at the code:
We’ll start off by defining the two canvases. We’ll also use CSS to make sure that only main-canvas-container is visible on the screen.
Now let’s work a bit on our UpdateFrame() method :
As you might have noticed, it’s more or less the same code we had in our previous implementation of RenderFrame(), but this time we’re running the commands on _offscreenCanvasContextinstead.
At this point, RenderFrame() is way more simple:
As you can see, it’s reduced to a simple call to DrawImageAsync(), using the pre-built image data from _offscreenCanvasContext.