Return of local leds[]
This commit is contained in:
		| @@ -379,6 +379,7 @@ typedef struct Segment { | ||||
|     uint16_t aux0;  // custom var | ||||
|     uint16_t aux1;  // custom var | ||||
|     byte* data;     // effect data pointer | ||||
|     uint32_t* leds; // local leds[] array (may be a pointer to global) | ||||
|     static uint16_t maxWidth, maxHeight;  // these define matrix width & height (max. segment dimensions) | ||||
|  | ||||
|   private: | ||||
| @@ -461,6 +462,7 @@ typedef struct Segment { | ||||
|       aux0(0), | ||||
|       aux1(0), | ||||
|       data(nullptr), | ||||
|       leds(nullptr), | ||||
|       _capabilities(0), | ||||
|       _dataLen(0), | ||||
|       _t(nullptr) | ||||
| @@ -485,6 +487,7 @@ typedef struct Segment { | ||||
|       //#endif | ||||
|       if (name) delete[] name; | ||||
|       if (_t) delete _t; | ||||
|       if (leds) free(leds); | ||||
|       deallocateData(); | ||||
|     } | ||||
|  | ||||
| @@ -492,7 +495,7 @@ typedef struct Segment { | ||||
|     Segment& operator= (Segment &&orig) noexcept; // move assignment | ||||
|  | ||||
| #ifdef WLED_DEBUG | ||||
|     size_t getSize() const { return sizeof(Segment) + (data?_dataLen:0) + (name?strlen(name):0) + (_t?sizeof(Transition):0); } | ||||
|     size_t getSize() const { return sizeof(Segment) + (data?_dataLen:0) + (name?strlen(name):0) + (_t?sizeof(Transition):0) + (leds?sizeof(CRGB)*length():0); } | ||||
| #endif | ||||
|  | ||||
|     inline bool     getOption(uint8_t n) const { return ((options >> n) & 0x01); } | ||||
| @@ -533,7 +536,7 @@ typedef struct Segment { | ||||
|       * Safe to call from interrupts and network requests. | ||||
|       */ | ||||
|     inline void markForReset(void) { reset = true; }  // setOption(SEG_OPTION_RESET, true) | ||||
|     inline void setUpLeds(void) {} // legacy filler (should be removed) | ||||
|     void setUpLeds(void); // local double buffer/lossless getPixelColor() | ||||
|  | ||||
|     // transition functions | ||||
|     void     startTransition(uint16_t dur); // transition has to start before actual segment values change | ||||
|   | ||||
| @@ -199,6 +199,8 @@ void /*IRAM_ATTR*/ Segment::setPixelColorXY(int x, int y, uint32_t col) | ||||
|   if (Segment::maxHeight==1) return; // not a matrix set-up | ||||
|   if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return;  // if pixel would fall out of virtual segment just exit | ||||
|  | ||||
|   if (leds) leds[XY(x,y)] = col; | ||||
|  | ||||
|   uint8_t _bri_t = currentBri(on ? opacity : 0); | ||||
|   if (_bri_t < 255) { | ||||
|     byte r = scale8(R(col), _bri_t); | ||||
| @@ -284,6 +286,7 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa) | ||||
|  | ||||
| // returns RGBW values of pixel | ||||
| uint32_t Segment::getPixelColorXY(uint16_t x, uint16_t y) { | ||||
|   if (leds) return leds[XY(x,y)]; | ||||
|   if (reverse  ) x = virtualWidth()  - x - 1; | ||||
|   if (reverse_y) y = virtualHeight() - y - 1; | ||||
|   if (transpose) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed | ||||
|   | ||||
| @@ -85,9 +85,11 @@ Segment::Segment(const Segment &orig) { | ||||
|   data = nullptr; | ||||
|   _dataLen = 0; | ||||
|   _t = nullptr; | ||||
|   leds = nullptr; | ||||
|   if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); } | ||||
|   if (orig.data) { if (allocateData(orig._dataLen)) memcpy(data, orig.data, orig._dataLen); } | ||||
|   if (orig._t)   { _t = new Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); } | ||||
|   if (orig.leds) { leds = (uint32_t*)malloc(sizeof(uint32_t)*length()); if (leds) memcpy(leds, orig.leds, sizeof(uint32_t)*length()); } | ||||
| } | ||||
|  | ||||
| // move constructor | ||||
| @@ -98,6 +100,7 @@ Segment::Segment(Segment &&orig) noexcept { | ||||
|   orig.data = nullptr; | ||||
|   orig._dataLen = 0; | ||||
|   orig._t   = nullptr; | ||||
|   orig.leds = nullptr; | ||||
| } | ||||
|  | ||||
| // copy assignment | ||||
| @@ -107,6 +110,7 @@ Segment& Segment::operator= (const Segment &orig) { | ||||
|     // clean destination | ||||
|     if (name) delete[] name; | ||||
|     if (_t)   delete _t; | ||||
|     if (leds) free(leds); | ||||
|     deallocateData(); | ||||
|     // copy source | ||||
|     memcpy((void*)this, (void*)&orig, sizeof(Segment)); | ||||
| @@ -115,10 +119,12 @@ Segment& Segment::operator= (const Segment &orig) { | ||||
|     data = nullptr; | ||||
|     _dataLen = 0; | ||||
|     _t = nullptr; | ||||
|     leds = nullptr; | ||||
|     // copy source data | ||||
|     if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); } | ||||
|     if (orig.data) { if (allocateData(orig._dataLen)) memcpy(data, orig.data, orig._dataLen); } | ||||
|     if (orig._t)   { _t = new Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); } | ||||
|     if (orig.leds) { leds = (uint32_t*)malloc(sizeof(uint32_t)*length()); if (leds) memcpy(leds, orig.leds, sizeof(uint32_t)*length()); } | ||||
|   } | ||||
|   return *this; | ||||
| } | ||||
| @@ -128,6 +134,7 @@ Segment& Segment::operator= (Segment &&orig) noexcept { | ||||
|   //DEBUG_PRINTLN(F("-- Moving segment --")); | ||||
|   if (this != &orig) { | ||||
|     if (name) delete[] name; // free old name | ||||
|     if (leds) free(leds); | ||||
|     deallocateData(); // free old runtime data | ||||
|     if (_t) delete _t; | ||||
|     memcpy((void*)this, (void*)&orig, sizeof(Segment)); | ||||
| @@ -135,6 +142,7 @@ Segment& Segment::operator= (Segment &&orig) noexcept { | ||||
|     orig.data = nullptr; | ||||
|     orig._dataLen = 0; | ||||
|     orig._t   = nullptr; | ||||
|     orig.leds = nullptr; | ||||
|   } | ||||
|   return *this; | ||||
| } | ||||
| @@ -174,12 +182,28 @@ void Segment::deallocateData() { | ||||
|   */ | ||||
| void Segment::resetIfRequired() { | ||||
|   if (reset) { | ||||
|     if (leds) { free(leds); leds = nullptr; } | ||||
|     deallocateData(); | ||||
|     next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0; | ||||
|     reset = false; // setOption(SEG_OPTION_RESET, false); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void Segment::setUpLeds() { | ||||
|   // deallocation happens in resetIfRequired() as it is called when segment changes or in destructor | ||||
|   if (useGlobalLedBuffer) return; // TODO optional seg buffer for FX without lossy restore due to opacity | ||||
|  | ||||
|   // no global buffer | ||||
|   if (leds == nullptr && length() > 0) { //softhack007 quickfix - avoid malloc(0) which is undefined behaviour (should not happen, but i've seen it) | ||||
|     //#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM) | ||||
|     //if (psramFound()) | ||||
|     //  leds = (CRGB*)ps_malloc(sizeof(CRGB)*length());   // softhack007 disabled; putting leds into psram leads to horrible slowdown on WROVER boards | ||||
|     //else | ||||
|     //#endif | ||||
|     leds = (uint32_t *)calloc(length(), sizeof(uint32_t)); | ||||
|   } | ||||
| } | ||||
|  | ||||
| CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) { | ||||
|   static unsigned long _lastPaletteChange = 0; // perhaps it should be per segment | ||||
|   static CRGBPalette16 randomPalette = CRGBPalette16(DEFAULT_COLOR); | ||||
| @@ -592,6 +616,8 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col) | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   if (leds) leds[i] = col; | ||||
|  | ||||
|   uint16_t len = length(); | ||||
|   uint8_t _bri_t = currentBri(on ? opacity : 0); | ||||
|   if (_bri_t < 255) { | ||||
| @@ -691,6 +717,8 @@ uint32_t Segment::getPixelColor(int i) | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   if (leds) return leds[i]; | ||||
|  | ||||
|   if (reverse) i = virtualLength() - i - 1; | ||||
|   i *= groupLength(); | ||||
|   i += start; | ||||
|   | ||||
| @@ -147,18 +147,11 @@ void BusDigital::show() { | ||||
|       else pix += _skip; | ||||
|       PolyBus::setPixelColor(_busPtr, _iType, pix, c, co); | ||||
|     } | ||||
|     PolyBus::show(_busPtr, _iType); | ||||
|   } else { | ||||
|     PolyBus::applyPostAdjustments(_busPtr, _iType); | ||||
|     PolyBus::show(_busPtr, _iType); | ||||
|     // now restore (as close as possible) previous colors | ||||
|     // warning: this may not be the best idea as the buffer may still be in use | ||||
|     for (size_t i=0; i<_len; i++) { | ||||
|       uint8_t co = _colorOrderMap.getPixelColorOrder(i+_start, _colorOrder); | ||||
|       setPixelColor(i, restoreColorLossy(PolyBus::getPixelColor(_busPtr, _iType, i, co), _bri)); | ||||
|     } | ||||
|   } | ||||
|   PolyBus::setBrightness(_busPtr, _iType, 255); // restore full brightness | ||||
|   PolyBus::show(_busPtr, _iType); | ||||
|   PolyBus::setBrightness(_busPtr, _iType, 255); // restore full brightness at bus level (setting unscaled pixel color) | ||||
| } | ||||
|  | ||||
| bool BusDigital::canShow() { | ||||
| @@ -243,7 +236,7 @@ uint32_t BusDigital::getPixelColor(uint16_t pix) { | ||||
|       } | ||||
|       return c; | ||||
|     } | ||||
|     return PolyBus::getPixelColor(_busPtr, _iType, pix, co); | ||||
|     return restoreColorLossy(PolyBus::getPixelColor(_busPtr, _iType, pix, co), _bri); | ||||
|   } | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Blaz Kristan
					Blaz Kristan