-- Leo's gemini proxy

-- Connecting to gemini.ctrl-c.club:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

Impedance Mismatch in Bindings


I love working Common Lisp. Instead of compiling stuff and trying it out, I can dynamically change things -- often while the code is running -- to see how things would look in a game, for instance. Compare that to compiling a few dozen times just to get the layout of something right.


There are many C libraries which may be usable in Lisp via foreign-function-interfaces or bindings. The quality of the bindings varies with the abilities of the coders writing the bindings, and the level of understanding of the overall system, especially the C end of it.


Unfortunately, the issue I call 'impedance mismatch' for the lack of a better term, comes up often when using FFIs.


I've been messing around with Raylib, a neat support library for making games. The 'cl-raylib' library is a handcrafted layer translating raylib's C calls to Lispy equivalents. It is a non-trivial effort, and I am very grateful to the author. However....


RGBA hassles

Many (if not all) raylib drawing calls take a color parameter. In raylib (C), a color is represented by a 4-byte value, containing each of the Red, Green, Blue, and Alpha components. An RGBA conveniently fits into 32 bits. In C it is represented by a simple struct, with unsigned byte components, for easy access to the elements; the entire struct can be passed by value in a register.


In Lisp, the default way of handling C structs, is to take them apart and convert them into lists. So a 4-byte RGBA value in C is converted to a 4-element list (r g b a). Sounds innocent enough, but it is now a linked list, and each of the elements is a 64-bit (8-byte) value, and an 8-byte pointer, adding up to 64 bytes.


To make matters worse, the 4 elements are likely in different parts of the memory, and just walking the list will trash 4 cache lines.


So cl-raylib's list of stock colors eats up 64 bytes each. Every drawing call into raylib requires, just for the color parameter, walking the list and packing a 32-bit value. Translating colors back from C (I doubt that happens much, but still) requires consing up a fresh list from a 4-byte value.


Clearly this is a bad way to deal with colors. It makes a lot more sense to keep colors as 32-bit integers, and have a couple of routines to pack and unpack them to lists if that is ever necessary. Or better yet, a few macros to access bytes directly as needed.


It took maybe 10 minutes to change the code with search/replace. I've been waiting for the maintainer to look at the PR for a couple of days now, hopefully it will be done. Otherwise I will have to fork and maintain my own version of the bindings.


I tried to be super sensitive with the maintainer to avoid the face-saving head-clashing that often ensues in such cases.


=>. index

=>.. home

-- Response ended

-- Page fetched on Thu Jun 13 13:41:44 2024