From 3dc190df6c98e7aa3586ef00b4937f4d9ee6ef45 Mon Sep 17 00:00:00 2001 From: Bodmer Date: Fri, 13 Oct 2023 18:47:32 +0100 Subject: [PATCH] Add fastBlend to improve RP2040 performance --- TFT_eSPI.cpp | 18 +++++++++--------- TFT_eSPI.h | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/TFT_eSPI.cpp b/TFT_eSPI.cpp index 47b1089..23c0ebd 100644 --- a/TFT_eSPI.cpp +++ b/TFT_eSPI.cpp @@ -3954,7 +3954,7 @@ constexpr float deg2rad = 3.14159265359/180.0; uint16_t TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color, uint8_t alpha, uint32_t bg_color) { if (bg_color == 0x00FFFFFF) bg_color = readPixel(x, y); - color = alphaBlend(alpha, color, bg_color); + color = fastBlend(alpha, color, bg_color); drawPixel(x, y, color); return color; } @@ -4195,7 +4195,7 @@ void TFT_eSPI::drawArc(int32_t x, int32_t y, int32_t r, int32_t ir, if (alpha < 16) continue; // Skip low alpha pixels // If background is read it must be done in each quadrant - uint16_t pcol = alphaBlend(alpha, fg_color, bg_color); + uint16_t pcol = fastBlend(alpha, fg_color, bg_color); // Check if an AA pixels need to be drawn slope = ((r - cy)<<16)/(r - cx); if (slope <= startSlope[0] && slope >= endSlope[0]) // BL @@ -4366,7 +4366,7 @@ void TFT_eSPI::drawSmoothRoundRect(int32_t x, int32_t y, int32_t r, int32_t ir, if (alpha < 16) continue; // Skip low alpha pixels // If background is read it must be done in each quadrant - TODO - uint16_t pcol = alphaBlend(alpha, fg_color, bg_color); + uint16_t pcol = fastBlend(alpha, fg_color, bg_color); if (quadrants & 0x8) drawPixel(x + cx - r, y - cy + r + h, pcol); // BL if (quadrants & 0x1) drawPixel(x + cx - r, y + cy - r, pcol); // TL if (quadrants & 0x2) drawPixel(x - cx + r + w, y + cy - r, pcol); // TR @@ -4522,12 +4522,12 @@ void TFT_eSPI::drawWedgeLine(float ax, float ay, float bx, float by, float ar, f bg = readPixel(xp, yp); swin = true; } #ifdef GC9A01_DRIVER - uint16_t pcol = alphaBlend((uint8_t)(alpha * PixelAlphaGain), fg_color, bg); + uint16_t pcol = fastBlend((uint8_t)(alpha * PixelAlphaGain), fg_color, bg); drawPixel(xp, yp, pcol); swin = swin; #else if (swin) { setWindow(xp, yp, x1, yp); swin = false; } - pushColor(alphaBlend((uint8_t)(alpha * PixelAlphaGain), fg_color, bg)); + pushColor(fastBlend((uint8_t)(alpha * PixelAlphaGain), fg_color, bg)); #endif } } @@ -4560,12 +4560,12 @@ void TFT_eSPI::drawWedgeLine(float ax, float ay, float bx, float by, float ar, f bg = readPixel(xp, yp); swin = true; } #ifdef GC9A01_DRIVER - uint16_t pcol = alphaBlend((uint8_t)(alpha * PixelAlphaGain), fg_color, bg); + uint16_t pcol = fastBlend((uint8_t)(alpha * PixelAlphaGain), fg_color, bg); drawPixel(xp, yp, pcol); swin = swin; #else if (swin) { setWindow(xp, yp, x1, yp); swin = false; } - pushColor(alphaBlend((uint8_t)(alpha * PixelAlphaGain), fg_color, bg)); + pushColor(fastBlend((uint8_t)(alpha * PixelAlphaGain), fg_color, bg)); #endif } } @@ -4719,7 +4719,7 @@ void TFT_eSPI::fillRectVGradient(int16_t x, int16_t y, int16_t w, int16_t h, uin while (h--) { drawFastHLine(x, y++, w, color); alpha += delta; - color = alphaBlend((uint8_t)alpha, color1, color2); + color = fastBlend((uint8_t)alpha, color1, color2); } end_nin_write(); @@ -4757,7 +4757,7 @@ void TFT_eSPI::fillRectHGradient(int16_t x, int16_t y, int16_t w, int16_t h, uin while (w--) { drawFastVLine(x++, y, h, color); alpha += delta; - color = alphaBlend((uint8_t)alpha, color1, color2); + color = fastBlend((uint8_t)alpha, color1, color2); } end_nin_write(); diff --git a/TFT_eSPI.h b/TFT_eSPI.h index 6f612b9..1b01b25 100644 --- a/TFT_eSPI.h +++ b/TFT_eSPI.h @@ -985,6 +985,20 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac template static inline void transpose(T& a, T& b) { T t = a; a = b; b = t; } +// Fast alphaBlend +template static inline uint16_t +fastBlend(A alpha, F fgc, B bgc) +{ + // Split out and blend 5 bit red and blue channels + uint32_t rxb = bgc & 0xF81F; + rxb += ((fgc & 0xF81F) - rxb) * (alpha >> 2) >> 6; + // Split out and blend 6 bit green channel + uint32_t xgx = bgc & 0x07E0; + xgx += ((fgc & 0x07E0) - xgx) * alpha >> 8; + // Recombine channels + return (rxb & 0xF81F) | (xgx & 0x07E0); +} + /*************************************************************************************** ** Section 10: Additional extension classes ***************************************************************************************/