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.
This commit is contained in:
Frank
2023-04-21 16:44:58 +02:00
parent 363567434d
commit 9130e4be54
5 changed files with 47 additions and 45 deletions

View File

@@ -925,7 +925,7 @@ class WS2812FX { // 96 bytes
uint16_t* customMappingTable; uint16_t* customMappingTable;
uint16_t customMappingSize; uint16_t customMappingSize;
uint32_t _lastShow; /*uint32_t*/ unsigned long _lastShow; // WLEDMM avoid losing precision
uint8_t _segment_index; uint8_t _segment_index;
uint8_t _mainSegment; uint8_t _mainSegment;

View File

@@ -1097,11 +1097,11 @@ void Segment::refreshLightCapabilities() {
* Fills segment with color * Fills segment with color
*/ */
void Segment::fill(uint32_t c) { void Segment::fill(uint32_t c) {
const uint16_t cols = is2D() ? virtualWidth() : virtualLength(); const uint_fast16_t cols = is2D() ? virtualWidth() : virtualLength(); // WLEDMM use fast int types
const uint16_t rows = virtualHeight(); // will be 1 for 1D 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++) { for(uint_fast16_t y = 0; y < rows; y++) for (uint_fast16_t x = 0; x < cols; x++) {
if (is2D()) setPixelColorXY(x, y, c); if (is2D()) setPixelColorXY((uint16_t)x, (uint16_t)y, c);
else setPixelColor(x, 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 * fade out function, higher rate = quicker fade
*/ */
void Segment::fade_out(uint8_t rate) { void Segment::fade_out(uint8_t rate) {
const uint16_t cols = is2D() ? virtualWidth() : virtualLength(); const uint_fast16_t cols = is2D() ? virtualWidth() : virtualLength(); // WLEDMM use fast int types
const uint16_t rows = virtualHeight(); // will be 1 for 1D const uint_fast16_t rows = virtualHeight(); // will be 1 for 1D
rate = (255-rate) >> 1; rate = (255-rate) >> 1;
float mappedRate = float(rate) +1.1; float mappedRate = float(rate) +1.1;
@@ -1136,7 +1136,7 @@ void Segment::fade_out(uint8_t rate) {
int g2 = G(color); int g2 = G(color);
int b2 = B(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); color = is2D() ? getPixelColorXY(x, y) : getPixelColor(x);
int w1 = W(color); int w1 = W(color);
int r1 = R(color); int r1 = R(color);
@@ -1154,19 +1154,19 @@ void Segment::fade_out(uint8_t rate) {
gdelta += (g2 == g1) ? 0 : (g2 > g1) ? 1 : -1; gdelta += (g2 == g1) ? 0 : (g2 > g1) ? 1 : -1;
bdelta += (b2 == b1) ? 0 : (b2 > b1) ? 1 : -1; bdelta += (b2 == b1) ? 0 : (b2 > b1) ? 1 : -1;
if (is2D()) setPixelColorXY(x, y, 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(x, 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() // fades all pixels to black using nscale8()
void Segment::fadeToBlackBy(uint8_t fadeBy) { void Segment::fadeToBlackBy(uint8_t fadeBy) {
const uint16_t cols = is2D() ? virtualWidth() : virtualLength(); const uint_fast16_t cols = is2D() ? virtualWidth() : virtualLength(); // WLEDMM use fast int types
const uint16_t rows = virtualHeight(); // will be 1 for 1D 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++) { for (uint_fast16_t y = 0; y < rows; y++) for (uint_fast16_t x = 0; x < cols; x++) {
if (is2D()) setPixelColorXY(x, y, CRGB(getPixelColorXY(x,y)).nscale8(255-fadeBy)); if (is2D()) setPixelColorXY((uint16_t)x, (uint16_t)y, CRGB(getPixelColorXY(x,y)).nscale8(255-fadeBy));
else setPixelColor(x, CRGB(getPixelColor(x)).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 #ifndef WLED_DISABLE_2D
if (is2D()) { if (is2D()) {
// compatibility with 2D // compatibility with 2D
const uint16_t cols = virtualWidth(); const uint_fast16_t cols = virtualWidth(); // WLEDMM use fast int types
const uint16_t rows = virtualHeight(); const uint_fast16_t rows = virtualHeight();
for (uint16_t i = 0; i < rows; i++) blurRow(i, blur_amount); // blur all rows for (uint_fast16_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 for (uint_fast16_t k = 0; k < cols; k++) blurCol(k, blur_amount); // blur all columns
return; return;
} }
#endif #endif
uint8_t keep = 255 - blur_amount; uint8_t keep = 255 - blur_amount;
uint8_t seep = blur_amount >> 1; uint8_t seep = blur_amount >> 1;
CRGB carryover = CRGB::Black; 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 cur = CRGB(getPixelColor(i));
CRGB part = cur; CRGB part = cur;
@@ -1200,9 +1201,9 @@ void Segment::blur(uint8_t blur_amount)
uint8_t r = R(c); uint8_t r = R(c);
uint8_t g = G(c); uint8_t g = G(c);
uint8_t b = B(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; carryover = part;
} }
} }
@@ -1460,7 +1461,7 @@ void WS2812FX::finalizeInit(void)
} }
void WS2812FX::service() { 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; now = nowUp + timebase;
if (nowUp - _lastShow < MIN_SHOW_DELAY) return; if (nowUp - _lastShow < MIN_SHOW_DELAY) return;
bool doShow = false; bool doShow = false;
@@ -1478,7 +1479,7 @@ void WS2812FX::service() {
{ {
if (seg.grouping == 0) seg.grouping = 1; //sanity check if (seg.grouping == 0) seg.grouping = 1; //sanity check
doShow = true; 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 if (!seg.freeze) { //only run effect function if not frozen
_virtualSegmentLength = seg.virtualLength(); _virtualSegmentLength = seg.virtualLength();
@@ -1493,14 +1494,14 @@ void WS2812FX::service() {
// effect blending (execute previous effect) // effect blending (execute previous effect)
// actual code may be a bit more involved as effects have runtime data including allocated memory // 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()); //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.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.handleTransition();
} }
seg.next_time = nowUp + delay; seg.next_time = nowUp + frameDelay;
} }
_segment_index++; _segment_index++;
} }
@@ -1746,7 +1747,7 @@ uint16_t WS2812FX::getLengthTotal(void) {
uint16_t WS2812FX::getLengthPhysical(void) { uint16_t WS2812FX::getLengthPhysical(void) {
uint16_t len = 0; 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); Bus *bus = busses.getBus(b);
if (bus->getType() >= TYPE_NET_DDP_RGB) continue; //exclude non-physical network busses if (bus->getType() >= TYPE_NET_DDP_RGB) continue; //exclude non-physical network busses
len += bus->getLength(); 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) //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 //not influenced by auto-white mode, also true if white slider does not affect output white channel
bool WS2812FX::hasRGBWBus(void) { 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); Bus *bus = busses.getBus(b);
if (bus == nullptr || bus->getLength()==0) break; if (bus == nullptr || bus->getLength()==0) break;
if (bus->hasRGB() && bus->hasWhite()) return true; if (bus->hasRGB() && bus->hasWhite()) return true;
@@ -1768,7 +1769,7 @@ bool WS2812FX::hasRGBWBus(void) {
bool WS2812FX::hasCCTBus(void) { bool WS2812FX::hasCCTBus(void) {
if (cctFromRgb && !correctWB) return false; 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); Bus *bus = busses.getBus(b);
if (bus == nullptr || bus->getLength()==0) break; if (bus == nullptr || bus->getLength()==0) break;
switch (bus->getType()) { 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) { void WS2812FX::setRange(uint16_t i, uint16_t i2, uint32_t col) {
if (i2 >= i) 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 } 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);
} }
} }

View File

@@ -372,15 +372,15 @@ void clearEEPROM();
float floor_t(float x); float floor_t(float x);
float fmod_t(float num, float denom); float fmod_t(float num, float denom);
#else #else
#include <math.h> #include <math.h> // WLEDMM use "float" variants
#define sin_t sin #define sin_t sinf
#define cos_t cos #define cos_t cosf
#define tan_t tan #define tan_t tanf
#define asin_t asin #define asin_t asinf
#define acos_t acos #define acos_t acosf
#define atan_t atan #define atan_t atanf
#define fmod_t fmod #define fmod_t fmodf
#define floor_t floor #define floor_t floorf
#endif #endif
//wled_serial.cpp //wled_serial.cpp

View File

@@ -70,7 +70,8 @@ void toggleOnOff()
//scales the brightness with the briMultiplier factor //scales the brightness with the briMultiplier factor
byte scaledBri(byte in) 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; if (val > 255) val = 255;
return (byte)val; return (byte)val;
} }

View File

@@ -8,7 +8,7 @@
*/ */
// version code in format yymmddb (b = daily build) // 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 //uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG //#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 bool fadeTransition _INIT(true); // enable crossfading color transition
WLED_GLOBAL uint16_t transitionDelay _INIT(750); // default crossfade duration in ms 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 // User Interface CONFIG
#ifndef SERVERNAME #ifndef SERVERNAME