yuri91 / ili9341-rs

A WIP, no_std, generic driver for the ILI9341 (and ILI9340C) TFT LCD display
Apache License 2.0
58 stars 50 forks source link

Drawing is extremely slow compared to Arduino library #14

Closed pepijndevos closed 2 years ago

pepijndevos commented 4 years ago

I have this display hooked up to my Arduino Mega as well as a STM32F4DISCOVERY. On the Arduino, I can clear the screen in under a second, while on the Discovery board, I can see the pixels crawl by. Example: https://twitter.com/pepijndevos/status/1256983103693901825

I have not studied the Rust code, but I have done some optimization on the Arduino side, and the key thing to realize is that setting bounds and starting/stopping transactions is costly. For example, I obtained major speedups by drawing diagonal lines in vertical/horizontal segments, and using long transactions when possible.

More info: https://github.com/adafruit/Adafruit_ILI9341/pull/3 https://github.com/adafruit/Adafruit-GFX-Library/pull/36

This might be related to #10, but I think there are more fundamental problems, because the rectangle function does seem to be implemented, but still very slow.

[edit] It does not seem to do something obviously dumb. It's also entirely possible the code I shared in #13 sets the SPI to 5Hz or something stupid like that. Though even if it's just a misconfiguration on my end, there is definitely room for optimization.

jamwaffles commented 4 years ago

Just to check, are you running with --release? That improves speed a lot.

That said, as I mentioned on Twitter earlier, I think a decent amount of blame lies with embedded-graphics and a poor implementation of the DrawTarget trait. We're aiming to fix this in v0.7.0 which I hope will help allow drivers like this one to do a better job of optimising writes.

yuri91 commented 4 years ago

Looking at the video it seems honestly too slow, so I would double check that you are running in release mode, and the clock speeds of the micro and the SPI.

Drawing rectangles should already be as fast as possible (although buggy when using embedded_graphics at the moment.

For lines, I will look at your links when I have time (already tracked here)!

pepijndevos commented 4 years ago

Running with --release fixes the extreme slowdown :facepalm: It still seems somewhat slower than Arduino though, so once I have time I should put a scope on the clock to see the frequency and idle time.

But yea, for things other than squares, the linked PRs on Adafruit definitely contain some tricks to speed up things.

Something else I'm completely clueless about: Is there a HAL abstraction for FIFO/async SPI? With a blocking loop you're almost guaranteed to have some idle time between transfers.

flaminggoat commented 4 years ago

I think most of the slow down is caused as the pixels are transferred in individual SPI transactions where the pixel location then colour is sent. I wrote an enhancement that improved the speed significantly but this has later been removed. https://github.com/yuri91/ili9341-rs/pull/6/commits/20c22260a66b9ab5d197580f77e4b106a52afc5e

yuri91 commented 2 years ago

Both the spi driver implementation and embedded_graphics changed since this issue was opened. I have no way of comparing with arduino myself now, so I will close the issue. Feel free to open a new one if the slowdown is still there.