diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index eaa46caa..bfeb6616 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -610,6 +610,20 @@ uint8_t BusHub75Matrix::activeType = 0; uint8_t BusHub75Matrix::instanceCount = 0; uint8_t BusHub75Matrix::last_bri = 0; +#ifndef NO_CIE1931 + +// WLEDMM speedup: create a version of "unGamma8" that can be inlined by the compiler +extern uint8_t gammaTinv[256]; // defined in colors.cpp +static uint8_t const* myGammaTable = gammaTinv; // local alias for gammaTinv + +static inline uint8_t unGamma8_bus(uint8_t value) { + return myGammaTable[value]; +} +static inline uint32_t unGamma24_bus(uint32_t c) { + return RGBW32(myGammaTable[R(c)], myGammaTable[G(c)], myGammaTable[B(c)], W(c)); +} + +#endif // -------------------------- // Bitdepth reduction based on panel size @@ -1080,6 +1094,13 @@ BusHub75Matrix::BusHub75Matrix(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWh activeFourScanPanel = fourScanPanel; if (newDisplay) memcpy(&activeMXconfig, &mxconfig, sizeof(mxconfig)); } + +#ifndef NO_CIE1931 + // force initial calculation of gamma correction tables + if ((gammaCorrectVal < 0.999f) || (gammaCorrectVal > 3.0f)) calcGammaTable(1.0f); + else calcGammaTable(gammaCorrectVal); +#endif + instanceCount++; USER_PRINT(F("heap usage: ")); USER_PRINTLN(int(lastHeap - ESP.getFreeHeap())); } @@ -1142,13 +1163,12 @@ void __attribute__((hot)) IRAM_ATTR BusHub75Matrix::show(void) { for (int y=0; y 3.0f)) return value; if (gammaTinv[255] == 0) calcInvGammaTable(gammaCorrectVal); + //if ((gammaCorrectVal < 0.999f) || (gammaCorrectVal > 3.0f)) return value; // WLEDMM yes, looks stupid return gammaTinv[value]; } @@ -482,13 +481,13 @@ void calcGammaTable(float gamma) } // used for individual channel or brightness gamma correction -IRAM_ATTR_YN __attribute__((hot)) uint8_t gamma8(uint8_t b) // WLEDMM added IRAM_ATTR_YN +IRAM_ATTR_YN __attribute__((hot)) uint8_t gamma8_slow(uint8_t b) // WLEDMM added IRAM_ATTR_YN { return gammaT[b]; } // used for color gamma correction -uint32_t __attribute__((hot)) gamma32(uint32_t color) +IRAM_ATTR_YN uint32_t __attribute__((hot)) gamma32(uint32_t color) { if (!gammaCorrectCol) return color; uint8_t w = W(color); diff --git a/wled00/const.h b/wled00/const.h index bf0e62ad..388eaad6 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -594,8 +594,10 @@ // error only in MM, not in upstream... tbd: find out why #ifdef ARDUINO_ARCH_ESP32 #define IRAM_ATTR_YN IRAM_ATTR + #define DRAM_ATTR_YN DRAM_ATTR #else #define IRAM_ATTR_YN + #define DRAM_ATTR_YN #endif #define WLED_O2_ATTR __attribute__((optimize("O2"))) diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index c5e95604..37b4e10a 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -78,11 +78,17 @@ uint16_t __attribute__((const)) approximateKelvinFromRGB(uint32_t rgb); void setRandomColor(byte* rgb); uint8_t gamma8_cal(uint8_t b, float gamma); void calcGammaTable(float gamma); -uint8_t __attribute__((pure)) gamma8(uint8_t b); // WLEDMM: added attribute pure +uint8_t __attribute__((pure)) gamma8_slow(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) +// WLEDMM: speedup - inline function for gamma correction +extern uint8_t gammaTinv[256]; // colors.cpp +extern uint8_t gammaT[256]; // colors.cpp +inline uint8_t gamma8(uint8_t value) { return gammaT[value];} // WLEDMM inlined for speed +inline uint8_t fast_unGamma8(uint8_t value) { return gammaTinv[value];} + //dmx_output.cpp void initDMXOutput(); void handleDMXOutput(); diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 1842d6ad..d778251b 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -886,6 +886,11 @@ void WLED::setup() #endif USER_PRINT(F("Free heap ")); USER_PRINTLN(ESP.getFreeHeap());USER_PRINTLN(); + + // WLEDMM force initial calculation of gamma correction LUT + if ((gammaCorrectVal < 0.999f) || (gammaCorrectVal > 3.0f)) calcGammaTable(1.0f); // no gamma => create linear LUT + else calcGammaTable(gammaCorrectVal); + USER_PRINTLN(F("WLED initialization done.\n")); delay(50); // repeat Ada prompt diff --git a/wled00/ws.cpp b/wled00/ws.cpp index 9b7d24e7..e061b6a6 100644 --- a/wled00/ws.cpp +++ b/wled00/ws.cpp @@ -253,6 +253,7 @@ static bool sendLiveLedsWs(uint32_t wsClient) // WLEDMM added "static" } #endif + (void) unGamma8(127); // WLEDMM dummy call, just to make sure that gammaTinv is initialized, so we can use fast_unGamma8 uint8_t stripBrightness = strip.getBrightness(); for (size_t i = 0; pos < bufSize -2; i += n) { @@ -268,9 +269,9 @@ static bool sendLiveLedsWs(uint32_t wsClient) // WLEDMM added "static" if (gammaCorrectPreview) { uint8_t w = W(c); // not sure why, but it looks better if using "white" without corrections if (w>0) c = color_add(c, RGBW32(w, w, w, 0), false); // add white channel to RGB channels - color_add() will prevent over-saturation - buffer[pos++] = unGamma8(R(c)); //R - buffer[pos++] = unGamma8(G(c)); //G - buffer[pos++] = unGamma8(B(c)); //B + buffer[pos++] = fast_unGamma8(R(c)); //R + buffer[pos++] = fast_unGamma8(G(c)); //G + buffer[pos++] = fast_unGamma8(B(c)); //B } else { // WLEDMM end uint8_t w = W(c); // WLEDMM small optimization