MCUFRIEND_kbv Library for Uno 2.4, 2.8, 3.5, 3.6, 3.95 inch mcufriend Shields

My apologies. setAddrWindow(x1, y1, x2, y2) uses limit values not height and width. e.g. (0, 0, 479, 319)

Here is an example program. Note that my rectangle drawing will be about 10x faster than your code.

/* Skeleton from readpixel_kbv */

#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;

unsigned short minutes[12800];
unsigned short seconds[12800];

uint16_t g_identifier;

void setup(void)
{
    tft.reset();
    g_identifier = tft.readID();
    tft.begin(g_identifier);
    tft.setRotation(1);
    tft.fillScreen(0x0000);
    // draw really irritating rectangles
    int h = 320, w = 480;
    for (int x = 0; h > 0; x++, h -= 2, w -= 2) {
        uint16_t colour = random(0xFFFF);
        tft.drawRect(x, x, w, h, colour);
    }
    // save the areas where digits get printed.
    tft.readGRAM(176, 130, minutes, 128, 100);//copy rectangle behind "minutes"
    tft.readGRAM(340, 130, seconds, 128, 100);//copy rectangle behind "seconds"
    tft.setTextSize(10);        //digit is 80 high, 60 wide
    tft.setTextColor(0xFFFF);   //WHITE transparent
}

void print_xy_2dig(int x, int y, int val)
{
    tft.setCursor(x, y);
    val %= 100;
    if (val < 10) tft.print("0");
    tft.print(val);
}

void loop()
{
    delay(500);
    //redraw the saved rectasngles.  note that this is x1, y1, x2, y2
    tft.setAddrWindow(176, 130, 176 + 128 - 1, 130 + 100 - 1);
    tft.pushColors(minutes, 12800, 1);//copy minutes rectangle back?
    tft.setAddrWindow(340, 130, 340 + 128 - 1, 130 + 100 - 1);
    tft.pushColors(seconds, 12800, 1);//copy seconds rectangle back?
    //draw the time
    uint32_t elapsed = millis() / 1000;
    print_xy_2dig(176, 130, elapsed / 60);
    print_xy_2dig(340, 130, elapsed % 60);
    delay(500);
}

I am sure that you could invent some less irritating random graphics. mind you, it did illustrate your point.

In practice, you only redraw the background when necessary. i.e. only when a digit changes.

David.