Indentations and a few optimisations

Restore addPixelColor() behaviour.
This commit is contained in:
Blaz Kristan 2024-09-23 18:03:17 +02:00
parent 0a5400263b
commit 33cf82a982
6 changed files with 69 additions and 77 deletions

View File

@ -56,6 +56,9 @@
#define RGBW32(r,g,b,w) (uint32_t((byte(w) << 24) | (byte(r) << 16) | (byte(g) << 8) | (byte(b)))) #define RGBW32(r,g,b,w) (uint32_t((byte(w) << 24) | (byte(r) << 16) | (byte(g) << 8) | (byte(b))))
#endif #endif
extern bool realtimeRespectLedMaps; // used in getMappedPixelIndex()
extern byte realtimeMode; // used in getMappedPixelIndex()
/* Not used in all effects yet */ /* Not used in all effects yet */
#define WLED_FPS 42 #define WLED_FPS 42
#define FRAMETIME_FIXED (1000/WLED_FPS) #define FRAMETIME_FIXED (1000/WLED_FPS)
@ -596,9 +599,9 @@ typedef struct Segment {
void fadeToBlackBy(uint8_t fadeBy); void fadeToBlackBy(uint8_t fadeBy);
inline void blendPixelColor(int n, uint32_t color, uint8_t blend) { setPixelColor(n, color_blend(getPixelColor(n), color, blend)); } inline void blendPixelColor(int n, uint32_t color, uint8_t blend) { setPixelColor(n, color_blend(getPixelColor(n), color, blend)); }
inline void blendPixelColor(int n, CRGB c, uint8_t blend) { blendPixelColor(n, RGBW32(c.r,c.g,c.b,0), blend); } inline void blendPixelColor(int n, CRGB c, uint8_t blend) { blendPixelColor(n, RGBW32(c.r,c.g,c.b,0), blend); }
inline void addPixelColor(int n, uint32_t color, bool saturate = false) { setPixelColor(n, color_add(getPixelColor(n), color, saturate)); } inline void addPixelColor(int n, uint32_t color, bool preserveCR = true) { setPixelColor(n, color_add(getPixelColor(n), color, preserveCR)); }
inline void addPixelColor(int n, byte r, byte g, byte b, byte w = 0, bool saturate = false) { addPixelColor(n, RGBW32(r,g,b,w), saturate); } inline void addPixelColor(int n, byte r, byte g, byte b, byte w = 0, bool preserveCR = true) { addPixelColor(n, RGBW32(r,g,b,w), preserveCR); }
inline void addPixelColor(int n, CRGB c, bool saturate = false) { addPixelColor(n, RGBW32(c.r,c.g,c.b,0), saturate); } inline void addPixelColor(int n, CRGB c, bool preserveCR = true) { addPixelColor(n, RGBW32(c.r,c.g,c.b,0), preserveCR); }
inline void fadePixelColor(uint16_t n, uint8_t fade) { setPixelColor(n, color_fade(getPixelColor(n), fade, true)); } inline void fadePixelColor(uint16_t n, uint8_t fade) { setPixelColor(n, color_fade(getPixelColor(n), fade, true)); }
[[gnu::hot]] uint32_t color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255) const; [[gnu::hot]] uint32_t color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255) const;
[[gnu::hot]] uint32_t color_wheel(uint8_t pos) const; [[gnu::hot]] uint32_t color_wheel(uint8_t pos) const;
@ -633,9 +636,9 @@ typedef struct Segment {
// 2D support functions // 2D support functions
inline void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend) { setPixelColorXY(x, y, color_blend(getPixelColorXY(x,y), color, blend)); } inline void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend) { setPixelColorXY(x, y, color_blend(getPixelColorXY(x,y), color, blend)); }
inline void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), blend); } inline void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), blend); }
inline void addPixelColorXY(int x, int y, uint32_t color, bool saturate = false) { setPixelColorXY(x, y, color_add(getPixelColorXY(x,y), color, saturate)); } inline void addPixelColorXY(int x, int y, uint32_t color, bool preserveCR = true) { setPixelColorXY(x, y, color_add(getPixelColorXY(x,y), color, preserveCR)); }
inline void addPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0, bool saturate = false) { addPixelColorXY(x, y, RGBW32(r,g,b,w), saturate); } inline void addPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0, bool preserveCR = true) { addPixelColorXY(x, y, RGBW32(r,g,b,w), preserveCR); }
inline void addPixelColorXY(int x, int y, CRGB c, bool saturate = false) { addPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), saturate); } inline void addPixelColorXY(int x, int y, CRGB c, bool preserveCR = true) { addPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), preserveCR); }
inline void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { setPixelColorXY(x, y, color_fade(getPixelColorXY(x,y), fade, true)); } inline void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { setPixelColorXY(x, y, color_fade(getPixelColorXY(x,y), fade, true)); }
void box_blur(unsigned r = 1U, bool smear = false); // 2D box blur void box_blur(unsigned r = 1U, bool smear = false); // 2D box blur
void blur2D(uint8_t blur_amount, bool smear = false); void blur2D(uint8_t blur_amount, bool smear = false);
@ -837,13 +840,16 @@ class WS2812FX { // 96 bytes
uint16_t uint16_t
getLengthPhysical() const, getLengthPhysical() const,
getLengthTotal() const, // will include virtual/nonexistent pixels in matrix getLengthTotal() const, // will include virtual/nonexistent pixels in matrix
getFps() const, getFps() const;
getMappedPixelIndex(uint16_t index) const;
inline uint16_t getFrameTime() const { return _frametime; } // returns amount of time a frame should take (in ms) inline uint16_t getFrameTime() const { return _frametime; } // returns amount of time a frame should take (in ms)
inline uint16_t getMinShowDelay() const { return MIN_SHOW_DELAY; } // returns minimum amount of time strip.service() can be delayed (constant) inline uint16_t getMinShowDelay() const { return MIN_SHOW_DELAY; } // returns minimum amount of time strip.service() can be delayed (constant)
inline uint16_t getLength() const { return _length; } // returns actual amount of LEDs on a strip (2D matrix may have less LEDs than W*H) inline uint16_t getLength() const { return _length; } // returns actual amount of LEDs on a strip (2D matrix may have less LEDs than W*H)
inline uint16_t getTransition() const { return _transitionDur; } // returns currently set transition time (in ms) inline uint16_t getTransition() const { return _transitionDur; } // returns currently set transition time (in ms)
inline uint16_t getMappedPixelIndex(uint16_t index) const { // convert logical address to physical
if (index < customMappingSize && (realtimeMode == REALTIME_MODE_INACTIVE || realtimeRespectLedMaps)) index = customMappingTable[index];
return index;
};
uint32_t uint32_t
now, now,

View File

@ -191,7 +191,7 @@ void IRAM_ATTR_YN Segment::setPixelColorXY(int x, int y, uint32_t col)
if (yY >= H) break; if (yY >= H) break;
int xX = x; int xX = x;
for (int g = 0; g < grouping; g++) { // groupping horizontally for (int g = 0; g < grouping; g++) { // groupping horizontally
if (xX >= W) continue; // we have reached one dimension's end if (xX >= W) break; // we have reached X dimension's end
#ifndef WLED_DISABLE_MODE_BLEND #ifndef WLED_DISABLE_MODE_BLEND
// if blending modes, blend with underlying pixel // if blending modes, blend with underlying pixel
if (_modeBlend) col = color_blend(strip.getPixelColorXY(start + xX, startY + yY), col, 0xFFFFU - progress(), true); if (_modeBlend) col = color_blend(strip.getPixelColorXY(start + xX, startY + yY), col, 0xFFFFU - progress(), true);
@ -292,11 +292,10 @@ void Segment::blurRow(uint32_t row, fract8 blur_amount, bool smear){
uint32_t part = color_fade(cur, seep); uint32_t part = color_fade(cur, seep);
curnew = color_fade(cur, keep); curnew = color_fade(cur, keep);
if (x > 0) { if (x > 0) {
if (carryover) if (carryover) curnew = color_add(curnew, carryover);
curnew = color_add(curnew, carryover);
uint32_t prev = color_add(lastnew, part); uint32_t prev = color_add(lastnew, part);
if (last != prev) // optimization: only set pixel if color has changed // optimization: only set pixel if color has changed
setPixelColorXY(x - 1, row, prev); if (last != prev) setPixelColorXY(x - 1, row, prev);
} else // first pixel } else // first pixel
setPixelColorXY(x, row, curnew); setPixelColorXY(x, row, curnew);
lastnew = curnew; lastnew = curnew;
@ -325,11 +324,10 @@ void Segment::blurCol(uint32_t col, fract8 blur_amount, bool smear) {
uint32_t part = color_fade(cur, seep); uint32_t part = color_fade(cur, seep);
curnew = color_fade(cur, keep); curnew = color_fade(cur, keep);
if (y > 0) { if (y > 0) {
if (carryover) if (carryover) curnew = color_add(curnew, carryover);
curnew = color_add(curnew, carryover);
uint32_t prev = color_add(lastnew, part); uint32_t prev = color_add(lastnew, part);
if (last != prev) // optimization: only set pixel if color has changed // optimization: only set pixel if color has changed
setPixelColorXY(col, y - 1, prev); if (last != prev) setPixelColorXY(col, y - 1, prev);
} else // first pixel } else // first pixel
setPixelColorXY(col, y, curnew); setPixelColorXY(col, y, curnew);
lastnew = curnew; lastnew = curnew;

View File

@ -628,13 +628,7 @@ uint16_t IRAM_ATTR Segment::virtualHeight() const {
uint16_t IRAM_ATTR_YN Segment::nrOfVStrips() const { uint16_t IRAM_ATTR_YN Segment::nrOfVStrips() const {
unsigned vLen = 1; unsigned vLen = 1;
#ifndef WLED_DISABLE_2D #ifndef WLED_DISABLE_2D
if (is2D()) { if (is2D() && map1D2D == M12_pBar) vLen = virtualWidth();
switch (map1D2D) {
case M12_pBar:
vLen = virtualWidth();
break;
}
}
#endif #endif
return vLen; return vLen;
} }
@ -710,17 +704,21 @@ uint16_t IRAM_ATTR Segment::virtualLength() const {
void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col) void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col)
{ {
if (!isActive()) return; // not active if (!isActive() || i < 0) return; // not active or invalid index
#ifndef WLED_DISABLE_2D #ifndef WLED_DISABLE_2D
int vStrip = 0; int vStrip = 0;
#endif #endif
if (i >= virtualLength() || i<0) // pixel would fall out of segment, check if this is a virtual strip NOTE: this is almost always false if not virtual strip, saves the calculation on 'standard' call // if the 1D effect is using virtual strips "i" will have virtual strip id stored in upper 16 bits
{ // in such case "i" will be > virtualLength()
if (i >= virtualLength()) {
// check if this is a virtual strip
#ifndef WLED_DISABLE_2D #ifndef WLED_DISABLE_2D
vStrip = i>>16; // hack to allow running on virtual strips (2D segment columns/rows) vStrip = i>>16; // hack to allow running on virtual strips (2D segment columns/rows)
i &= 0xFFFF; //truncate vstrip index
if (i >= virtualLength()) return; // if pixel would still fall out of segment just exit
#else
return;
#endif #endif
i &= 0xFFFF; //truncate vstrip index
if (i >= virtualLength() || i<0) return; // if pixel would still fall out of segment just exit
} }
#ifndef WLED_DISABLE_2D #ifndef WLED_DISABLE_2D
@ -734,12 +732,12 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col)
break; break;
case M12_pBar: case M12_pBar:
// expand 1D effect vertically or have it play on virtual strips // expand 1D effect vertically or have it play on virtual strips
if (vStrip>0) setPixelColorXY(vStrip - 1, vH - i - 1, col); if (vStrip > 0) setPixelColorXY(vStrip - 1, vH - i - 1, col);
else for (int x = 0; x < vW; x++) setPixelColorXY(x, vH - i - 1, col); else for (int x = 0; x < vW; x++) setPixelColorXY(x, vH - i - 1, col);
break; break;
case M12_pArc: case M12_pArc:
// expand in circular fashion from center // expand in circular fashion from center
if (i==0) if (i == 0)
setPixelColorXY(0, 0, col); setPixelColorXY(0, 0, col);
else { else {
float r = i; float r = i;
@ -910,9 +908,6 @@ void Segment::setPixelColor(float i, uint32_t col, bool aa)
uint32_t IRAM_ATTR_YN Segment::getPixelColor(int i) const uint32_t IRAM_ATTR_YN Segment::getPixelColor(int i) const
{ {
if (!isActive()) return 0; // not active if (!isActive()) return 0; // not active
#ifndef WLED_DISABLE_2D
int vStrip = i>>16;
#endif
#ifndef WLED_DISABLE_2D #ifndef WLED_DISABLE_2D
if (is2D()) { if (is2D()) {
@ -922,10 +917,11 @@ uint32_t IRAM_ATTR_YN Segment::getPixelColor(int i) const
case M12_Pixels: case M12_Pixels:
return getPixelColorXY(i % vW, i / vW); return getPixelColorXY(i % vW, i / vW);
break; break;
case M12_pBar: case M12_pBar: {
if (vStrip>0) { i &= 0xFFFF; return getPixelColorXY(vStrip - 1, vH - i -1); } int vStrip = i>>16; // virtual strips are only relevant in Bar expansion mode
else return getPixelColorXY(0, vH - i -1); if (vStrip > 0) return getPixelColorXY(vStrip - 1, vH - (i & 0xFFFF) -1);
break; else return getPixelColorXY(0, vH - i -1);
break; }
case M12_pArc: case M12_pArc:
if (i >= vW && i >= vH) { if (i >= vW && i >= vH) {
unsigned vI = sqrt16(i*i/2); unsigned vI = sqrt16(i*i/2);
@ -1884,14 +1880,6 @@ bool WS2812FX::deserializeMap(uint8_t n) {
return (customMappingSize > 0); return (customMappingSize > 0);
} }
__attribute__ ((always_inline)) inline uint16_t WS2812FX::getMappedPixelIndex(uint16_t index) const {
// convert logical address to physical
if (index < customMappingSize
&& (realtimeMode == REALTIME_MODE_INACTIVE || realtimeRespectLedMaps)) index = customMappingTable[index];
return index;
}
WS2812FX* WS2812FX::instance = nullptr; WS2812FX* WS2812FX::instance = nullptr;

View File

@ -437,9 +437,9 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
if (light_gc_col > 1.0f) gammaCorrectCol = true; if (light_gc_col > 1.0f) gammaCorrectCol = true;
else gammaCorrectCol = false; else gammaCorrectCol = false;
if (gammaCorrectVal <= 1.0f || gammaCorrectVal > 3) { if (gammaCorrectVal <= 1.0f || gammaCorrectVal > 3) {
gammaCorrectVal = 1.0f; // no gamma correction gammaCorrectVal = 1.0f; // no gamma correction
gammaCorrectBri = false; gammaCorrectBri = false;
gammaCorrectCol = false; gammaCorrectCol = false;
} }
NeoGammaWLEDMethod::calcGammaTable(gammaCorrectVal); // fill look-up table NeoGammaWLEDMethod::calcGammaTable(gammaCorrectVal); // fill look-up table

View File

@ -34,9 +34,9 @@ uint32_t color_blend(uint32_t color1, uint32_t color2, uint16_t blend, bool b16)
/* /*
* color add function that preserves ratio * color add function that preserves ratio
* original idea: https://github.com/Aircoookie/WLED/pull/2465 by https://github.com/Proto-molecule * original idea: https://github.com/Aircoookie/WLED/pull/2465 by https://github.com/Proto-molecule
* heavily optimized for speed by @dedehai * speed optimisations by @dedehai
*/ */
uint32_t color_add(uint32_t c1, uint32_t c2, bool desat) uint32_t color_add(uint32_t c1, uint32_t c2, bool preserveCR)
{ {
if (c1 == BLACK) return c2; if (c1 == BLACK) return c2;
if (c2 == BLACK) return c1; if (c2 == BLACK) return c1;
@ -47,21 +47,21 @@ uint32_t color_add(uint32_t c1, uint32_t c2, bool desat)
uint32_t w = wg >> 16; uint32_t w = wg >> 16;
uint32_t g = wg & 0xFFFF; uint32_t g = wg & 0xFFFF;
if(desat) { // desaturate if (preserveCR) { // preserve color ratios
unsigned max = r; // check for overflow note unsigned max = std::max(r,g); // check for overflow note
max = g > max ? g : max; max = std::max(max,b);
max = b > max ? b : max; max = std::max(max,w);
max = w > max ? w : max; //unsigned max = r; // check for overflow note
//max = g > max ? g : max;
//max = b > max ? b : max;
//max = w > max ? w : max;
if (max > 255) { if (max > 255) {
uint32_t scale = (uint32_t(255)<<8) / max; // division of two 8bit (shifted) values does not work -> use bit shifts and multiplaction instead uint32_t scale = (uint32_t(255)<<8) / max; // division of two 8bit (shifted) values does not work -> use bit shifts and multiplaction instead
rb = ((rb * scale) >> 8) & 0x00FF00FF; // rb = ((rb * scale) >> 8) & 0x00FF00FF; //
wg = (wg * scale) & 0xFF00FF00; wg = (wg * scale) & 0xFF00FF00;
} } else wg = wg << 8; //shift white and green back to correct position
else wg = wg << 8; //shift white and green back to correct position
return rb | wg; return rb | wg;
} } else {
else {
r = r > 255 ? 255 : r; r = r > 255 ? 255 : r;
g = g > 255 ? 255 : g; g = g > 255 ? 255 : g;
b = b > 255 ? 255 : b; b = b > 255 ? 255 : b;
@ -106,20 +106,20 @@ CRGB ColorFromPaletteWLED(const CRGBPalette16& pal, unsigned index, uint8_t brig
unsigned red1 = entry->r; unsigned red1 = entry->r;
unsigned green1 = entry->g; unsigned green1 = entry->g;
unsigned blue1 = entry->b; unsigned blue1 = entry->b;
if(blendType != NOBLEND) { if (blendType != NOBLEND) {
if(hi4 == 15) entry = &(pal[0]); if (hi4 == 15) entry = &(pal[0]);
else ++entry; else ++entry;
unsigned f2 = ((index & 0x0F) << 4) + 1; // +1 so we scale by 256 as a max value, then result can just be shifted by 8 unsigned f2 = ((index & 0x0F) << 4) + 1; // +1 so we scale by 256 as a max value, then result can just be shifted by 8
unsigned f1 = (257 - f2); // f2 is 1 minimum, so this is 256 max unsigned f1 = (257 - f2); // f2 is 1 minimum, so this is 256 max
red1 = (red1 * f1 + (unsigned)entry->r * f2) >> 8; red1 = (red1 * f1 + (unsigned)entry->r * f2) >> 8;
green1 = (green1 * f1 + (unsigned)entry->g * f2) >> 8; green1 = (green1 * f1 + (unsigned)entry->g * f2) >> 8;
blue1 = (blue1 * f1 + (unsigned)entry->b * f2) >> 8; blue1 = (blue1 * f1 + (unsigned)entry->b * f2) >> 8;
} }
if( brightness < 255) { // note: zero checking could be done to return black but that is hardly ever used so it is omitted if (brightness < 255) { // note: zero checking could be done to return black but that is hardly ever used so it is omitted
uint32_t scale = brightness + 1; // adjust for rounding (bitshift) uint32_t scale = brightness + 1; // adjust for rounding (bitshift)
red1 = (red1 * scale) >> 8; red1 = (red1 * scale) >> 8;
green1 = (green1 * scale) >> 8; green1 = (green1 * scale) >> 8;
blue1 = (blue1 * scale) >> 8; blue1 = (blue1 * scale) >> 8;
} }
return CRGB((uint8_t)red1, (uint8_t)green1, (uint8_t)blue1); return CRGB((uint8_t)red1, (uint8_t)green1, (uint8_t)blue1);
} }
@ -485,7 +485,7 @@ uint16_t approximateKelvinFromRGB(uint32_t rgb) {
} }
} }
//gamma 2.8 lookup table used for color correction // gamma lookup table used for color correction (filled on 1st use (cfg.cpp & set.cpp))
uint8_t NeoGammaWLEDMethod::gammaT[256]; uint8_t NeoGammaWLEDMethod::gammaT[256];
// re-calculates & fills gamma table // re-calculates & fills gamma table

View File

@ -80,7 +80,7 @@ class NeoGammaWLEDMethod {
#define gamma32(c) NeoGammaWLEDMethod::Correct32(c) #define gamma32(c) NeoGammaWLEDMethod::Correct32(c)
#define gamma8(c) NeoGammaWLEDMethod::rawGamma8(c) #define gamma8(c) NeoGammaWLEDMethod::rawGamma8(c)
[[gnu::hot]] uint32_t color_blend(uint32_t, uint32_t, uint16_t, bool b16=false); [[gnu::hot]] uint32_t color_blend(uint32_t, uint32_t, uint16_t, bool b16=false);
[[gnu::hot]] uint32_t color_add(uint32_t, uint32_t, bool desat = false); [[gnu::hot]] uint32_t color_add(uint32_t, uint32_t, bool preserveCR = false);
[[gnu::hot]] uint32_t color_fade(uint32_t c1, uint8_t amount, bool video=false); [[gnu::hot]] uint32_t color_fade(uint32_t c1, uint8_t amount, bool video=false);
[[gnu::hot]] CRGB ColorFromPaletteWLED(const CRGBPalette16 &pal, unsigned index, uint8_t brightness = (uint8_t)255U, TBlendType blendType = LINEARBLEND); [[gnu::hot]] CRGB ColorFromPaletteWLED(const CRGBPalette16 &pal, unsigned index, uint8_t brightness = (uint8_t)255U, TBlendType blendType = LINEARBLEND);
CRGBPalette16 generateHarmonicRandomPalette(CRGBPalette16 &basepalette); CRGBPalette16 generateHarmonicRandomPalette(CRGBPalette16 &basepalette);