sumotoy / RA8875

A library for RAiO RA8875 display driver for Teensy3.x or LC/Arduino's/Energia/Spark
GNU General Public License v3.0
79 stars 55 forks source link

Finally a new function to draw BMP and XBMP's 30fps @ 120x120px 16-bit colors #157

Open kawasakizx10rr opened 7 months ago

kawasakizx10rr commented 7 months ago

I have used the RA8875 lib for years and I have always been annoyed at the time it takes to draw a bmp / xbmp, using drawPixel to draw a bmp is very slow taking over 100ms for draw a small 60px bmp, and pages taking ages to draw when using a lot of bmps.

WELLLLLLLL, after scanning the code for a while and understanding how it works, I have wrote two functions which can draw a 60x60px bmp in 8ms in full 16-bit color, and a 120x120 bmp in 31ms THATS OVER 30 FPS!!!!

I an using a ESP32 but i have tested it using a mega2560 too, to which i am running the SPI at 20Mhz on the ESP32, which is only a 10% increase in fps, compared to 12Mhz, but still. I have also written a new font engine and font creation tool which is way eaiser to use but lacks the font chip support so ill leave that out, but anyway here is the functions to add to your lib.

You can thank me later 🥇 🥇 🥇 regards, Edwin J Martin.


void RA8875::drawBMP(int16_t a_x, int16_t a_y, const uint16_t *a_data, uint16_t a_width, uint16_t a_height, uint16_t a_scale) {
    int xPos = 0, linesDrawn = 0, startI = 0;
    setActiveWindow(a_x, a_x + (a_width*a_scale)-1, a_y, a_y + (a_height*a_scale)-1);
    setXY(a_x, a_y);
    writeCommand(RA8875_MRWC);
    _startSend();
    SPI.transfer(RA8875_DATAWRITE);
    for (int i = 0; i < a_width * a_height; i++) {
        if (a_scale != 1 && xPos == 0 && linesDrawn == 0) {
            //printf("i:%d\n", i);
            startI = i;
        }
        for (int n = 0; n < a_scale; n++)
            SPI.transfer16(a_data[i]);
        if (a_scale != 1) {
             // draw line again
             if (xPos == a_width - 1 && linesDrawn != a_scale - 1) {
                linesDrawn++;
                i = startI;
                xPos = 0;
            }
            else if (xPos == a_width - 1) {
                linesDrawn = 0;
                xPos = 0;
            }
            else
                xPos++;
        }   
    }
    _endSend();
    setActiveWindow();
}

/**************************************************************************/

void RA8875::drawXBMP(int16_t a_x, int16_t a_y, const uint8_t* a_data, const uint16_t a_arraySize, const uint16_t a_width, const uint16_t a_height, const uint16_t a_foreground, const uint16_t a_background, const uint16_t a_scale)
{
    int xPos = 0, linesDrawn = 0, startI = 0, startB = 0;
    setActiveWindow(a_x, a_x + (a_width*a_scale)-1, a_y, a_y + (a_height*a_scale)-1);
    setXY(a_x, a_y);
    writeCommand(RA8875_MRWC);
    _startSend();
    SPI.transfer(RA8875_DATAWRITE);
    for (int i = 0; i < a_arraySize; i++) {
        for (int b = 7 ; b >= 0; b--) {
             if (a_scale != 1 && xPos == 0 && linesDrawn == 0) {
                //printf("i:%d, b:%d\n", i, b);
                startI = i; 
                startB = b;
             }
             uint8_t val = bitRead(a_data[i], b);
             for (int n = 0; n < a_scale; n++) {
                SPI.transfer16(val ? a_foreground : a_background);
             }
             if (a_scale != 1) {        
                if (xPos == a_width - 1 && linesDrawn != a_scale - 1) { // draw line again
                   linesDrawn++;
                   i = startI;
                   b = startB + 1;
                   xPos = 0;
                }
                else if (xPos == a_width - 1) {
                   linesDrawn = 0;
                   xPos = 0;
        }
        else
           xPos++;
         }
    }
   }
   _endSend();
   setActiveWindow();
}
kawasakizx10rr commented 7 months ago

A copy of my fork can be found here: [https://github.com/kawasakizx10rr/HydroControllerV5.0/tree/main/Libraries/RA8875-0.9](my fork)