The two main bottlenecks to draw a screen full of tiles seems to be the drawPixel and drawBitmapFunctions.
A few cpu load measurement I did using the getCpuLoad() function at the default 20FP (50ms/frame, so 1% is 0.5ms) :
- blank screen : 10% (which represents the time to send the buffer to the screen. Nokia 5110 maximum SPI bus frequency is the limitation here)
- gb.display.fillScreen() : 10% (it uses memset so it's almost instant)
- fillRect() to fill the screen : 76%
- gb.display.drawPixel() in a for loop to fill the screen : 50%
- Code: Select all
for(byte x = 0; x < LCDWIDTH; x++){
for(byte y = 0; y < LCDHEIGHT; y++){
gb.display.drawPixel(x,y);
}
}
Right now, fillRect() call drawFastVline (which is not optimized at all) plenty of times to actually fill the rectangle, that's why it's slower than the for loop calling drawPixel.
I got a small improvement (76% to 69%) with the following change the function drawFastVline:
- Code: Select all
void Display::drawFastVLine(int8_t x, int8_t y, int8_t h) {
// stupidest/slowest version :
//drawLine(x, y, x, y + h - 1);
//new version :
for(int8_t i=0; i<h; i++){
drawPixel(x,y+i);
}
}
(I will commit that change to the beta branch soon)
- I tried to place the drawFastVline function inline but it didn't change anything in this case
- drawPixel have be previously made inline for performance improvement, I tried to make it not inline and it doesn't make any difference this time. Maybe because of the optimization done by avr-gcc
What is surprising is that if I change the fillRect function to a for loop with drawPixel instead of a for loop of drawFastVline, it is slower ! (74%). Doing a for loop of drawPixel() directly in the .ino only takes 50%. I don't understand where the difference comes from.
- Replacing (y/8) by (y>>3) in the drawPixel doesn't affect performance, it seems that the optimizer does its job here.
- removing the INVERT color makes a 5% improvement when filling the whole screen. Not a big difference, and this color is pretty handy.