Adafruit_GFX : interesting speed problem

Hello

I’m using 1.8" TFT LCD with Sparkfun SAMD21G board. I want to clear screen in main loop and added simple cls void in Adafruit_GFX library.

void Adafruit_GFX::cls(uint16_t cl)
{
  for(int16_t j=0;j<159;j++)
  {
    for(int16_t i=0;i<127;i++)
    {
      drawPixel(i,j,cl);
    }
  }
}

And I call this routine like:

TFT.cls(C4);

While I expected to run this code fastest, it runs too slow than the code below.

TFT.fillRect(0,0,127,159,C4);

fillRect calls this:

drawFastVLine(i, y, h, color);

drawFastVLine calls this :

drawLine(x, y, x, y+h-1, color);

Lastly in the drawline routine drawPixel is being called.

void Adafruit_GFX::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) 
{
  .......
  .......
  .......
  for (; x0<=x1; x0++) {
    if (steep) {
      drawPixel(y0, x0, color);
    } else {
      drawPixel(x0, y0, color);
    }
  .......
  .......
}

I couldn’t undserstand that my cls code runs slower than the lots of code chains. In cls loop, there is no statements, no conditions, calls drawPixel routine by the shortest way.

Have you any idea?

You can "bootstrap" a new hardware display with just an init() and a drawPixel() function.

OTOH, the hardware controller has got many speed ups. e.g. setting a Window and filling it directly. or scrolling the whole screen in hardware.

Your little screen does not matter too much. But just imagine that you were clearing a 800x480 display with drawPixel()

I suggest that you study the Adafruit_ST7735 library. It should be pretty easy to follow.

David.

This is down to the way the TFT commands work, each call to drawPixel() sends thirteen 8 bit commands and each command takes time:

  • 8 bits column command
  • 16 bit x axis address of top left of pixel area bounding box
  • 16 bit y axis address of top left of pixel area bounding box
  • 8 bits column command
  • 16 bit x axis address of bottom right of pixel area bounding box
  • 16 bit y axis address of bottom right of pixel area bounding box
  • 8 bit RAM write command
  • 16 bit colour to plot

To draw a line or rectangular area you can however:

  • 8 bits column command
  • 16 bit x axis address of top left of pixel area bounding box
  • 16 bit y axis address of top left of pixel area bounding box
  • 8 bits column command
  • 16 bit x axis address of bottom right of pixel area bounding box
  • 16 bit y axis address of bottom right of pixel area bounding box
  • 8 bit RAM write command
  • Send many 16 bit colour values to fill the line/box area (with a raster scan)

Thus in principle for a large number of pixels you get close to only needing 2 bytes per pixel to be sent, so it it ~6 times faster.

david_prentice:
I suggest that you study the Adafruit_ST7735 library. It should be pretty easy to follow.

David.

Thank you, I studied a bit while I working on this project. What I want to draw attention is in both routine, drawPixel is being called. It looks like the short loop takes longer time.

bodmer:
This is down to the way the TFT commands work, each call to drawPixel() sends thirteen 8 bit commands and each command takes time:

  • 8 bits column command
  • 16 bit x axis address of top left of pixel area bounding box
  • 16 bit y axis address of top left of pixel area bounding box
  • 8 bits column command
  • 16 bit x axis address of bottom right of pixel area bounding box
  • 16 bit y axis address of bottom right of pixel area bounding box
  • 8 bit RAM write command
  • 16 bit colour to plot

To draw a line or rectangular area you can however:

  • 8 bits column command
  • 16 bit x axis address of top left of pixel area bounding box
  • 16 bit y axis address of top left of pixel area bounding box
  • 8 bits column command
  • 16 bit x axis address of bottom right of pixel area bounding box
  • 16 bit y axis address of bottom right of pixel area bounding box
  • 8 bit RAM write command
  • Send many 16 bit colour values to fill the line/box area (with a raster scan)

Thus in principle for a large number of pixels you get close to only needing 2 bytes per pixel to be sent, so it it ~6 times faster.

Thank you, I wrote earlier such a library for PIC18 and ST7735. I know principle.

I edited the question. Main problem is, in both routine same drawPixel is being called.

strat:
Thank you, I studied a bit while I working on this project. What I want to draw attention is in both routine, drawPixel is being called. It looks like the short loop takes longer time.

Thank you, I wrote earlier such a library for PIC18 and ST7735. I know principle.

I edited the question. Main problem is, in both routine same drawPixel is being called.

No! You have not understood what is happening.

The functions in the GFX generic library are overridden by optimised code in the display device specific subclass library. Look in that support library to understand what is happening and you will be able to see post #2 is correct.

Thank you bodmer, you are right.

I found a different solution to increase speed of filling screen. I pasted content of cls routine into the fillScreen and it runs faster than fillRect.