First class partial redraw support
The current implementation of the graphics backend features two framebuffers that are rasterized and blitted alternatingly. The advantage of this approach is that blitting and rasterization can happen at the same time on different cores. The disadvantage is that for applications that if an application does not want/need to refresh the entire screen it needs to write its changes to both framebuffers, effectively doubling rasterization time in all cases (unless we overlooked some sort of caching; pippin, you know about this best, could you give feedback?).
We think this is a poor choice for typical applications and should not be the default. Vector graphics rasterization on the ESP32S3 is a bit sluggish at the moment, which is only compounded by the many of the ratherintricate many system fonts. The standard applications "gay drums" and "worms" both had to implement partial redraws to achieve reasonable frame rate, which does make the codebase a bit uglier and, even worse, may pose a considerable barrier for beginners that could be easily avoided.
Of course, tradeoffs must be made, so let us investigate the benefits of the dual parallel framebuffer architecture: Assuming for starters that no other comparably cpu heavy tasks are running, it is easy to see that if blitting and rasterization take the about the same time the framerate is roughly doubled, which is very neat. However, as soon as there is a significant imbalance between those two execution times this advantage fades quickly since we care about the ratio of framerates. Also, if another very heavy task (the bl00mbox render task runs completely single core and can get quite thick at times, see shoegaze) is running, rasterization and blitting may easily be pushed to the other core, in which case the advantage is entirely lost. Similarily, many small tasks that sum up to the approximately same CPU load as the graphics engine or more also negate any performance gain entirely. This means the dual parallel framebuffer approach yields a framerate gain worth mentioning only if the following conditions are met:
- The rasterization task cpu load must be within a certain fixed range (we assume blitting time to be roughly constant)
- The graphics engine is the primary consumer of computational resources
Combining 1) and 2) implies an advantage only at high frame rates. Many existing applications are not really in that spectrum.
Keeping in mind that we want to possible run intricate UI with captouch gestures and bells and whistles in the micropython task and that bl00mbox really can bl00m when given some resources (again see shoegaze, we think we did a good job w sound design there, took us a few hours :>) we would consider the above conditions within context of the goals of the badge an edge case that was relevant when people used it as a name badge but does not really fit in more intricate future applications. The massive +100% cpu load penalty of twice the rasterization time for partial redraws however has popped up in the wild and will continue to do so (think something like an LSDJ tracker interface where partial redraws could make the UI hella snappy even under heavy audio load).
With this in mind, we'd like to propose to disable framebuffer alternating. The code can remain there, and if somebody feels like it they can implement a mpy binding for applications to enable it again (and the os disabling it again on_exit), but we don't think it matters much given what we've seen in applications so far.
Of course, we see the firmware only from our very limited perspective and others may have had different experiences, so we'd be interested in the general opinions of y'all on this!
PS: This alone is insufficient for proper partial redraw support as the volume overlay is written to the framebuffer. We'd need to add proper compositing down the line, but that doesn't seem too tricky from what we've seen. "gay drums" has a very unstable hack to circumvent the problem which works okay if we don't mess with the animation time so resolving this can be postponed a tiny bit without requiring refactor from users. We would propose to do this in a second step.