From f8a673ce810f83030e9297d8d5bd022d72919d80 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Tue, 7 Jan 2025 15:09:29 +0100 Subject: [PATCH] code robustness improvements plus minor speedup * make XY() and _setPixelColorXY_raw() const (minor speedup) * segment is a struct not a class: friend class Segment --> friend struct Segment * fix missing braces around two macros * use non-throwing "new" where possible * improve robustness of transition code --- wled00/FX.h | 10 +++++----- wled00/FX_2Dfcn.cpp | 4 ++-- wled00/FX_fcn.cpp | 24 ++++++++++++------------ wled00/json.cpp | 2 +- wled00/playlist.cpp | 2 +- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/wled00/FX.h b/wled00/FX.h index e0924695..b942ac8e 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -610,7 +610,7 @@ typedef struct Segment { uint16_t progress(void) const; //transition progression between 0-65535 // WLEDMM method inlined for speed (its called at each setPixelColor) - inline uint8_t currentBri(uint8_t briNew, bool useCct = false) { + [[gnu::hot]] inline uint8_t currentBri(uint8_t briNew, bool useCct = false) { uint32_t prog = (transitional && _t) ? progress() : 0xFFFFU; if (transitional && _t && prog < 0xFFFFU) { if (useCct) return ((briNew * prog) + _t->_cctT * (0xFFFFU - prog)) >> 16; @@ -703,7 +703,7 @@ typedef struct Segment { void deletejMap(); //WLEDMM jMap #ifndef WLED_DISABLE_2D - inline uint16_t XY(uint_fast16_t x, uint_fast16_t y) const { // support function to get relative index within segment (for leds[]) // WLEDMM inline for speed + [[gnu::hot]] inline uint16_t XY(uint_fast16_t x, uint_fast16_t y) const { // support function to get relative index within segment (for leds[]) // WLEDMM inline for speed uint_fast16_t width = max(uint16_t(1), virtualWidth()); // segment width in logical pixels -- softhack007 avoid div/0 uint_fast16_t height = max(uint16_t(1), virtualHeight()); // segment height in logical pixels -- softhack007 avoid div/0 return (x%width) + (y%height) * width; @@ -711,7 +711,7 @@ typedef struct Segment { #ifdef WLEDMM_FASTPATH // WLEDMM this is a "gateway" function - we either call _fast or fall back to "slow" - inline void setPixelColorXY(int x, int y, uint32_t col) { + [[gnu::hot]] inline void setPixelColorXY(int x, int y, uint32_t col) { if (!_isSimpleSegment) { // slow path setPixelColorXY_slow(x, y, col); } else { // fast path @@ -724,7 +724,7 @@ typedef struct Segment { setPixelColorXY_fast(x, y, col, scaled_col, int(_2dWidth), int(_2dHeight)); // call "fast" function } } - inline uint32_t getPixelColorXY(int x, int y) const { + [[gnu::hot]] inline uint32_t getPixelColorXY(int x, int y) const { // minimal sanity checks if (!_isValid2D) return 0; // not active if ((unsigned(x) >= _2dWidth) || (unsigned(y) >= _2dHeight)) return 0 ; // check if (x,y) are out-of-range - due to 2's complement, this also catches negative values @@ -1080,7 +1080,7 @@ class WS2812FX { // 96 bytes #endif std::vector _segments; - friend class Segment; + friend struct Segment; uint32_t getPixelColorXYRestored(uint16_t x, uint16_t y) const; // WLEDMM gets the original color from the driver (without downscaling by _bri) diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index 2c7d0fc8..247f166e 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -68,7 +68,7 @@ void WS2812FX::setUpMatrix() { if (!needLedMap) size = 0; // softhack007 USER_PRINTF("setupmatrix customMappingTable alloc %d from %d\n", size, customMappingTableSize); //if (customMappingTable != nullptr) delete[] customMappingTable; - //customMappingTable = new uint16_t[size]; + //customMappingTable = new(std::nothrow) uint16_t[size]; // don't use new / delete if ((size > 0) && (customMappingTable != nullptr)) { // resize @@ -118,7 +118,7 @@ void WS2812FX::setUpMatrix() { JsonArray map = doc.as(); gapSize = map.size(); if (!map.isNull() && (gapSize > 0) && gapSize >= customMappingSize) { // not an empty map //softhack also check gapSize>0 - gapTable = new int8_t[gapSize]; + gapTable = new(std::nothrow) int8_t[gapSize]; if (gapTable) for (size_t i = 0; i < gapSize; i++) { gapTable[i] = constrain(map[i], -1, 1); } diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index cc837fb7..772d9a32 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -93,9 +93,9 @@ Segment::Segment(const Segment &orig) { _dataLen = 0; _t = nullptr; if (ledsrgb && !Segment::_globalLeds) {ledsrgb = nullptr; ledsrgbSize = 0;} // WLEDMM - if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); } + if (orig.name) { name = new(std::nothrow) 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._t) { _t = new(std::nothrow) Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); } //else markForReset(); // WLEDMM // if (orig.ledsrgb && !Segment::_globalLeds) { allocLeds(); if (ledsrgb) memcpy(ledsrgb, orig.ledsrgb, sizeof(CRGB)*length()); } // WLEDMM jMap = nullptr; //WLEDMM jMap @@ -178,9 +178,9 @@ Segment& Segment::operator= (const Segment &orig) { //if (!Segment::_globalLeds) {ledsrgb = oldLeds; ledsrgbSize = oldLedsSize;}; // WLEDMM reuse leds instead of ledsrgb = nullptr; if (!Segment::_globalLeds) {ledsrgb = nullptr; ledsrgbSize = 0;}; // WLEDMM copy has no buffers (yet) // copy source data - if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); } + if (orig.name) { name = new(std::nothrow) 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._t) { _t = new(std::nothrow) Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); } //else markForReset(); // WLEDMM //if (orig.ledsrgb && !Segment::_globalLeds) { allocLeds(); if (ledsrgb) memcpy(ledsrgb, orig.ledsrgb, sizeof(CRGB)*length()); } // WLEDMM don't copy old buffer jMap = nullptr; //WLEDMM jMap @@ -441,7 +441,7 @@ void Segment::startTransition(uint16_t dur) { uint32_t _colorT[NUM_COLORS]; for (size_t i=0; i_briT = _briT; _t->_cctT = _cctT; @@ -473,7 +473,7 @@ uint8_t IRAM_ATTR_YN Segment::currentBri(uint8_t briNew, bool useCct) { #endif uint8_t Segment::currentMode(uint8_t newMode) { - return (progress()>32767U) ? newMode : _t->_modeP; // change effect in the middle of transition + return (progress()>32767U) ? newMode : (_t ? _t->_modeP : newMode); // change effect in the middle of transition } uint32_t Segment::currentColor(uint8_t slot, uint32_t colorNew) { @@ -755,7 +755,7 @@ class JMapC { ArrayAndSize arrayAndSize; arrayAndSize.size = 0; if (arrayChunk[0].is()) { //if array of arrays - arrayAndSize.array = new XandY[arrayChunk.size()]; + arrayAndSize.array = new(std::nothrow) XandY[arrayChunk.size()]; for (JsonVariant arrayElement: arrayChunk) { maxWidth = max((uint16_t)maxWidth, arrayElement[0].as()); // WLEDMM use native min/max maxHeight = max((uint16_t)maxHeight, arrayElement[1].as()); // WLEDMM @@ -766,7 +766,7 @@ class JMapC { } } else { // if array (of x and y) - arrayAndSize.array = new XandY[1]; + arrayAndSize.array = new(std::nothrow) XandY[1]; maxWidth = max((uint16_t)maxWidth, arrayChunk[0].as()); // WLEDMM use native min/max maxHeight = max((uint16_t)maxHeight, arrayChunk[1].as()); // WLEDMM arrayAndSize.array[arrayAndSize.size].x = arrayChunk[0].as(); @@ -798,7 +798,7 @@ class JMapC { void Segment::createjMap() { if (!jMap) { DEBUG_PRINTLN("createjMap"); - jMap = new JMapC(); + jMap = new(std::nothrow) JMapC(); } } @@ -1704,14 +1704,14 @@ void WS2812FX::enumerateLedmaps() { if (len > 0 && len < 33) { (void) cleanUpName(name); len = strlen(name); - ledmapNames[i-1] = new char[len+1]; // +1 to include terminating \0 + ledmapNames[i-1] = new(std::nothrow) char[len+1]; // +1 to include terminating \0 if (ledmapNames[i-1]) strlcpy(ledmapNames[i-1], name, 33); } if (!ledmapNames[i-1]) { char tmp[33]; snprintf_P(tmp, 32, PSTR("ledmap%d.json"), i); len = strlen(tmp); - ledmapNames[i-1] = new char[len+1]; + ledmapNames[i-1] = new(std::nothrow) char[len+1]; if (ledmapNames[i-1]) strlcpy(ledmapNames[i-1], tmp, 33); } @@ -2638,7 +2638,7 @@ bool WS2812FX::deserializeMap(uint8_t n) { size_t size = max(ledmapMaxSize, size_t(Segment::maxWidth * Segment::maxHeight)); // TroyHacks USER_PRINTF("deserializemap customMappingTable alloc %u from %u\n", size, customMappingTableSize); //if (customMappingTable != nullptr) delete[] customMappingTable; - //customMappingTable = new uint16_t[size]; + //customMappingTable = new(std::nothrow) uint16_t[size]; // don't use new / delete if ((size > 0) && (customMappingTable != nullptr)) { diff --git a/wled00/json.cpp b/wled00/json.cpp index 6429bd2e..c51deefa 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -146,7 +146,7 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId) size_t len = 0; if (name != nullptr) len = strlen(name); if (len > 0 && len < 32) { - seg.name = new char[len+1]; + seg.name = new(std::nothrow) char[len+1]; if (seg.name) strlcpy(seg.name, name, len+1); } else { // but is empty (already deleted above) diff --git a/wled00/playlist.cpp b/wled00/playlist.cpp index 1d6f7a99..463f2b15 100644 --- a/wled00/playlist.cpp +++ b/wled00/playlist.cpp @@ -68,7 +68,7 @@ int16_t loadPlaylist(JsonObject playlistObj, byte presetId) { if (playlistLen == 0) return -1; if (playlistLen > 100) playlistLen = 100; - playlistEntries = new PlaylistEntry[playlistLen]; + playlistEntries = new(std::nothrow) PlaylistEntry[playlistLen]; if (playlistEntries == nullptr) return -1; byte it = 0;