From 9130e4be54de71079ebcbb1bddc93426545bf831 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Fri, 21 Apr 2023 16:44:58 +0200 Subject: [PATCH] minor optimization of core LED functions * use _fast_ integer types in loops - in contrast to "uint16_t" etc, the compiler can leave out range/overflow corrections, so it might run faster. * fcn_declare.h: revive "WLED_USE_REAL_MATH" option, which can be a bit faster on ESP32. --- wled00/FX.h | 2 +- wled00/FX_fcn.cpp | 65 ++++++++++++++++++++++---------------------- wled00/fcn_declare.h | 18 ++++++------ wled00/led.cpp | 3 +- wled00/wled.h | 4 +-- 5 files changed, 47 insertions(+), 45 deletions(-) diff --git a/wled00/FX.h b/wled00/FX.h index 1bfe8b0d..c20d02b6 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -925,7 +925,7 @@ class WS2812FX { // 96 bytes uint16_t* customMappingTable; uint16_t customMappingSize; - uint32_t _lastShow; + /*uint32_t*/ unsigned long _lastShow; // WLEDMM avoid losing precision uint8_t _segment_index; uint8_t _mainSegment; diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 85f95eef..20c6ca19 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -1097,11 +1097,11 @@ void Segment::refreshLightCapabilities() { * Fills segment with color */ void Segment::fill(uint32_t c) { - const uint16_t cols = is2D() ? virtualWidth() : virtualLength(); - const uint16_t rows = virtualHeight(); // will be 1 for 1D - for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { - if (is2D()) setPixelColorXY(x, y, c); - else setPixelColor(x, c); + const uint_fast16_t cols = is2D() ? virtualWidth() : virtualLength(); // WLEDMM use fast int types + const uint_fast16_t rows = virtualHeight(); // will be 1 for 1D + for(uint_fast16_t y = 0; y < rows; y++) for (uint_fast16_t x = 0; x < cols; x++) { + if (is2D()) setPixelColorXY((uint16_t)x, (uint16_t)y, c); + else setPixelColor((uint16_t)x, c); } } @@ -1124,8 +1124,8 @@ void Segment::fadePixelColor(uint16_t n, uint8_t fade) { * fade out function, higher rate = quicker fade */ void Segment::fade_out(uint8_t rate) { - const uint16_t cols = is2D() ? virtualWidth() : virtualLength(); - const uint16_t rows = virtualHeight(); // will be 1 for 1D + const uint_fast16_t cols = is2D() ? virtualWidth() : virtualLength(); // WLEDMM use fast int types + const uint_fast16_t rows = virtualHeight(); // will be 1 for 1D rate = (255-rate) >> 1; float mappedRate = float(rate) +1.1; @@ -1136,7 +1136,7 @@ void Segment::fade_out(uint8_t rate) { int g2 = G(color); int b2 = B(color); - for (uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { + for (uint_fast16_t y = 0; y < rows; y++) for (uint_fast16_t x = 0; x < cols; x++) { color = is2D() ? getPixelColorXY(x, y) : getPixelColor(x); int w1 = W(color); int r1 = R(color); @@ -1154,19 +1154,19 @@ void Segment::fade_out(uint8_t rate) { gdelta += (g2 == g1) ? 0 : (g2 > g1) ? 1 : -1; bdelta += (b2 == b1) ? 0 : (b2 > b1) ? 1 : -1; - if (is2D()) setPixelColorXY(x, y, r1 + rdelta, g1 + gdelta, b1 + bdelta, w1 + wdelta); - else setPixelColor(x, r1 + rdelta, g1 + gdelta, b1 + bdelta, w1 + wdelta); + if (is2D()) setPixelColorXY((uint16_t)x, (uint16_t)y, r1 + rdelta, g1 + gdelta, b1 + bdelta, w1 + wdelta); + else setPixelColor((uint16_t)x, r1 + rdelta, g1 + gdelta, b1 + bdelta, w1 + wdelta); } } // fades all pixels to black using nscale8() void Segment::fadeToBlackBy(uint8_t fadeBy) { - const uint16_t cols = is2D() ? virtualWidth() : virtualLength(); - const uint16_t rows = virtualHeight(); // will be 1 for 1D + const uint_fast16_t cols = is2D() ? virtualWidth() : virtualLength(); // WLEDMM use fast int types + const uint_fast16_t rows = virtualHeight(); // will be 1 for 1D - for (uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { - if (is2D()) setPixelColorXY(x, y, CRGB(getPixelColorXY(x,y)).nscale8(255-fadeBy)); - else setPixelColor(x, CRGB(getPixelColor(x)).nscale8(255-fadeBy)); + for (uint_fast16_t y = 0; y < rows; y++) for (uint_fast16_t x = 0; x < cols; x++) { + if (is2D()) setPixelColorXY((uint16_t)x, (uint16_t)y, CRGB(getPixelColorXY(x,y)).nscale8(255-fadeBy)); + else setPixelColor((uint16_t)x, CRGB(getPixelColor(x)).nscale8(255-fadeBy)); } } @@ -1178,17 +1178,18 @@ void Segment::blur(uint8_t blur_amount) #ifndef WLED_DISABLE_2D if (is2D()) { // compatibility with 2D - const uint16_t cols = virtualWidth(); - const uint16_t rows = virtualHeight(); - for (uint16_t i = 0; i < rows; i++) blurRow(i, blur_amount); // blur all rows - for (uint16_t k = 0; k < cols; k++) blurCol(k, blur_amount); // blur all columns + const uint_fast16_t cols = virtualWidth(); // WLEDMM use fast int types + const uint_fast16_t rows = virtualHeight(); + for (uint_fast16_t i = 0; i < rows; i++) blurRow(i, blur_amount); // blur all rows + for (uint_fast16_t k = 0; k < cols; k++) blurCol(k, blur_amount); // blur all columns return; } #endif uint8_t keep = 255 - blur_amount; uint8_t seep = blur_amount >> 1; CRGB carryover = CRGB::Black; - for(uint16_t i = 0; i < virtualLength(); i++) + uint_fast16_t vlength = virtualLength(); + for(uint_fast16_t i = 0; i < vlength; i++) { CRGB cur = CRGB(getPixelColor(i)); CRGB part = cur; @@ -1200,9 +1201,9 @@ void Segment::blur(uint8_t blur_amount) uint8_t r = R(c); uint8_t g = G(c); uint8_t b = B(c); - setPixelColor(i-1, qadd8(r, part.red), qadd8(g, part.green), qadd8(b, part.blue)); + setPixelColor((uint16_t)(i-1), qadd8(r, part.red), qadd8(g, part.green), qadd8(b, part.blue)); } - setPixelColor(i,cur.red, cur.green, cur.blue); + setPixelColor((uint16_t)i,cur.red, cur.green, cur.blue); carryover = part; } } @@ -1460,7 +1461,7 @@ void WS2812FX::finalizeInit(void) } void WS2812FX::service() { - uint32_t nowUp = millis(); // Be aware, millis() rolls over every 49 days + unsigned long nowUp = millis(); // Be aware, millis() rolls over every 49 days // WLEDMM avoid losing precision now = nowUp + timebase; if (nowUp - _lastShow < MIN_SHOW_DELAY) return; bool doShow = false; @@ -1478,7 +1479,7 @@ void WS2812FX::service() { { if (seg.grouping == 0) seg.grouping = 1; //sanity check doShow = true; - uint16_t delay = FRAMETIME; + uint16_t frameDelay = FRAMETIME; // WLEDMM avoid name clash with "delay" function if (!seg.freeze) { //only run effect function if not frozen _virtualSegmentLength = seg.virtualLength(); @@ -1493,14 +1494,14 @@ void WS2812FX::service() { // effect blending (execute previous effect) // actual code may be a bit more involved as effects have runtime data including allocated memory //if (seg.transitional && seg._modeP) (*_mode[seg._modeP])(progress()); - delay = (*_mode[seg.currentMode(seg.mode)])(); + frameDelay = (*_mode[seg.currentMode(seg.mode)])(); if (seg.mode != FX_MODE_HALLOWEEN_EYES) seg.call++; - if (seg.transitional && delay > FRAMETIME) delay = FRAMETIME; // force faster updates during transition + if (seg.transitional && frameDelay > FRAMETIME) frameDelay = FRAMETIME; // force faster updates during transition seg.handleTransition(); } - seg.next_time = nowUp + delay; + seg.next_time = nowUp + frameDelay; } _segment_index++; } @@ -1746,7 +1747,7 @@ uint16_t WS2812FX::getLengthTotal(void) { uint16_t WS2812FX::getLengthPhysical(void) { uint16_t len = 0; - for (size_t b = 0; b < busses.getNumBusses(); b++) { + for (unsigned b = 0; b < busses.getNumBusses(); b++) { // WLEDMM use native (fast) types Bus *bus = busses.getBus(b); if (bus->getType() >= TYPE_NET_DDP_RGB) continue; //exclude non-physical network busses len += bus->getLength(); @@ -1758,7 +1759,7 @@ uint16_t WS2812FX::getLengthPhysical(void) { //returns if there is an RGBW bus (supports RGB and White, not only white) //not influenced by auto-white mode, also true if white slider does not affect output white channel bool WS2812FX::hasRGBWBus(void) { - for (size_t b = 0; b < busses.getNumBusses(); b++) { + for (unsigned b = 0; b < busses.getNumBusses(); b++) { // WLEDMM use native (fast) types Bus *bus = busses.getBus(b); if (bus == nullptr || bus->getLength()==0) break; if (bus->hasRGB() && bus->hasWhite()) return true; @@ -1768,7 +1769,7 @@ bool WS2812FX::hasRGBWBus(void) { bool WS2812FX::hasCCTBus(void) { if (cctFromRgb && !correctWB) return false; - for (size_t b = 0; b < busses.getNumBusses(); b++) { + for (unsigned b = 0; b < busses.getNumBusses(); b++) { // WLEDMM use native (fast) types Bus *bus = busses.getBus(b); if (bus == nullptr || bus->getLength()==0) break; switch (bus->getType()) { @@ -1964,10 +1965,10 @@ uint8_t WS2812FX::setPixelSegment(uint8_t n) { void WS2812FX::setRange(uint16_t i, uint16_t i2, uint32_t col) { if (i2 >= i) { - for (uint16_t x = i; x <= i2; x++) setPixelColor(x, col); + for (uint_fast16_t x = i; x <= i2; x++) setPixelColor((uint16_t)x, col); // WLEDMM use fast int types } else { - for (uint16_t x = i2; x <= i; x++) setPixelColor(x, col); + for (uint_fast16_t x = i2; x <= i; x++) setPixelColor((uint16_t)x, col); } } diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index b193e393..519ea5a6 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -372,15 +372,15 @@ void clearEEPROM(); float floor_t(float x); float fmod_t(float num, float denom); #else - #include - #define sin_t sin - #define cos_t cos - #define tan_t tan - #define asin_t asin - #define acos_t acos - #define atan_t atan - #define fmod_t fmod - #define floor_t floor + #include // WLEDMM use "float" variants + #define sin_t sinf + #define cos_t cosf + #define tan_t tanf + #define asin_t asinf + #define acos_t acosf + #define atan_t atanf + #define fmod_t fmodf + #define floor_t floorf #endif //wled_serial.cpp diff --git a/wled00/led.cpp b/wled00/led.cpp index 545aff4d..7e85c36a 100644 --- a/wled00/led.cpp +++ b/wled00/led.cpp @@ -70,7 +70,8 @@ void toggleOnOff() //scales the brightness with the briMultiplier factor byte scaledBri(byte in) { - uint16_t val = ((uint16_t)in*briMultiplier)/100; + if (briMultiplier == 100) return(in); // WLEDMM shortcut + uint_fast16_t val = ((uint_fast16_t)in*(uint_fast16_t)briMultiplier)/100; // WLEDMM if (val > 255) val = 255; return (byte)val; } diff --git a/wled00/wled.h b/wled00/wled.h index ba77a277..ada93852 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2304210 +#define VERSION 2304211 //uncomment this if you have a "my_config.h" file you'd like to use //#define WLED_USE_MY_CONFIG @@ -337,7 +337,7 @@ WLED_GLOBAL byte nightlightMode _INIT(NL_MODE_FADE); // See const.h for ava WLED_GLOBAL bool fadeTransition _INIT(true); // enable crossfading color transition WLED_GLOBAL uint16_t transitionDelay _INIT(750); // default crossfade duration in ms -WLED_GLOBAL byte briMultiplier _INIT(100); // % of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) +WLED_GLOBAL uint_fast16_t briMultiplier _INIT(100); // % of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) // User Interface CONFIG #ifndef SERVERNAME