Porting MyPaint to Rust (report and some thoughts)

Hi everyone,

I’ve been porting MyPaint’s engine to Rust, and I’m posting it here because this is where the original comes from.

One thing first, because it changes how you should read the rest: almost all of the code was written by an AI model, DeepSeek V4.1 Flash, working from my instructions. I decide what goes in, read the diffs, run the tests and the gate, and say what is wrong when something breaks. But I can’t claim I typed it, and I’d rather say that now than have it come up later.

The reason I started is simple. I use MyPaint, and the brush feel is better than anything else I’ve used. I like it a lot. Seeing that the last release was still 2.0.1 from 2020 felt like a waste of something good.

So I asked an AI why a project like this gets so little work done on it, and the answer was the tech stack. I did not check that claim myself, and it may be partly wrong. But it matched what I could see from the outside, and it is what made me look at a rewrite. I would rather say that than pretend I worked it out on my own.

Rust builds for Windows, Linux and macOS from the same code, which a painting program needs, and the ecosystem now has the pieces: wgpu for GPU rendering on Vulkan, DX12 and Metal, winit for windows and tablets, egui for the interface. Painting wants fast pixels and low input latency, and that’s the part Rust does well.

So the rule I set was to keep the behaviour, not to redesign it.

What exists now is a tile surface with layers and mipmaps, the document model and undo stack, nine tool modes, brush and colour panels, ORA and PNG, autosave and recovery. It runs on Windows. Linux and macOS have not been built, so I can’t call it cross-platform yet. To Linux users, sorry: my machine is almost out of disk space, so I can barely even attempt a build there. If you try it and it breaks, I’d like to know where.

There’s also a gate that sends the same brush and the same events through libmypaint and through my engine, then compares the buffers byte for byte. 194 of the 196 official brushes come out identical, and I know why the other two differ. It is one trajectory at one canvas size, so it doesn’t prove much beyond itself.

Two things I’m unsure about, and I’d rather write them down:

  • Whether the engine really keeps 100% of the original’s semantics and feel. The gate compares pixels along one path. Tilt, zoom, rotation and other canvas sizes are not covered, and someone who paints every day would notice a difference I can’t measure.

  • Large canvases with large brushes still stutter. I have not solved this, and I honestly don’t know how to yet. It is the hardest problem in the project for me.

I plan to keep working on this, slowly, for as long as I can. I would also like company on it, though I’m aware that saying so can read as asking strangers to do my homework. So, no pressure either way: if you’re curious, the gate and the missing UI panels are where an extra hand actually helps. If you’d rather just try it and tell me what feels wrong, that’s just as useful to me.

Source: https://github.com/Icey0111/mypaint-rs Windows build: https://github.com/Icey0111/mypaint-rs/releases

Thanks.

Other programs using MyPaint’s brush engine, like Krita, GIMP and Drawpile, won’t want to or can’t take a Rust dependency. So even discounting the “it’s yet another sucky AI rewrite” that nobody else will want to touch with a very long stick, this also useless as far as the developer community around the engine is concerned.

Does this mean that MyPaint’s brush engine exists in Krita? I’ve never looked into this. Also, if you have any suggestions for what I should do, what would they be?

Yes, it exists in other programs. Please don’t look into it, we have enough people wasting our time with AI nonsense.

I’d suggest you find something better to do than starting the umpteenth AI rewrite thing. If the maintainers of a program wanted to throw AI tools at it, they could do it much better than someone who doesn’t know what they are doing.

I apologize for my immature ideas, and thank you for your advice.