ILI9341 Speedup

bitbank

Member
Hi everyone. I'm new to the Teensy forum. I just got the Teensy 4 and 4.1 and decided to look for ways I could help the libraries. I optimize code for a living and in my spare time (I can't help it ;)). I also like to work on display libraries, so I decided to focus my attention on the ILI9341_t3 lib provided with the Arduino support of the Teensy. I was able to make some significant improvements to the speed without breaking compatibility. My last set of changes hasn't been merged yet, but you can try it here:

https://github.com/PaulStoffregen/ILI9341_t3/pull/61

A couple of my other PRs were already merged recently. The complete changes include:
  1. You can now explicitly set the SPI speed (still defaults to 30Mhz, but 80Mhz works for me)
  2. Speedup of setAddr() only sets each axis if it changed (helps almost every operation)
  3. Sped up circle and rounded rect drawing. Most apparent on larger circles/rect, can be 100% faster
  4. Sped up proportional font drawing - 40-100% faster depending on the character
  5. Sped up GLCD font drawing (default 5x7 fixed font),

Here's a video if it in action running at 80Mhz
 
Hi and Welcome,

I thought I responded earlier today, but looks like I may have forgot to actually post.

I may have to borrow some of your improvements and integrate them into my version of the library: https://github.com/KurtE/ILI9341_t3n

Or I do take Pull Requests :D

The _t3n library already has the ability to set the clock speed (both write and read). Also support for using all of the different SPI busses that each processor supports, plus frame buffer, DMA..

But thought about caching the X and Y but never got around to do so.

So again great stuff!
 
Hi Kurt,
Thanks for sharing. I write my own display libraries too, so it's kind of redundant to keep improving all of the various forks of these libraries. You're welcome to make use of the new code any way you can. My changes basically involve removing the last remnants of single-pixel operations and removing any bit-at-a-time operations and replacing them with smarter ways (e.g. __builtin_clz). If you have something that could use my 'touch', just point me to it and I'll take a look.
 
Thanks, the one I always meant to do and never got around to is to optimize the setAddr window to only update the X or Y if they change.

Note: I will probably do it slightly different as I don't believe that using static variables here will work properly if you have multiple displays. So will instead use instance variables.


Thanks again
 
I mentioned this idea in a chat... thought I'd also put it here on the forum in case anyone is interested or wants to give it a try.

The main problem I hear from people lately isn't raw speed, but the "tearing" issue where writes aren't done in sync with the display's vertical refresh. While the ILI9341 has a TE (tearing effect) pin that pulses once per vertical refresh, very few display boards bring that pin out.

But maybe a library could query the display at regular intervals to learn where it currently is within its vertical refresh? Then it could learn the actual refresh rate the display is using and manage to stay in sync. This probably only makes sense for libraries like Kurt's ILI9341_t3n which have a full frame buffer on the Teensy side. Maybe parts of the buffer could be marked as dirty, and then the library could refresh those lines in sync with the display's refresh so freshly drawn pixels always appear on the next vertical scan.

This is the ILI9341 command that might be able to give this info. Maybe?

scanline.png
 
@bitbank, welcome to the family! I think you will find this community super helpful and super friendly.

@bitbank and @kurtE I really appreciate your hard work and optimizations and admire your abilities (and of course Pauls). I use the heck out of ILI9341 displays and find the _t3 driver totally rocks. If you are taking requests here goes

1. I've written some high-level graphing functions and i would really like to get text width of a set of characters before drawing so I can center text or even draw right justified. The adafruit_gfx lib has a getTextBounds() and I tried to adapt to to my own version, but the code is a bit above my capability.
2. I've written a flickerFreePrint lib that remembers previous text and paints any text changes to background color before drawing in fore color. Iv'e tested it with many fonts and seems to work well. I've made several updates since i told the forum, but if you want to have the code and add to your libs, i'll gladly hand it over
3. I love all the updates but would really like everything merged into a single lib. As of now i'm not sure to grab this lib or that.

Welcome home.
 
The adafruit_gfx lib has a getTextBounds()

I've put getTextBounds() onto my (lengthy) TO-DO list. Can't make any promises of a time frame, other than it definitely won't happen for the upcoming 1.53 release, and because it's now on my list I will not forget to eventually do it.
 
I've put getTextBounds() onto my (lengthy) TO-DO list. Can't make any promises of a time frame, other than it definitely won't happen for the upcoming 1.53 release, and because it's now on my list I will not forget to eventually do it.

@KurtE implemented getTextBounds as well as using GFX fonts into his ILI9341_t3n library as well as having frame buffering support. Any potential of using that library in teensyduino instead of the ILI9341 library. If not some of those features could be ported over to the ILI9341 library like using GFX fonts, scrolling, etc?
 
Get text bounds

I've also been researching for a few hours to no avail. Get text bounds would be really useful in keeping my text aligned. I recently came from a samd51 to a teensy 4 but unable to port all of my code as I cant align the fonts. Has anyone come up with an ad hoc solution that there are willing to share? Kind Regards
 
As mentioned in the ILI9341_t3n we have such functions:
Code:
  void getTextBounds(const uint8_t *buffer, uint16_t len, int16_t x, int16_t y,
                     int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h);
  void getTextBounds(const char *string, int16_t x, int16_t y, int16_t *x1,
                     int16_t *y1, uint16_t *w, uint16_t *h);
  void getTextBounds(const String &str, int16_t x, int16_t y, int16_t *x1,
                     int16_t *y1, uint16_t *w, uint16_t *h);
  int16_t strPixelLen(const char *str, uint16_t cb=0xffff);  // optional number of characters...
 
Back
Top