diff --git a/wled00/FX.h b/wled00/FX.h index 677005f2..4e408254 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -976,6 +976,7 @@ class WS2812FX { // 96 bytes now, timebase; uint32_t __attribute__((pure)) getPixelColor(uint_fast16_t) const; // WLEDMM attribute pure = does not have side-effects + uint32_t __attribute__((pure)) getPixelColorRestored(uint_fast16_t i) const;// WLEDMM gets the original color from the driver (without downscaling by _bri) inline uint32_t getLastShow(void) const { return _lastShow; } inline uint32_t segColor(uint8_t i) const { return _colors_t[i]; } @@ -1068,6 +1069,8 @@ class WS2812FX { // 96 bytes std::vector _segments; friend class Segment; + uint32_t getPixelColorXYRestored(uint16_t x, uint16_t y) const; // WLEDMM gets the original color from the driver (without downscaling by _bri) + private: uint16_t _length; uint8_t _brightness; diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index 9ac62e1d..0803ad1a 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -249,6 +249,17 @@ uint32_t __attribute__((hot)) WS2812FX::getPixelColorXY(uint16_t x, uint16_t y) return busses.getPixelColor(index); } +uint32_t __attribute__((hot)) WS2812FX::getPixelColorXYRestored(uint16_t x, uint16_t y) const { // WLEDMM gets the original color from the driver (without downscaling by _bri) + #ifndef WLED_DISABLE_2D + uint_fast16_t index = (y * Segment::maxWidth + x); //WLEDMM: use fast types + #else + uint16_t index = x; + #endif + if (index < customMappingSize) index = customMappingTable[index]; + if (index >= _length) return 0; + return busses.getPixelColorRestored(index); +} + /////////////////////////////////////////////////////////// // Segment:: routines /////////////////////////////////////////////////////////// @@ -467,7 +478,7 @@ uint32_t IRAM_ATTR_YN Segment::getPixelColorXY(int x, int y) const { x *= groupLength_; // expand to physical pixels y *= groupLength_; // expand to physical pixels if (x >= width() || y >= height()) return 0; - return strip.getPixelColorXY(start + x, startY + y); + return strip.getPixelColorXYRestored(start + x, startY + y); } // Blends the specified color with the existing pixel color. diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 51087562..f2ed3e20 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -1304,7 +1304,7 @@ uint32_t __attribute__((hot)) Segment::getPixelColor(int i) const if (offset < INT16_MAX) i += offset; // WLEDMM if ((i >= stop) && (stop>0)) i -= length(); // WLEDMM avoid negative index (stop = 0 is a possible value) if (i<0) i=0; // WLEDMM just to be 100% sure - return strip.getPixelColor(i); + return strip.getPixelColorRestored(i); } uint8_t Segment::differs(Segment& b) const { @@ -1943,6 +1943,12 @@ uint32_t WS2812FX::getPixelColor(uint_fast16_t i) const // WLEDMM fast int types return busses.getPixelColor(i); } +uint32_t WS2812FX::getPixelColorRestored(uint_fast16_t i) const // WLEDMM gets the original color from the driver (without downscaling by _bri) +{ + if (i < customMappingSize) i = customMappingTable[i]; + if (i >= _length) return 0; + return busses.getPixelColorRestored(i); +} //DISCLAIMER //The following function attemps to calculate the current LED power usage, diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index fa205c44..66a417e8 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -890,6 +890,14 @@ uint32_t BusHub75Matrix::getPixelColor(uint16_t pix) const { return getBitFromArray(_ledsDirty, pix) ? DARKGREY: BLACK; // just a hack - we only know if the pixel is black or not } +uint32_t __attribute__((hot)) BusHub75Matrix::getPixelColorRestored(uint16_t pix) const { + if (!_valid || pix >= _len) return BLACK; + if (_ledBuffer) + return uint32_t(_ledBuffer[pix]) & 0x00FFFFFF; + else + return getBitFromArray(_ledsDirty, pix) ? DARKGREY: BLACK; // just a hack - we only know if the pixel is black or not +} + void BusHub75Matrix::setBrightness(uint8_t b, bool immediate) { _bri = b; // if (_bri > 238) _bri=238; // not strictly needed. Enable this line if you see glitches at highest brightness. @@ -1106,6 +1114,27 @@ uint32_t IRAM_ATTR __attribute__((hot)) BusManager::getPixelColor(uint_fast16_t return 0; } +uint32_t IRAM_ATTR __attribute__((hot)) BusManager::getPixelColorRestored(uint_fast16_t pix) { // WLEDMM uses bus::getPixelColorRestored() + if ((pix >= laststart) && (pix < lastend ) && (lastBus != nullptr)) { + // WLEDMM same bus as last time - no need to search again + return lastBus->getPixelColorRestored(pix - laststart); + } + + for (uint_fast8_t i = 0; i < numBusses; i++) { + Bus* b = busses[i]; + uint_fast16_t bstart = b->getStart(); + if (pix < bstart || pix >= bstart + b->getLength()) continue; + else { + // WLEDMM remember last Bus we took + lastBus = b; + laststart = bstart; + lastend = bstart + b->getLength(); + return b->getPixelColorRestored(pix - bstart); + } + } + return 0; +} + bool BusManager::canAllShow() const { for (uint8_t i = 0; i < numBusses; i++) { if (!busses[i]->canShow()) return false; diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index 80488b6a..677e71de 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -135,6 +135,7 @@ class Bus { virtual void setStatusPixel(uint32_t c) {} virtual void setPixelColor(uint16_t pix, uint32_t c) = 0; virtual uint32_t getPixelColor(uint16_t pix) const { return 0; } + virtual uint32_t getPixelColorRestored(uint16_t pix) const { return restore_Color_Lossy(getPixelColor(pix), _bri); } // override in case your bus has a lossless buffer (HUB75, FastLED, Art-Net) virtual void setBrightness(uint8_t b, bool immediate=false) { _bri = b; } virtual void cleanup() = 0; virtual uint8_t getPins(uint8_t* pinArray) const { return 0; } @@ -183,6 +184,17 @@ class Bus { inline static void setGlobalAWMode(uint8_t m) { if (m < 5) _gAWM = m; else _gAWM = AW_GLOBAL_DISABLED; } inline static uint8_t getGlobalAWMode() { return _gAWM; } + inline uint32_t restore_Color_Lossy(uint32_t c, uint8_t restoreBri) const { // shamelessly grabbed from upstream, who grabbed from NPB, who .. + if (restoreBri < 255) { + uint8_t* chan = (uint8_t*) &c; + for (uint_fast8_t i=0; i<4; i++) { + uint_fast16_t val = chan[i]; + chan[i] = ((val << 8) + restoreBri) / (restoreBri + 1); //adding _bri slightly improves recovery / stops degradation on re-scale + } + } + return c; + } + bool reversed = false; protected: @@ -296,6 +308,7 @@ class BusOnOff : public Bus { void setPixelColor(uint16_t pix, uint32_t c); uint32_t getPixelColor(uint16_t pix) const; + uint32_t getPixelColorRestored(uint16_t pix) const override { return getPixelColor(pix);} // WLEDMM BusOnOff ignores brightness void show(); @@ -326,6 +339,7 @@ class BusNetwork : public Bus { void setPixelColor(uint16_t pix, uint32_t c); uint32_t __attribute__((pure)) getPixelColor(uint16_t pix) const; // WLEDMM attribute added + uint32_t __attribute__((pure)) getPixelColorRestored(uint16_t pix) const override { return getPixelColor(pix);} // WLEDMM BusNetwork ignores brightness void show(); @@ -367,6 +381,7 @@ class BusHub75Matrix : public Bus { void setPixelColor(uint16_t pix, uint32_t c) override; uint32_t getPixelColor(uint16_t pix) const override; + uint32_t getPixelColorRestored(uint16_t pix) const override; // lossless getPixelColor supported void show(void) override; @@ -418,6 +433,7 @@ class BusManager { void setSegmentCCT(int16_t cct, bool allowWBCorrection = false); uint32_t __attribute__((pure)) getPixelColor(uint_fast16_t pix); // WLEDMM attribute added + uint32_t __attribute__((pure)) getPixelColorRestored(uint_fast16_t pix); // WLEDMM bool canAllShow() const; diff --git a/wled00/ws.cpp b/wled00/ws.cpp index 85bad64d..f6c1e862 100644 --- a/wled00/ws.cpp +++ b/wled00/ws.cpp @@ -251,6 +251,7 @@ static bool sendLiveLedsWs(uint32_t wsClient) // WLEDMM added "static" } #endif uint32_t c = restoreColorLossy(strip.getPixelColor(i), stripBrightness); // WLEDMM full bright preview - does _not_ recover ABL reductions + //uint32_t c = strip.getPixelColorRestored(i); // WLEDMM begin: preview with color gamma correction if (gammaCorrectPreview) { uint8_t w = W(c); // not sure why, but it looks better if using "white" without corrections