From 078bd7077504f8fca97dfb5c1cac5613a50f6fa0 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Mon, 5 Aug 2024 17:28:03 +0200 Subject: [PATCH] HUB75 speedups and minor improvements * HUB75: allow to use native driver gamma correction - requires to undo WLED gamma * added unGamma24() function * HUB75: optimized setPixelColor() * some experimental HUB75 stuff --- wled00/bus_manager.cpp | 33 ++++++++++++++++++++++++--------- wled00/bus_manager.h | 3 ++- wled00/colors.cpp | 6 ++++++ wled00/fcn_declare.h | 1 + wled00/wled.h | 2 +- 5 files changed, 34 insertions(+), 11 deletions(-) diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index a24fdf28..604a92c5 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -501,6 +501,7 @@ void BusNetwork::cleanup() { BusHub75Matrix::BusHub75Matrix(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) { + _valid = false; mxconfig.double_buff = false; // default to off, known to cause issue with some effects but needs more memory @@ -594,6 +595,13 @@ BusHub75Matrix::BusHub75Matrix(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWh mxconfig.gpio.d = 21; mxconfig.gpio.e = 12; + // mxconfig.double_buff = true; // <------------- Turn on double buffer + // mxconfig.driver = HUB75_I2S_CFG::ICN2038S; // experimental - use specific shift register driver + //mxconfig.latch_blanking = 3; + // mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_10M; // experimental - 5MHZ should be enugh, but colours looks slightly better at 10MHz + //mxconfig.min_refresh_rate = 90; + //mxconfig.min_refresh_rate = 120; + #else USER_PRINTLN("MatrixPanel_I2S_DMA - Default pins"); /* @@ -691,18 +699,25 @@ BusHub75Matrix::BusHub75Matrix(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWh } void BusHub75Matrix::setPixelColor(uint16_t pix, uint32_t c) { - r = R(c); - g = G(c); - b = B(c); + if (!_valid || pix >= _len) return; +#ifndef NO_CIE1931 + c = unGamma24(c); // to use the driver linear brightness feature, we first need to undo WLED gamma correction +#endif + uint8_t r = R(c); + uint8_t g = G(c); + uint8_t b = B(c); + if(fourScanPanel != nullptr) { - x = pix % fourScanPanel->width(); - y = floor(pix / fourScanPanel->width()); - fourScanPanel->drawPixelRGB888(x, y, r, g, b); + int pxwidth = fourScanPanel->width(); + int x = pix % pxwidth; + int y = pix / pxwidth; + fourScanPanel->drawPixelRGB888(int16_t(x), int16_t(y), r, g, b); } else { - x = pix % display->width(); - y = floor(pix / display->width()); - display->drawPixelRGB888(x, y, r, g, b); + int pxwidth = display->width(); + int x = pix % pxwidth; + int y = pix / pxwidth; + display->drawPixelRGB888(int16_t(x), int16_t(y), r, g, b); } } diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index 0bfd3e04..40fc0061 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -4,6 +4,7 @@ #ifdef WLED_ENABLE_HUB75MATRIX #include #include +//extern volatile bool previousBufferFree; // experimental #endif /* * Class for addressing various light types @@ -348,6 +349,7 @@ class BusHub75Matrix : public Bus { void show() { if(mxconfig.double_buff) { display->flipDMABuffer(); // Show the back buffer, set currently output buffer to the back (i.e. no longer being sent to LED panels) + // while(!previousBufferFree) delay(1); // experimental - Wait before we allow any writing to the buffer. Stop flicker. display->clearScreen(); // Now clear the back-buffer } } @@ -377,7 +379,6 @@ class BusHub75Matrix : public Bus { MatrixPanel_I2S_DMA *display = nullptr; VirtualMatrixPanel *fourScanPanel = nullptr; HUB75_I2S_CFG mxconfig; - uint8_t r, g, b, x, y; }; #endif diff --git a/wled00/colors.cpp b/wled00/colors.cpp index 465fefbb..f7751861 100644 --- a/wled00/colors.cpp +++ b/wled00/colors.cpp @@ -413,6 +413,12 @@ uint8_t unGamma8(uint8_t value) { if (gammaTinv[255] == 0) calcInvGammaTable(gammaCorrectVal); return gammaTinv[value]; } + +uint32_t unGamma24(uint32_t c) { + if ((gammaCorrectVal < 0.999f) || (gammaCorrectVal > 3.0f)) return c; + if (gammaTinv[255] == 0) calcInvGammaTable(gammaCorrectVal); + return RGBW32(gammaTinv[R(c)], gammaTinv[G(c)], gammaTinv[B(c)], W(c)); +} // wleDMM end uint8_t gamma8_cal(uint8_t b, float gamma) diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index aa0645d0..a0713d0f 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -69,6 +69,7 @@ void calcGammaTable(float gamma); uint8_t __attribute__((pure)) gamma8(uint8_t b); // WLEDMM: added attribute pure uint32_t __attribute__((pure)) gamma32(uint32_t); // WLEDMM: added attribute pure uint8_t unGamma8(uint8_t value); // WLEDMM revert gamma correction +uint32_t unGamma24(uint32_t c); // WLEDMM for 24bit color (white left as-is) //dmx_output.cpp void initDMXOutput(); diff --git a/wled00/wled.h b/wled00/wled.h index 5d881cf0..be21de04 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2407171 +#define VERSION 2408050 // WLEDMM - you can check for this define in usermods, to only enabled WLEDMM specific code in the "right" fork. Its not defined in AC WLED. #define _MoonModules_WLED_