From eae5a74a11c3d3770d910bb85c475a253573899d Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Wed, 11 Sep 2024 17:14:59 +0200 Subject: [PATCH] color_fade bugfix impure void remove optimisations: hot --- wled00/FX.h | 166 +++++++++++++++++++++---------------------- wled00/FX_2Dfcn.cpp | 2 +- wled00/FX_fcn.cpp | 18 ++--- wled00/colors.cpp | 19 ++--- wled00/fcn_declare.h | 14 ++-- 5 files changed, 111 insertions(+), 108 deletions(-) diff --git a/wled00/FX.h b/wled00/FX.h index b1b1fbcb78..a9de2a1899 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -517,26 +517,26 @@ typedef struct Segment { #endif inline bool getOption(uint8_t n) const { return ((options >> n) & 0x01); } - inline bool isSelected(void) const { return selected; } - inline bool isInTransition(void) const { return _t != nullptr; } - inline bool isActive(void) const { return stop > start; } - inline bool is2D(void) const { return (width()>1 && height()>1); } - inline bool hasRGB(void) const { return _isRGB; } - inline bool hasWhite(void) const { return _hasW; } - inline bool isCCT(void) const { return _isCCT; } - inline uint16_t width(void) const { return isActive() ? (stop - start) : 0; } // segment width in physical pixels (length if 1D) - inline uint16_t height(void) const { return stopY - startY; } // segment height (if 2D) in physical pixels (it *is* always >=1) - inline uint16_t length(void) const { return width() * height(); } // segment length (count) in physical pixels - inline uint16_t groupLength(void) const { return grouping + spacing; } - inline uint8_t getLightCapabilities(void) const { return _capabilities; } - - static uint16_t getUsedSegmentData(void) { return _usedSegmentData; } - static void addUsedSegmentData(int len) { _usedSegmentData += len; } + inline bool isSelected() const { return selected; } + inline bool isInTransition() const { return _t != nullptr; } + inline bool isActive() const { return stop > start; } + inline bool is2D() const { return (width()>1 && height()>1); } + inline bool hasRGB() const { return _isRGB; } + inline bool hasWhite() const { return _hasW; } + inline bool isCCT() const { return _isCCT; } + inline uint16_t width() const { return isActive() ? (stop - start) : 0; } // segment width in physical pixels (length if 1D) + inline uint16_t height() const { return stopY - startY; } // segment height (if 2D) in physical pixels (it *is* always >=1) + inline uint16_t length() const { return width() * height(); } // segment length (count) in physical pixels + inline uint16_t groupLength() const { return grouping + spacing; } + inline uint8_t getLightCapabilities() const { return _capabilities; } + + inline static uint16_t getUsedSegmentData() { return _usedSegmentData; } + inline static void addUsedSegmentData(int len) { _usedSegmentData += len; } #ifndef WLED_DISABLE_MODE_BLEND - static void modeBlend(bool blend) { _modeBlend = blend; } + inline static void modeBlend(bool blend) { _modeBlend = blend; } #endif static void handleRandomPalette(); - inline static const CRGBPalette16 &getCurrentPalette(void) { return Segment::_currentPalette; } + inline static const CRGBPalette16 &getCurrentPalette() { return Segment::_currentPalette; } void setUp(uint16_t i1, uint16_t i2, uint8_t grp=1, uint8_t spc=0, uint16_t ofs=UINT16_MAX, uint16_t i1Y=0, uint16_t i2Y=1); bool setColor(uint8_t slot, uint32_t c); //returns true if changed @@ -546,39 +546,39 @@ typedef struct Segment { void setMode(uint8_t fx, bool loadDefaults = false); void setPalette(uint8_t pal); uint8_t differs(Segment& b) const; - void refreshLightCapabilities(void); + void refreshLightCapabilities(); // runtime data functions - inline uint16_t dataSize(void) const { return _dataLen; } + inline uint16_t dataSize() const { return _dataLen; } bool allocateData(size_t len); // allocates effect data buffer in heap and clears it - void deallocateData(void); // deallocates (frees) effect data buffer from heap - void resetIfRequired(void); // sets all SEGENV variables to 0 and clears data buffer + void deallocateData(); // deallocates (frees) effect data buffer from heap + void resetIfRequired(); // sets all SEGENV variables to 0 and clears data buffer /** * Flags that before the next effect is calculated, * the internal segment state should be reset. * Call resetIfRequired before calling the next effect function. * Safe to call from interrupts and network requests. */ - inline void markForReset(void) { reset = true; } // setOption(SEG_OPTION_RESET, true) + inline void markForReset() { reset = true; } // setOption(SEG_OPTION_RESET, true) // transition functions void startTransition(uint16_t dur); // transition has to start before actual segment values change - void stopTransition(void); // ends transition mode by destroying transition structure (does nothing if not in transition) - inline void handleTransition(void) { if (progress() == 0xFFFFU) stopTransition(); } + void stopTransition(); // ends transition mode by destroying transition structure (does nothing if not in transition) + inline void handleTransition() { if (progress() == 0xFFFFU) stopTransition(); } #ifndef WLED_DISABLE_MODE_BLEND void swapSegenv(tmpsegd_t &tmpSegD); // copies segment data into specifed buffer, if buffer is not a transition buffer, segment data is overwritten from transition buffer void restoreSegenv(tmpsegd_t &tmpSegD); // restores segment data from buffer, if buffer is not transition buffer, changed values are copied to transition buffer #endif - uint16_t progress(void) const; // transition progression between 0-65535 - uint8_t currentBri(bool useCct = false) const; // current segment brightness/CCT (blended while in transition) - uint8_t currentMode(void) const; // currently active effect/mode (while in transition) - uint32_t currentColor(uint8_t slot) const; // currently active segment color (blended while in transition) - CRGBPalette16 &loadPalette(CRGBPalette16 &tgt, uint8_t pal); - void setCurrentPalette(void); + [[gnu::hot]] uint16_t progress() const; // transition progression between 0-65535 + [[gnu::hot]] uint8_t currentBri(bool useCct = false) const; // current segment brightness/CCT (blended while in transition) + uint8_t currentMode() const; // currently active effect/mode (while in transition) + [[gnu::hot]] uint32_t currentColor(uint8_t slot) const; // currently active segment color (blended while in transition) + [[gnu::hot]] CRGBPalette16 &loadPalette(CRGBPalette16 &tgt, uint8_t pal); + void setCurrentPalette(); // 1D strip - uint16_t virtualLength(void) const; - void setPixelColor(int n, uint32_t c); // set relative pixel within segment with color + [[gnu::hot]] uint16_t virtualLength() const; + [[gnu::hot]] void setPixelColor(int n, uint32_t c); // set relative pixel within segment with color inline void setPixelColor(unsigned n, uint32_t c) { setPixelColor(int(n), c); } inline void setPixelColor(int n, byte r, byte g, byte b, byte w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); } inline void setPixelColor(int n, CRGB c) { setPixelColor(n, RGBW32(c.r,c.g,c.b,0)); } @@ -587,7 +587,7 @@ typedef struct Segment { inline void setPixelColor(float i, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0, bool aa = true) { setPixelColor(i, RGBW32(r,g,b,w), aa); } inline void setPixelColor(float i, CRGB c, bool aa = true) { setPixelColor(i, RGBW32(c.r,c.g,c.b,0), aa); } #endif - uint32_t getPixelColor(int i) const; + [[gnu::hot]] uint32_t getPixelColor(int i) const; // 1D support functions (some implement 2D as well) void blur(uint8_t, bool smear = false); void fill(uint32_t c); @@ -599,8 +599,8 @@ typedef struct Segment { inline void addPixelColor(int n, byte r, byte g, byte b, byte w = 0, bool fast = false) { addPixelColor(n, RGBW32(r,g,b,w), fast); } inline void addPixelColor(int n, CRGB c, bool fast = false) { addPixelColor(n, RGBW32(c.r,c.g,c.b,0), fast); } inline void fadePixelColor(uint16_t n, uint8_t fade) { setPixelColor(n, color_fade(getPixelColor(n), fade, true)); } - uint32_t color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255) const; - uint32_t color_wheel(uint8_t pos) 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; // 2D Blur: shortcuts for bluring columns or rows only (50% faster than full 2D blur) inline void blurCols(fract8 blur_amount, bool smear = false) { // blur all columns @@ -613,12 +613,12 @@ typedef struct Segment { } // 2D matrix - uint16_t virtualWidth(void) const; // segment width in virtual pixels (accounts for groupping and spacing) - uint16_t virtualHeight(void) const; // segment height in virtual pixels (accounts for groupping and spacing) - uint16_t nrOfVStrips(void) const; // returns number of virtual vertical strips in 2D matrix (used to expand 1D effects into 2D) + [[gnu::hot]] uint16_t virtualWidth() const; // segment width in virtual pixels (accounts for groupping and spacing) + [[gnu::hot]] uint16_t virtualHeight() const; // segment height in virtual pixels (accounts for groupping and spacing) + [[gnu::hot]] uint16_t nrOfVStrips() const; // returns number of virtual vertical strips in 2D matrix (used to expand 1D effects into 2D) #ifndef WLED_DISABLE_2D - uint16_t XY(uint16_t x, uint16_t y); // support function to get relative index within segment - void setPixelColorXY(int x, int y, uint32_t c); // set relative pixel within segment with color + [[gnu::hot]] uint16_t XY(int x, int y); // support function to get relative index within segment + [[gnu::hot]] void setPixelColorXY(int x, int y, uint32_t c); // set relative pixel within segment with color inline void setPixelColorXY(unsigned x, unsigned y, uint32_t c) { setPixelColorXY(int(x), int(y), c); } inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); } inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); } @@ -628,7 +628,7 @@ typedef struct Segment { inline void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColorXY(x, y, RGBW32(r,g,b,w), aa); } inline void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), aa); } #endif - uint32_t getPixelColorXY(int x, int y) const; + [[gnu::hot]] uint32_t getPixelColorXY(int x, int y) const; // 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, CRGB c, uint8_t blend) { blendPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), blend); } @@ -697,8 +697,8 @@ typedef struct Segment { // main "strip" class class WS2812FX { // 96 bytes - typedef uint16_t (*mode_ptr)(void); // pointer to mode function - typedef void (*show_callback)(void); // pre show callback + typedef uint16_t (*mode_ptr)(); // pointer to mode function + typedef void (*show_callback)(); // pre show callback typedef struct ModeData { uint8_t _id; // mode (effect) id mode_ptr _fcn; // mode (effect) function @@ -764,29 +764,29 @@ class WS2812FX { // 96 bytes customPalettes.clear(); } - static WS2812FX* getInstance(void) { return instance; } + static WS2812FX* getInstance() { return instance; } void #ifdef WLED_DEBUG printSize(), // prints memory usage for strip components #endif finalizeInit(), // initialises strip components - service(void), // executes effect functions when due and calls strip.show() + service(), // executes effect functions when due and calls strip.show() setMode(uint8_t segid, uint8_t m), // sets effect/mode for given segment (high level API) setColor(uint8_t slot, uint32_t c), // sets color (in slot) for given segment (high level API) setCCT(uint16_t k), // sets global CCT (either in relative 0-255 value or in K) setBrightness(uint8_t b, bool direct = false), // sets strip brightness setRange(uint16_t i, uint16_t i2, uint32_t col), // used for clock overlay - purgeSegments(void), // removes inactive segments from RAM (may incure penalty and memory fragmentation but reduces vector footprint) + purgeSegments(), // removes inactive segments from RAM (may incure penalty and memory fragmentation but reduces vector footprint) setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t grouping = 1, uint8_t spacing = 0, uint16_t offset = UINT16_MAX, uint16_t startY=0, uint16_t stopY=1), setMainSegmentId(uint8_t n), resetSegments(), // marks all segments for reset makeAutoSegments(bool forceReset = false), // will create segments based on configured outputs fixInvalidSegments(), // fixes incorrect segment configuration setPixelColor(unsigned n, uint32_t c), // paints absolute strip pixel with index n and color c - show(void), // initiates LED output + show(), // initiates LED output setTargetFps(uint8_t fps), - setupEffectData(void); // add default effects to the list; defined in FX.cpp + setupEffectData(); // add default effects to the list; defined in FX.cpp inline void restartRuntime() { for (Segment &seg : _segments) seg.markForReset(); } inline void setTransitionMode(bool t) { for (Segment &seg : _segments) seg.startTransition(t ? _transitionDur : 0); } @@ -794,74 +794,74 @@ class WS2812FX { // 96 bytes inline void setPixelColor(unsigned n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); } inline void setPixelColor(unsigned n, CRGB c) { setPixelColor(n, c.red, c.green, c.blue); } inline void fill(uint32_t c) { for (unsigned i = 0; i < getLengthTotal(); i++) setPixelColor(i, c); } // fill whole strip with color (inline) - inline void trigger(void) { _triggered = true; } // Forces the next frame to be computed on all active segments. + inline void trigger() { _triggered = true; } // Forces the next frame to be computed on all active segments. inline void setShowCallback(show_callback cb) { _callback = cb; } inline void setTransition(uint16_t t) { _transitionDur = t; } // sets transition time (in ms) inline void appendSegment(const Segment &seg = Segment()) { if (_segments.size() < getMaxSegments()) _segments.push_back(seg); } - inline void suspend(void) { _suspend = true; } // will suspend (and canacel) strip.service() execution - inline void resume(void) { _suspend = false; } // will resume strip.service() execution + inline void suspend() { _suspend = true; } // will suspend (and canacel) strip.service() execution + inline void resume() { _suspend = false; } // will resume strip.service() execution bool paletteFade, - checkSegmentAlignment(void), - hasRGBWBus(void) const, - hasCCTBus(void) const, - isUpdating(void) const, // return true if the strip is being sent pixel updates + checkSegmentAlignment(), + hasRGBWBus() const, + hasCCTBus() const, + isUpdating() const, // return true if the strip is being sent pixel updates deserializeMap(uint8_t n=0); - inline bool isServicing(void) const { return _isServicing; } // returns true if strip.service() is executing - inline bool hasWhiteChannel(void) const { return _hasWhiteChannel; } // returns true if strip contains separate white chanel - inline bool isOffRefreshRequired(void) const { return _isOffRefreshRequired; } // returns true if strip requires regular updates (i.e. TM1814 chipset) - inline bool isSuspended(void) const { return _suspend; } // returns true if strip.service() execution is suspended - inline bool needsUpdate(void) const { return _triggered; } // returns true if strip received a trigger() request + inline bool isServicing() const { return _isServicing; } // returns true if strip.service() is executing + inline bool hasWhiteChannel() const { return _hasWhiteChannel; } // returns true if strip contains separate white chanel + inline bool isOffRefreshRequired() const { return _isOffRefreshRequired; } // returns true if strip requires regular updates (i.e. TM1814 chipset) + inline bool isSuspended() const { return _suspend; } // returns true if strip.service() execution is suspended + inline bool needsUpdate() const { return _triggered; } // returns true if strip received a trigger() request uint8_t paletteBlend, cctBlending, - getActiveSegmentsNum(void) const, - getFirstSelectedSegId(void) const, - getLastActiveSegmentId(void) const, + getActiveSegmentsNum() const, + getFirstSelectedSegId() const, + getLastActiveSegmentId() const, getActiveSegsLightCapabilities(bool selectedOnly = false) const, addEffect(uint8_t id, mode_ptr mode_fn, const char *mode_name); // add effect to the list; defined in FX.cpp; - inline uint8_t getBrightness(void) const { return _brightness; } // returns current strip brightness - inline uint8_t getMaxSegments(void) const { return MAX_NUM_SEGMENTS; } // returns maximum number of supported segments (fixed value) - inline uint8_t getSegmentsNum(void) const { return _segments.size(); } // returns currently present segments - inline uint8_t getCurrSegmentId(void) const { return _segment_index; } // returns current segment index (only valid while strip.isServicing()) - inline uint8_t getMainSegmentId(void) const { return _mainSegment; } // returns main segment index - inline uint8_t getPaletteCount() const { return 13 + GRADIENT_PALETTE_COUNT + customPalettes.size(); } - inline uint8_t getTargetFps() const { return _targetFps; } // returns rough FPS value for las 2s interval - inline uint8_t getModeCount() const { return _modeCount; } // returns number of registered modes/effects + inline uint8_t getBrightness() const { return _brightness; } // returns current strip brightness + inline uint8_t getMaxSegments() const { return MAX_NUM_SEGMENTS; } // returns maximum number of supported segments (fixed value) + inline uint8_t getSegmentsNum() const { return _segments.size(); } // returns currently present segments + inline uint8_t getCurrSegmentId() const { return _segment_index; } // returns current segment index (only valid while strip.isServicing()) + inline uint8_t getMainSegmentId() const { return _mainSegment; } // returns main segment index + inline uint8_t getPaletteCount() const { return 13 + GRADIENT_PALETTE_COUNT + customPalettes.size(); } + inline uint8_t getTargetFps() const { return _targetFps; } // returns rough FPS value for las 2s interval + inline uint8_t getModeCount() const { return _modeCount; } // returns number of registered modes/effects uint16_t - getLengthPhysical(void) const, - getLengthTotal(void) const, // will include virtual/nonexistent pixels in matrix + getLengthPhysical() const, + getLengthTotal() const, // will include virtual/nonexistent pixels in matrix getFps() const, getMappedPixelIndex(uint16_t index) const; - inline uint16_t getFrameTime(void) const { return _frametime; } // returns amount of time a frame should take (in ms) - inline uint16_t getMinShowDelay(void) const { return MIN_SHOW_DELAY; } // returns minimum amount of time strip.service() can be delayed (constant) - inline uint16_t getLength(void) const { return _length; } // returns actual amount of LEDs on a strip (2D matrix may have less LEDs than W*H) - inline uint16_t getTransition(void) const { return _transitionDur; } // returns currently set transition time (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 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) uint32_t now, timebase, getPixelColor(uint16_t) const; - inline uint32_t getLastShow(void) const { return _lastShow; } // returns millis() timestamp of last strip.show() call + inline uint32_t getLastShow() const { return _lastShow; } // returns millis() timestamp of last strip.show() call inline uint32_t segColor(uint8_t i) const { return _colors_t[i]; } // returns currently valid color (for slot i) AKA SEGCOLOR(); may be blended between two colors while in transition const char * getModeData(uint8_t id = 0) const { return (id && id<_modeCount) ? _modeData[id] : PSTR("Solid"); } const char ** - getModeDataSrc(void) { return &(_modeData[0]); } // vectors use arrays for underlying data + getModeDataSrc() { return &(_modeData[0]); } // vectors use arrays for underlying data Segment& getSegment(uint8_t id); - inline Segment& getFirstSelectedSeg(void) { return _segments[getFirstSelectedSegId()]; } // returns reference to first segment that is "selected" - inline Segment& getMainSegment(void) { return _segments[getMainSegmentId()]; } // returns reference to main segment - inline Segment* getSegments(void) { return &(_segments[0]); } // returns pointer to segment vector structure (warning: use carefully) + inline Segment& getFirstSelectedSeg() { return _segments[getFirstSelectedSegId()]; } // returns reference to first segment that is "selected" + inline Segment& getMainSegment() { return _segments[getMainSegmentId()]; } // returns reference to main segment + inline Segment* getSegments() { return &(_segments[0]); } // returns pointer to segment vector structure (warning: use carefully) // 2D support (panels) bool @@ -908,7 +908,7 @@ class WS2812FX { // 96 bytes // end 2D support - void loadCustomPalettes(void); // loads custom palettes from JSON + void loadCustomPalettes(); // loads custom palettes from JSON std::vector customPalettes; // TODO: move custom palettes out of WS2812FX class struct { diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index df2dc8d066..26ec1d608a 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -161,7 +161,7 @@ void WS2812FX::setUpMatrix() { #ifndef WLED_DISABLE_2D // XY(x,y) - gets pixel index within current segment (often used to reference leds[] array element) -uint16_t IRAM_ATTR_YN Segment::XY(uint16_t x, uint16_t y) +uint16_t IRAM_ATTR_YN Segment::XY(int x, int y) { unsigned width = virtualWidth(); // segment width in logical pixels (can be 0 if segment is inactive) unsigned height = virtualHeight(); // segment height in logical pixels (is always >= 1) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 7a6fa40b52..d3521c90ce 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -1197,7 +1197,7 @@ uint32_t Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_ /////////////////////////////////////////////////////////////////////////////// //do not call this method from system context (network callback) -void WS2812FX::finalizeInit(void) { +void WS2812FX::finalizeInit() { //reset segment runtimes for (segment &seg : _segments) { seg.markForReset(); @@ -1366,7 +1366,7 @@ uint32_t IRAM_ATTR WS2812FX::getPixelColor(uint16_t i) const { return BusManager::getPixelColor(i); } -void WS2812FX::show(void) { +void WS2812FX::show() { // avoid race condition, capture _callback value show_callback callback = _callback; if (callback) callback(); @@ -1463,7 +1463,7 @@ uint8_t WS2812FX::getActiveSegsLightCapabilities(bool selectedOnly) const { return totalLC; } -uint8_t WS2812FX::getFirstSelectedSegId(void) const { +uint8_t WS2812FX::getFirstSelectedSegId() const { size_t i = 0; for (const segment &seg : _segments) { if (seg.isActive() && seg.isSelected()) return i; @@ -1481,14 +1481,14 @@ void WS2812FX::setMainSegmentId(uint8_t n) { return; } -uint8_t WS2812FX::getLastActiveSegmentId(void) const { +uint8_t WS2812FX::getLastActiveSegmentId() const { for (size_t i = _segments.size() -1; i > 0; i--) { if (_segments[i].isActive()) return i; } return 0; } -uint8_t WS2812FX::getActiveSegmentsNum(void) const { +uint8_t WS2812FX::getActiveSegmentsNum() const { uint8_t c = 0; for (size_t i = 0; i < _segments.size(); i++) { if (_segments[i].isActive()) c++; @@ -1496,13 +1496,13 @@ uint8_t WS2812FX::getActiveSegmentsNum(void) const { return c; } -uint16_t WS2812FX::getLengthTotal(void) const { +uint16_t WS2812FX::getLengthTotal() const { unsigned len = Segment::maxWidth * Segment::maxHeight; // will be _length for 1D (see finalizeInit()) but should cover whole matrix for 2D if (isMatrix && _length > len) len = _length; // for 2D with trailing strip return len; } -uint16_t WS2812FX::getLengthPhysical(void) const { +uint16_t WS2812FX::getLengthPhysical() const { unsigned len = 0; for (size_t b = 0; b < BusManager::getNumBusses(); b++) { Bus *bus = BusManager::getBus(b); @@ -1515,7 +1515,7 @@ uint16_t WS2812FX::getLengthPhysical(void) const { //used for JSON API info.leds.rgbw. Little practical use, deprecate with info.leds.rgbw. //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) const { +bool WS2812FX::hasRGBWBus() const { for (size_t b = 0; b < BusManager::getNumBusses(); b++) { Bus *bus = BusManager::getBus(b); if (bus == nullptr || bus->getLength()==0) break; @@ -1524,7 +1524,7 @@ bool WS2812FX::hasRGBWBus(void) const { return false; } -bool WS2812FX::hasCCTBus(void) const { +bool WS2812FX::hasCCTBus() const { if (cctFromRgb && !correctWB) return false; for (size_t b = 0; b < BusManager::getNumBusses(); b++) { Bus *bus = BusManager::getBus(b); diff --git a/wled00/colors.cpp b/wled00/colors.cpp index ebea7ea055..ac1dee00a1 100644 --- a/wled00/colors.cpp +++ b/wled00/colors.cpp @@ -37,6 +37,8 @@ uint32_t color_blend(uint32_t color1, uint32_t color2, uint16_t blend, bool b16) */ uint32_t color_add(uint32_t c1, uint32_t c2, bool fast) { + if (c1 == BLACK) return c2; + if (c2 == BLACK) return c1; if (fast) { uint8_t r = R(c1); uint8_t g = G(c1); @@ -68,17 +70,18 @@ uint32_t color_add(uint32_t c1, uint32_t c2, bool fast) uint32_t color_fade(uint32_t c1, uint8_t amount, bool video) { + if (c1 == BLACK || amount + video == 0) return BLACK; uint32_t scaledcolor; // color order is: W R G B from MSB to LSB uint32_t r = R(c1); uint32_t g = G(c1); uint32_t b = B(c1); uint32_t w = W(c1); - uint32_t scale = amount + !video; // 32bit for faster calculation + uint32_t scale = amount; // 32bit for faster calculation if (video) { - scaledcolor = (((r * scale) >> 8) << 16) + ((r && scale) ? 1 : 0); - scaledcolor |= (((g * scale) >> 8) << 8) + ((g && scale) ? 1 : 0); - scaledcolor |= ((b * scale) >> 8) + ((b && scale) ? 1 : 0); - scaledcolor |= (((w * scale) >> 8) << 24) + ((w && scale) ? 1 : 0); + scaledcolor = (((r * scale) >> 8) + ((r && scale) ? 1 : 0)) << 16; + scaledcolor |= (((g * scale) >> 8) + ((g && scale) ? 1 : 0)) << 8; + scaledcolor |= ((b * scale) >> 8) + ((b && scale) ? 1 : 0); + scaledcolor |= (((w * scale) >> 8) + ((w && scale) ? 1 : 0)) << 24; } else { scaledcolor = ((r * scale) >> 8) << 16; scaledcolor |= ((g * scale) >> 8) << 8; @@ -195,7 +198,7 @@ CRGBPalette16 generateHarmonicRandomPalette(CRGBPalette16 &basepalette) RGBpalettecolors[3]); } -CRGBPalette16 generateRandomPalette(void) //generate fully random palette +CRGBPalette16 generateRandomPalette() //generate fully random palette { return CRGBPalette16(CHSV(random8(), random8(160, 255), random8(128, 255)), CHSV(random8(), random8(160, 255), random8(128, 255)), @@ -476,14 +479,14 @@ void NeoGammaWLEDMethod::calcGammaTable(float gamma) } } -uint8_t NeoGammaWLEDMethod::Correct(uint8_t value) +uint8_t IRAM_ATTR NeoGammaWLEDMethod::Correct(uint8_t value) { if (!gammaCorrectCol) return value; return gammaT[value]; } // used for color gamma correction -uint32_t NeoGammaWLEDMethod::Correct32(uint32_t color) +uint32_t IRAM_ATTR NeoGammaWLEDMethod::Correct32(uint32_t color) { if (!gammaCorrectCol) return color; uint8_t w = W(color); diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index d95b8ef8e4..f8399b1ad6 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -69,20 +69,20 @@ typedef struct WiFiConfig { // similar to NeoPixelBus NeoGammaTableMethod but allows dynamic changes (superseded by NPB::NeoGammaDynamicTableMethod) class NeoGammaWLEDMethod { public: - static uint8_t Correct(uint8_t value); // apply Gamma to single channel - static uint32_t Correct32(uint32_t color); // apply Gamma to RGBW32 color (WLED specific, not used by NPB) - static void calcGammaTable(float gamma); // re-calculates & fills gamma table + [[gnu::hot]] static uint8_t Correct(uint8_t value); // apply Gamma to single channel + [[gnu::hot]] static uint32_t Correct32(uint32_t color); // apply Gamma to RGBW32 color (WLED specific, not used by NPB) + static void calcGammaTable(float gamma); // re-calculates & fills gamma table static inline uint8_t rawGamma8(uint8_t val) { return gammaT[val]; } // get value from Gamma table (WLED specific, not used by NPB) private: static uint8_t gammaT[]; }; #define gamma32(c) NeoGammaWLEDMethod::Correct32(c) #define gamma8(c) NeoGammaWLEDMethod::rawGamma8(c) -uint32_t color_blend(uint32_t,uint32_t,uint16_t,bool b16=false); -uint32_t color_add(uint32_t,uint32_t, bool fast=false); -uint32_t color_fade(uint32_t c1, uint8_t amount, bool video=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 fast=false); +[[gnu::hot]] uint32_t color_fade(uint32_t c1, uint8_t amount, bool video=false); CRGBPalette16 generateHarmonicRandomPalette(CRGBPalette16 &basepalette); -CRGBPalette16 generateRandomPalette(void); +CRGBPalette16 generateRandomPalette(); inline uint32_t colorFromRgbw(byte* rgbw) { return uint32_t((byte(rgbw[3]) << 24) | (byte(rgbw[0]) << 16) | (byte(rgbw[1]) << 8) | (byte(rgbw[2]))); } void colorHStoRGB(uint16_t hue, byte sat, byte* rgb); //hue, sat to rgb void colorKtoRGB(uint16_t kelvin, byte* rgb);