Decouple segment led buffer from global led buffer
This commit is contained in:
parent
ebd909dfe7
commit
498dd76730
11
wled00/FX.h
11
wled00/FX.h
@ -380,7 +380,6 @@ typedef struct Segment {
|
|||||||
uint16_t aux1; // custom var
|
uint16_t aux1; // custom var
|
||||||
byte* data; // effect data pointer
|
byte* data; // effect data pointer
|
||||||
CRGB* leds; // local leds[] array (may be a pointer to global)
|
CRGB* leds; // local leds[] array (may be a pointer to global)
|
||||||
static CRGB *_globalLeds; // global leds[] array
|
|
||||||
static uint16_t maxWidth, maxHeight; // these define matrix width & height (max. segment dimensions)
|
static uint16_t maxWidth, maxHeight; // these define matrix width & height (max. segment dimensions)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -487,7 +486,7 @@ typedef struct Segment {
|
|||||||
//if (leds) Serial.printf(" [%u]", length()*sizeof(CRGB));
|
//if (leds) Serial.printf(" [%u]", length()*sizeof(CRGB));
|
||||||
//Serial.println();
|
//Serial.println();
|
||||||
//#endif
|
//#endif
|
||||||
if (!Segment::_globalLeds && leds) free(leds);
|
if (leds) free(leds);
|
||||||
if (name) delete[] name;
|
if (name) delete[] name;
|
||||||
if (_t) delete _t;
|
if (_t) delete _t;
|
||||||
deallocateData();
|
deallocateData();
|
||||||
@ -497,7 +496,7 @@ typedef struct Segment {
|
|||||||
Segment& operator= (Segment &&orig) noexcept; // move assignment
|
Segment& operator= (Segment &&orig) noexcept; // move assignment
|
||||||
|
|
||||||
#ifdef WLED_DEBUG
|
#ifdef WLED_DEBUG
|
||||||
size_t getSize() const { return sizeof(Segment) + (data?_dataLen:0) + (name?strlen(name):0) + (_t?sizeof(Transition):0) + (!Segment::_globalLeds && leds?sizeof(CRGB)*length():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
|
#endif
|
||||||
|
|
||||||
inline bool getOption(uint8_t n) const { return ((options >> n) & 0x01); }
|
inline bool getOption(uint8_t n) const { return ((options >> n) & 0x01); }
|
||||||
@ -710,7 +709,7 @@ class WS2812FX { // 96 bytes
|
|||||||
panel.clear();
|
panel.clear();
|
||||||
#endif
|
#endif
|
||||||
customPalettes.clear();
|
customPalettes.clear();
|
||||||
if (useLedsArray && Segment::_globalLeds) free(Segment::_globalLeds);
|
if (_globalLedBuffer) free(_globalLedBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static WS2812FX* getInstance(void) { return instance; }
|
static WS2812FX* getInstance(void) { return instance; }
|
||||||
@ -758,7 +757,7 @@ class WS2812FX { // 96 bytes
|
|||||||
// return true if the strip is being sent pixel updates
|
// return true if the strip is being sent pixel updates
|
||||||
isUpdating(void),
|
isUpdating(void),
|
||||||
deserializeMap(uint8_t n=0),
|
deserializeMap(uint8_t n=0),
|
||||||
useLedsArray = false;
|
useGlobalLedBuffer = false;
|
||||||
|
|
||||||
inline bool isServicing(void) { return _isServicing; }
|
inline bool isServicing(void) { return _isServicing; }
|
||||||
inline bool hasWhiteChannel(void) {return _hasWhiteChannel;}
|
inline bool hasWhiteChannel(void) {return _hasWhiteChannel;}
|
||||||
@ -905,6 +904,8 @@ class WS2812FX { // 96 bytes
|
|||||||
uint8_t _segment_index;
|
uint8_t _segment_index;
|
||||||
uint8_t _mainSegment;
|
uint8_t _mainSegment;
|
||||||
|
|
||||||
|
static uint32_t *_globalLedBuffer; // global leds[] array
|
||||||
|
|
||||||
void
|
void
|
||||||
estimateCurrentAndLimitBri(void);
|
estimateCurrentAndLimitBri(void);
|
||||||
};
|
};
|
||||||
|
@ -74,7 +74,6 @@
|
|||||||
// Segment class implementation
|
// Segment class implementation
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
uint16_t Segment::_usedSegmentData = 0U; // amount of RAM all segments use for their data[]
|
uint16_t Segment::_usedSegmentData = 0U; // amount of RAM all segments use for their data[]
|
||||||
CRGB *Segment::_globalLeds = nullptr;
|
|
||||||
uint16_t Segment::maxWidth = DEFAULT_LED_COUNT;
|
uint16_t Segment::maxWidth = DEFAULT_LED_COUNT;
|
||||||
uint16_t Segment::maxHeight = 1;
|
uint16_t Segment::maxHeight = 1;
|
||||||
|
|
||||||
@ -86,11 +85,11 @@ Segment::Segment(const Segment &orig) {
|
|||||||
data = nullptr;
|
data = nullptr;
|
||||||
_dataLen = 0;
|
_dataLen = 0;
|
||||||
_t = nullptr;
|
_t = nullptr;
|
||||||
if (leds && !Segment::_globalLeds) leds = nullptr;
|
leds = nullptr;
|
||||||
if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); }
|
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.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._t) { _t = new Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); }
|
||||||
if (orig.leds && !Segment::_globalLeds) { leds = (CRGB*)malloc(sizeof(CRGB)*length()); if (leds) memcpy(leds, orig.leds, sizeof(CRGB)*length()); }
|
if (orig.leds) { leds = (CRGB*)malloc(sizeof(CRGB)*length()); if (leds) memcpy(leds, orig.leds, sizeof(CRGB)*length()); }
|
||||||
}
|
}
|
||||||
|
|
||||||
// move constructor
|
// move constructor
|
||||||
@ -111,7 +110,7 @@ Segment& Segment::operator= (const Segment &orig) {
|
|||||||
// clean destination
|
// clean destination
|
||||||
if (name) delete[] name;
|
if (name) delete[] name;
|
||||||
if (_t) delete _t;
|
if (_t) delete _t;
|
||||||
if (leds && !Segment::_globalLeds) free(leds);
|
if (leds) free(leds);
|
||||||
deallocateData();
|
deallocateData();
|
||||||
// copy source
|
// copy source
|
||||||
memcpy((void*)this, (void*)&orig, sizeof(Segment));
|
memcpy((void*)this, (void*)&orig, sizeof(Segment));
|
||||||
@ -120,12 +119,12 @@ Segment& Segment::operator= (const Segment &orig) {
|
|||||||
data = nullptr;
|
data = nullptr;
|
||||||
_dataLen = 0;
|
_dataLen = 0;
|
||||||
_t = nullptr;
|
_t = nullptr;
|
||||||
if (!Segment::_globalLeds) leds = nullptr;
|
leds = nullptr;
|
||||||
// copy source data
|
// copy source data
|
||||||
if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); }
|
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.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._t) { _t = new Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); }
|
||||||
if (orig.leds && !Segment::_globalLeds) { leds = (CRGB*)malloc(sizeof(CRGB)*length()); if (leds) memcpy(leds, orig.leds, sizeof(CRGB)*length()); }
|
if (orig.leds) { leds = (CRGB*)malloc(sizeof(CRGB)*length()); if (leds) memcpy(leds, orig.leds, sizeof(CRGB)*length()); }
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -137,7 +136,7 @@ Segment& Segment::operator= (Segment &&orig) noexcept {
|
|||||||
if (name) delete[] name; // free old name
|
if (name) delete[] name; // free old name
|
||||||
deallocateData(); // free old runtime data
|
deallocateData(); // free old runtime data
|
||||||
if (_t) delete _t;
|
if (_t) delete _t;
|
||||||
if (leds && !Segment::_globalLeds) free(leds);
|
if (leds) free(leds);
|
||||||
memcpy((void*)this, (void*)&orig, sizeof(Segment));
|
memcpy((void*)this, (void*)&orig, sizeof(Segment));
|
||||||
orig.name = nullptr;
|
orig.name = nullptr;
|
||||||
orig.data = nullptr;
|
orig.data = nullptr;
|
||||||
@ -183,7 +182,7 @@ void Segment::deallocateData() {
|
|||||||
*/
|
*/
|
||||||
void Segment::resetIfRequired() {
|
void Segment::resetIfRequired() {
|
||||||
if (reset) {
|
if (reset) {
|
||||||
if (leds && !Segment::_globalLeds) { free(leds); leds = nullptr; }
|
if (leds) { free(leds); leds = nullptr; }
|
||||||
//if (transitional && _t) { transitional = false; delete _t; _t = nullptr; }
|
//if (transitional && _t) { transitional = false; delete _t; _t = nullptr; }
|
||||||
deallocateData();
|
deallocateData();
|
||||||
next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0;
|
next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0;
|
||||||
@ -193,19 +192,16 @@ void Segment::resetIfRequired() {
|
|||||||
|
|
||||||
void Segment::setUpLeds() {
|
void Segment::setUpLeds() {
|
||||||
// deallocation happens in resetIfRequired() as it is called when segment changes or in destructor
|
// deallocation happens in resetIfRequired() as it is called when segment changes or in destructor
|
||||||
if (Segment::_globalLeds)
|
if (WS2812FX::_globalLedBuffer) return; // TODO optional seg buffer for FX without lossy restore due to opacity
|
||||||
#ifndef WLED_DISABLE_2D
|
|
||||||
leds = &Segment::_globalLeds[start + startY*Segment::maxWidth];
|
// no global buffer
|
||||||
#else
|
if (leds == nullptr && length() > 0) { //softhack007 quickfix - avoid malloc(0) which is undefined behaviour (should not happen, but i've seen it)
|
||||||
leds = &Segment::_globalLeds[start];
|
|
||||||
#endif
|
|
||||||
else 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 defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM)
|
||||||
//if (psramFound())
|
//if (psramFound())
|
||||||
// leds = (CRGB*)ps_malloc(sizeof(CRGB)*length()); // softhack007 disabled; putting leds into psram leads to horrible slowdown on WROVER boards
|
// leds = (CRGB*)ps_malloc(sizeof(CRGB)*length()); // softhack007 disabled; putting leds into psram leads to horrible slowdown on WROVER boards
|
||||||
//else
|
//else
|
||||||
//#endif
|
//#endif
|
||||||
leds = (CRGB*)malloc(sizeof(CRGB)*length());
|
leds = (CRGB*)malloc(sizeof(CRGB)*length());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1062,22 +1058,22 @@ void WS2812FX::finalizeInit(void)
|
|||||||
Segment::maxHeight = 1;
|
Segment::maxHeight = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//initialize leds array. TBD: realloc if nr of leds change
|
// initialize leds array
|
||||||
if (Segment::_globalLeds) {
|
if (_globalLedBuffer) {
|
||||||
purgeSegments(true);
|
//purgeSegments(true);
|
||||||
free(Segment::_globalLeds);
|
free(_globalLedBuffer);
|
||||||
Segment::_globalLeds = nullptr;
|
_globalLedBuffer = nullptr;
|
||||||
}
|
}
|
||||||
if (useLedsArray) {
|
if (useGlobalLedBuffer) {
|
||||||
size_t arrSize = sizeof(CRGB) * getLengthTotal();
|
size_t arrSize = sizeof(uint32_t) * getLengthTotal();
|
||||||
// softhack007 disabled; putting leds into psram leads to horrible slowdown on WROVER boards (see setUpLeds())
|
// softhack007 disabled; putting leds into psram leads to horrible slowdown on WROVER boards (see setUpLeds())
|
||||||
//#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM)
|
//#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM)
|
||||||
//if (psramFound())
|
//if (psramFound())
|
||||||
// Segment::_globalLeds = (CRGB*) ps_malloc(arrSize);
|
// Segment::_globalLedBuffer = (CRGB*) ps_malloc(arrSize);
|
||||||
//else
|
//else
|
||||||
//#endif
|
//#endif
|
||||||
Segment::_globalLeds = (CRGB*) malloc(arrSize);
|
_globalLedBuffer = (uint32_t*) malloc(arrSize);
|
||||||
memset(Segment::_globalLeds, 0, arrSize);
|
memset(_globalLedBuffer, 0, arrSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
//segments are created in makeAutoSegments();
|
//segments are created in makeAutoSegments();
|
||||||
@ -1604,7 +1600,7 @@ void WS2812FX::printSize() {
|
|||||||
DEBUG_PRINTF("Data: %d*%d=%uB\n", sizeof(const char *), _modeData.size(), (_modeData.capacity()*sizeof(const char *)));
|
DEBUG_PRINTF("Data: %d*%d=%uB\n", sizeof(const char *), _modeData.size(), (_modeData.capacity()*sizeof(const char *)));
|
||||||
DEBUG_PRINTF("Map: %d*%d=%uB\n", sizeof(uint16_t), (int)customMappingSize, customMappingSize*sizeof(uint16_t));
|
DEBUG_PRINTF("Map: %d*%d=%uB\n", sizeof(uint16_t), (int)customMappingSize, customMappingSize*sizeof(uint16_t));
|
||||||
size = getLengthTotal();
|
size = getLengthTotal();
|
||||||
if (useLedsArray) DEBUG_PRINTF("Buffer: %d*%u=%uB\n", sizeof(CRGB), size, size*sizeof(CRGB));
|
if (useGlobalLedBuffer) DEBUG_PRINTF("Buffer: %d*%u=%uB\n", sizeof(CRGB), size, size*sizeof(CRGB));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1707,6 +1703,7 @@ bool WS2812FX::deserializeMap(uint8_t n) {
|
|||||||
|
|
||||||
|
|
||||||
WS2812FX* WS2812FX::instance = nullptr;
|
WS2812FX* WS2812FX::instance = nullptr;
|
||||||
|
uint32_t* WS2812FX::_globalLedBuffer = nullptr;
|
||||||
|
|
||||||
const char JSON_mode_names[] PROGMEM = R"=====(["FX names moved"])=====";
|
const char JSON_mode_names[] PROGMEM = R"=====(["FX names moved"])=====";
|
||||||
const char JSON_palette_names[] PROGMEM = R"=====([
|
const char JSON_palette_names[] PROGMEM = R"=====([
|
||||||
|
@ -90,7 +90,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
CJSON(strip.cctBlending, hw_led[F("cb")]);
|
CJSON(strip.cctBlending, hw_led[F("cb")]);
|
||||||
Bus::setCCTBlend(strip.cctBlending);
|
Bus::setCCTBlend(strip.cctBlending);
|
||||||
strip.setTargetFps(hw_led["fps"]); //NOP if 0, default 42 FPS
|
strip.setTargetFps(hw_led["fps"]); //NOP if 0, default 42 FPS
|
||||||
CJSON(strip.useLedsArray, hw_led[F("ld")]);
|
CJSON(strip.useGlobalLedBuffer, hw_led[F("ld")]);
|
||||||
|
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
// 2D Matrix Settings
|
// 2D Matrix Settings
|
||||||
@ -706,7 +706,7 @@ void serializeConfig() {
|
|||||||
hw_led[F("cb")] = strip.cctBlending;
|
hw_led[F("cb")] = strip.cctBlending;
|
||||||
hw_led["fps"] = strip.getTargetFps();
|
hw_led["fps"] = strip.getTargetFps();
|
||||||
hw_led[F("rgbwm")] = Bus::getGlobalAWMode(); // global auto white mode override
|
hw_led[F("rgbwm")] = Bus::getGlobalAWMode(); // global auto white mode override
|
||||||
hw_led[F("ld")] = strip.useLedsArray;
|
hw_led[F("ld")] = strip.useGlobalLedBuffer;
|
||||||
|
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
// 2D Matrix Settings
|
// 2D Matrix Settings
|
||||||
|
@ -91,7 +91,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
Bus::setCCTBlend(strip.cctBlending);
|
Bus::setCCTBlend(strip.cctBlending);
|
||||||
Bus::setGlobalAWMode(request->arg(F("AW")).toInt());
|
Bus::setGlobalAWMode(request->arg(F("AW")).toInt());
|
||||||
strip.setTargetFps(request->arg(F("FR")).toInt());
|
strip.setTargetFps(request->arg(F("FR")).toInt());
|
||||||
strip.useLedsArray = request->hasArg(F("LD"));
|
strip.useGlobalLedBuffer = request->hasArg(F("LD"));
|
||||||
|
|
||||||
bool busesChanged = false;
|
bool busesChanged = false;
|
||||||
for (uint8_t s = 0; s < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; s++) {
|
for (uint8_t s = 0; s < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; s++) {
|
||||||
|
@ -404,7 +404,7 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
sappend('v',SET_F("CB"),strip.cctBlending);
|
sappend('v',SET_F("CB"),strip.cctBlending);
|
||||||
sappend('v',SET_F("FR"),strip.getTargetFps());
|
sappend('v',SET_F("FR"),strip.getTargetFps());
|
||||||
sappend('v',SET_F("AW"),Bus::getGlobalAWMode());
|
sappend('v',SET_F("AW"),Bus::getGlobalAWMode());
|
||||||
sappend('c',SET_F("LD"),strip.useLedsArray);
|
sappend('c',SET_F("LD"),strip.useGlobalLedBuffer);
|
||||||
|
|
||||||
for (uint8_t s=0; s < busses.getNumBusses(); s++) {
|
for (uint8_t s=0; s < busses.getNumBusses(); s++) {
|
||||||
Bus* bus = busses.getBus(s);
|
Bus* bus = busses.getBus(s);
|
||||||
|
Loading…
Reference in New Issue
Block a user