Question about different commands, sizes, and buffer alignment
I'm not an expert, so my thoughts may be flawed here.
Some investigation that I have done has left me a little bit confused.
At the end of the draw pipeline, nuclear starts to push different primative draw commands into a continuous buffer stored in the CTX. Each new command gets tacked onto the end except in the case of a popup which gets stitched in at the nk_end call.
Within all of these pushes and buffer writing and pointer movement, there is a lot of math being done for memory alignment of the commands in the buffer. This isn't necessarily a bad thing (it's functional today). But I find it rather confusing. If I were to rewrite this, I would consider making a command type as a union of all command type to be pushed, that way alignment is lnt really something that anyone needs to consider. Every command would be the same size.
That, or perhaps I would try a linked list setup similar to how the Amiga RTOS handled its tasks.
@RobLoach I'm just genuinely curious about the design decision here. And wondering what the teams thoughts on playing around with that structure are.
What you're proposing does sound interesting. One of the core principles of Nuklear was the ability to run on low-end devices, in software. If there are ways to improve memory usage, I'm sure others would be interested as well.
I believe since each command could be a different size, a union was not considered.
I absolutely understand, and I work with very low-end devices every single day for my job.
I think nuclear does a fantastic job of handling all of this stuff from a low end perspective.
However, my thoughts on the union of the command primitives actually ends up increasing the overall size of the commands. Being that not every command is the same size by creating a union, you will then force all commands to be the same size as the largest command. .
Before anybody freaks out, this may not necessarily be a problem. You need to consider what sizes we're talking about. And from what I can tell, the size of each command that gets pushed onto the buffer is pretty small.
Usually two points for a line, or a rectangle, or a trapezoid, those are usually some of the biggest. If you start to go bigger for things like text, the structure ends up simply being a pointer to a text buffer. So what gets pushed ultimately is of a smaller size because it just needs to care about the pointer. But then it references a larger size. So in reality, the union itself can say pretty small.
Okay, so you've increased the size of the memory buffer by a little bit. Is that such a big deal? What benefits do we gain by doing this?
Potentially code clarity and easier maintenance from developers. Also, potentially when you have memory alignment like this and you've got standard sizes as you iterate, that could make compilation loops a lot quicker. It can make CPU usage better. You might be able to get the compiler to vectorize or loop unroll, because it doesn't have to think so much, or at least it can pre-calculate at compile time, how far to jump, how many times.
Is all that better or worth it? I don't know. And we are honestly not gonna know unless we actually get in and start taking measurements and stuff.