Only tested on Pi 4.
I installed Raspberry Pi OS Lite (you don't need and in fact don't want X -- it'll be more annoying if you have X on, although it may be workable).
(I bet it would work on other Pi models, at least. I bet it would work on other Linuxes on other computers, too, although you might need to adjust the bit layout from 5:6:5 16-bit BGR, to 32-bit BGRA or whatever.)
Install tcl
and critcl
, then run this thing.
$ sudo apt install tcl critcl
$ tclsh little-fbdev-critcl-play.tcl
The screen should turn green!
so I wanted to share the code :-)
Fun to think about how you would implement all the classic graphics stuff (and how to do it fast).
(and if you were writing your own OS/applications, you could throw out the parts that are slow or hard to implement. do you really need PostScript-style paths? how should you specify fonts? how do you scale and rotate stuff?)
I remember doing things like that in college... rasterization / rendering in its purest form, as an algorithmic/optimization problem rather than a 'find the best incantations to talk to the GPU / rendering engine / browser' problem.
(even if you ultimately want to use the GPU, now you can think of that in terms of how it replaces and accelerates parts of this pure software stack, which somehow 'tames' it, at least in my head)
(well, I guess that if I want to state alternatives, I should state the problem first. I want to put graphics on the screen without needing X11 or Wayland installed; I want to talk directly to Linux.)
there's Vulkan, which I'm told is the cleanest/most modern way to do headless graphics (and multithreaded graphics, if you end up wanting that too):
see triangle.cpp: it's 1236 lines :-)
i really like the look of this intro blog post:
(I mean, it makes sense that it's complicated. your GPU is a whole other computer, one which seems much more ad hoc and proprietary than your CPU computer, and this is the interface to program that computer)
(I think you can use OpenGL headlessly, too. I do hear that talking to X is also not that bad if you can call C functions, so that may be a conceptual alternative.)
TODO: say something about libdrm?? this post
I've been playing with Tcl a lot recently, and this is a tiny spin-off of that work. (It's useful to prototype with / lets me dodge the enormous upfront psychological drain of spinning up an actual graphics stack.)
turns out critcl is really nice.
(I don't get why I need to use the bytes
type instead of char*
in
the fillRectImpl
function interface. Any ideas? critcl doc for
reference)
Compare to the other little-
projects I have that use
Lua or LuaJIT instead:
they have a common vibe: one script you can read & run, that lives in
one file, that talks directly to the OS and uses the real OS functions
(open
, connect
, write
, ioctl
, whatever) that you can read
about on man
pages and Stack Overflow and see the stack trace of in
gdb
. no JNI or Python FFI or Lua FFI or (God forbid) Node FFI stuff
where you have to write some weird C or C++ file and figure out how to
compile and link it