2,704 karma · joined October 19, 2011
Working full time on a digital signage service:
https://info-beamer.com
See https://dividuum.de/ for other projects.Contact me at fw@dividuum.de / @dividuum
* How do you make sure you capture all mapped memory within a process? Walking something like /proc/self/maps?
* Does this include the stack and if so, doesn’t this cause havok when you write back. And if it doesn’t include the stack, can’t run things out of sync easily?
* This is then a page sized undo/redo, so it isn’t atomic with regards to actions triggered. Wouldn’t partially undoing such changes easily cause an invalid state?
> TinyKVM can fork itself into copies that use copy-on-write to allow for huge workloads like LLMs to share most memory. As an example, 6GB weights required only 260MB working memory per instance, making it highly scalable.
It’s a bit more than running a program under seccomp strict mode, but conceptually similar, so running anything too complicated likely won't work. You certainly won’t be able to sandbox chromium for taking website snapshots for example.
I remember being impressed by this approach, so I shamelessly copied it for my programming game: https://github.com/dividuum/infon/blob/master/renderer.h :)
Yeah. The Pi3 -> Pi4/5 jump was quite a massive change in how things work. I've been writing my own playback engine for 10 years now and that one was quite challenging. Precise playback start is something my software supports: You control everything in Lua and can, for example, preload a video and then start it based on either internal logic or based on an external trigger. Up to the Pi3, my software also supports dynamically adjusting the HDMI clock, so the vsyncs of multiple displays are synchronized. Customers have been using that for almost 10 years for video wall playback.
If you go with the hosted version of the software, provisioning is as simple as extracting a single 60MB zip file to an empty SD card and placing that into the Pi. If needed you can even use the API to preconfigure that ZIP file to include settings like WiFi.
I also added a similar mechanism to my own product years ago. Works flawlessly. Using content based addressing already made it quite easy to implement.
From my experience there is no magic at all. You have to wire everything up yourself. Different cards expose different properties and limitations, albeit all through the same API. But you have to handle the differences yourself. For example the Pi's primary VC4 graphics card has 48 planes to place framebuffers onto the screen, while the minimal implementation their 7" display uses only has a single plane. Your code has to know how to handle this. DRM doesn't abstract that away.
Yep. At least now the Pi's implementation does cause kernel tracebacks or lockups any more. Was rough in the beginning :-}
Flipping is supported (but not 90/270 rotation) and I use that together with a recently added transpose feature in the Writeback connector to support mirroring the primary VC4's output to the minimal DRM implementation of the official 7" display.
I'm using the Writeback connector to support screenshots, but copying every plane's configuration would be too much sometimes, so I heuristically compose some framebuffers via GL and then only place the remaining framebuffers (including the GL one) on Writeback and HDMI.
I'm also falling back to GL composition in some cases or while taking screenshots to avoid composing twice (HDMI + Writeback) if the scene is too complex or if other restrictions make that mandatory: Planes can only be rotated 0/180 degrees on the Pi HVS, so rotating a video to a portrait orientation is done on the GPU.
There is a ton more to learn: KMS (kernel mode setting) allows fine control over the video mode in case you cannot or do not want to rely on auto-detection.
Then there's the atomic API: Unlike in the blog post, all changes applied to the output (from video mode to plane positions or assigned framebuffers...) are gathered and then applied atomically in a single commit. If necessary you can test if your atomic commit is correct and will work by doing a "Test only commit" before doing the real commit. Making changes atomically avoids all kinds of race conditions resulting in, for example, screen tearing.
Then there's the interaction with video decoding: Using FFmpeg on the Pi allows you to access to hardware decoder. They produce DRM framebuffers for each video frame. You can then directly assign them to planes and position them on the screen. The resulting playback is zero-copy and as fast as it gets on the Pi.
Another fun feature is the Writeback connector, which unlike the one ending up as an HDMI signal allows you to write your output to a new DRM framebuffer. This can, for example, be used to take screenshots of your output or even feed the buffer back into a video encoder.
One very frustration aspect is that there is basically no real documentation, especially about semantics. I guess it makes sense if you consider that there's probably only a limited number of API consumers (like desktop compositors, special video players).
> In the worst case, two sdram clients accessing different pages of the same bank, may cause repeated closing and opening of the pages, harming the usable bandwidth you can achieve. Which pages belong to a bank depends on the physical address lines of the buffers used. We have found that it is pretty common for buffers to be allocated in pathologically bad ways.
> NUMA allows us to have more control over this. We can split our sdram, into, say, 8 NUMA regions, and configure the kernel to interleave the allocations between the regions. In addition the sdram controller allows the address bits used for segmenting the banks to be reconfigured (which we've exposed through eeprom config SDRAM_BANKLOW).
The original 2600+ lines of C++: https://gitlab.freedesktop.org/asahi/mesa/-/blob/main/src/ga...
The translated code: https://gitlab.freedesktop.org/asahi/mesa/-/blob/main/src/as...