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 customMappingSize;
uint32_t _lastShow;
/*uint32_t*/ unsigned long _lastShow; // WLEDMM avoid losing precision
uint8_t _segment_index;
uint8_t _mainSegment;

View File

@@ -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);
}
}

View File

@@ -372,15 +372,15 @@ void clearEEPROM();
float floor_t(float x);
float fmod_t(float num, float denom);
#else
#include <math.h>
#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 <math.h> // 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

View File

@@ -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;
}

View File

@@ -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