PineTime is based on the nRF52 microcontroller, and it's connected via SPI to the ST7789 display controller. Details here: https://medium.com/@ly.lee/optimising-pinetimes-display-driver-with-rust-and-mynewt-3ba269ea2f5c?source=friends_link&sk=4d2cbd2e6cd2343eed62d214814f7b81
ST7789 uses a non-standard SPI interface: There is an additional Data/Command pin that needs to be flipped to indicate whether we are sending SPI commands (e.g. set X and Y coordinates) or data (e.g. the bitmap to be rendered).
This means we can't send a continuous stream of SPI commands and data. Our program needs to intervene and flip the Data/Command pin, which slows down the rendering throughput. DMA wouldn't work here.
Unless... We have the entire bitmap already in RAM, and we are doing one huge DMA from RAM to ST7789, in a single SPI command. But ST7789 doesn't have RAM to hold the entire screen (see the article). And it's a bad use of RAM anyway.
We could put the bitmap into the external SPI Flash and do DMA from the external flash to ST7789. This is good for static bitmaps, like a black screen or a startup logo. Not good for dynamic UIs like ours.
So for interactive UIs it's hard to hit the theoretical max display update speed. Even if we tried, the RAM would be better used for other application functions.
I'm working on using the same st7789 screen for another project. I'm not sure of your driver implementation, but according to this post https://devzone.nordicsemi.com/f/nordic-q-a/38711/controlling-st7789-lcd-with-nrf52-dk there are a few tricks that can be employed for speedups. Writing a 4 pixels is slower than writing a defined 2x2 area as there is more switching. The Nordic nrf_gfx library for text writes pixels which is very inefficient. Each pixel requires a command and data, while the rectangle requires only one command and a stream of data.
Andy Cruz in the post implemented "fast_spi driver" but I couldn't make it work in his SDK 14.2 and spent hours trying to port it to 15.3 (I haven't migrated project to SDK16 yet due to not believing S332 was supported, which I was wrong).
EDIT: read post, you've done all of Andy's suggestions it seems