#graphics

Making really tiny WebAssembly graphics demos

I’ve been studying WebAssembly recently, which has included porting some of my m4vga graphics demos. I started with the Rust and WebAssembly Tutorial, which has you use fancy tools like wasm-pack, wasm-bindgen, webpack, and npm to produce a Rust-powered webpage.

And that’s great! But I want to know how things actually work, and those tools put a lot of code between me and the machine.

In this post, I’ll show how to create a simple web graphics demo using none of those tools — just hand-written Rust, JavaScript, and HTML. There will be no libraries between our code and the platform. It’s the web equivalent of bare metal programming!

The resulting WebAssembly module will be less than 300 bytes. That’s about the same size as the previous paragraph.

Rewriting m4vgalib in Rust

If this isn’t your first time visiting my blog, you may recall that I’ve spent the past several years building an elaborate microcontroller graphics demo using C++.

Over the past few months, I’ve been rewriting it — in Rust.

This is an interesting test case for Rust, because we’re very much in C/C++’s home court here: the demo runs on the bare metal, without an operating system, and is very sensitive to both CPU timing and memory usage.

The results so far? The Rust implementation is simpler, shorter (in lines of code), faster, and smaller (in bytes of Flash) than my heavily-optimized C++ version — and because it’s almost entirely safe code, several types of bugs that I fought regularly, such as race conditions and dangling pointers, are now caught by the compiler.

It’s fantastic. Read on for my notes on the process.

Racing the Beam

This post is the fourth in a series looking at the design and implementation of my Glitch demo and the m4vgalib code that powers it.

In part three we took a deep dive into the STM32F407’s internal architecture, and looked at how to sustain the high-bandwidth flow that we set up in part two.

Great, so we have pixels streaming from RAM at a predictable rate — but we don’t have enough RAM to hold an entire frame’s worth of 8-bit pixels! What to do?

Why, we generate the pixels as they’re needed, of course! But that’s easier said than done: generate them how, and from what?

In this article, I’ll take a look at m4vgalib’s answer to these questions: the rasterizer.

A Glitch in the Matrix

This post is the third in a series looking at the design and implementation of my Glitch demo and the m4vgalib code that powers it.

In part two, I showed a fast way to push pixels out of an STM32F407 by getting the DMA controller to run at top speed. I described the mode as follows:

It just runs full-tilt, restricted only by the speed of the “memory” [or memory-mapped peripheral] at either side…

But there’s a weakness in this approach, which can introduce jitter and hurt your video quality. I hinted at it in a footnote:

…and traffic on the AHB matrix, which is very important — I’ll come back to this.

Quite a bit of m4vgalib’s design is dedicated to coordinating matrix traffic, while imposing few restrictions on the application. In this article, with a minimum of movie puns, I’ll explain what that that means and how I achieved it.

Pushing Pixels

This post is the second in a series looking at the design and implementation of my Glitch demo and the m4vgalib code that powers it.

Updated 2015-06-10: clarifications from reader feedback.

For the first technical part in the series, I’d like to start from the very end: getting the finished pixels out of the microprocessor and off to a display.

Why start from the end? Because it’s where I started in my initial experiments, and because my decisions here had significant effects on the shape of the rest of the system.

Introducing Glitch

Hey, look! I made a little graphics demo!

Making Thingiverse Faster

Thingiverse has deployed my modifications to Thingiviewer, which were first seen on this very site powering the 3D Thing Previews. The internet is now just a little bit better. Woot!

m4vga

You can now view these demos in your browser!

m4vga is a technique/library for hacking the STM32F407 to generate high-quality analog color video signals with just a handful of resistors.

I wrote the C++ version between 2012 and 2015, and rewrote it in Rust in 2019 to put my money where my mouth is.

I did this because it was an immense technical challenge. Read on for details, including links to a series of blog posts I wrote examining the code in detail.

Web Demos

Here’s a collection of WebAssembly graphics demos and effects I’ve written. Most of these are trying to pack the most pizzazz into the smallest number of bytes.