speed optimisations, fix for restoreColorLossy, code cleanup (#4895)

- speed optimization in color_add, PS fast_color_add and blur functions
- applying more bit and shift manipulation tricks to squeeze out just a bit more speed on color manipulation functions.
- Optimization on blur is based on work by @blazoncek
- Renamed PS fast_color_add() to fast_color_scaleAdd()
This commit is contained in:
Damian Schneider
2025-09-23 20:15:42 +02:00
committed by GitHub
parent c6b4c77387
commit 8b3975752c
9 changed files with 138 additions and 149 deletions

View File

@@ -682,7 +682,7 @@ uint16_t Segment::maxMappingLength() const {
#endif
// pixel is clipped if it falls outside clipping range
// if clipping start > stop the clipping range is inverted
bool IRAM_ATTR_YN Segment::isPixelClipped(int i) const {
bool Segment::isPixelClipped(int i) const {
if (blendingStyle != BLEND_STYLE_FADE && isInTransition() && _clipStart != _clipStop) {
bool invert = _clipStart > _clipStop; // ineverted start & stop
int start = invert ? _clipStop : _clipStart;
@@ -700,7 +700,7 @@ bool IRAM_ATTR_YN Segment::isPixelClipped(int i) const {
return false;
}
void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col) const
void WLED_O2_ATTR Segment::setPixelColor(int i, uint32_t col) const
{
if (!isActive() || i < 0) return; // not active or invalid index
#ifndef WLED_DISABLE_2D
@@ -913,7 +913,7 @@ void Segment::setPixelColor(float i, uint32_t col, bool aa) const
}
#endif
uint32_t IRAM_ATTR_YN Segment::getPixelColor(int i) const
uint32_t WLED_O2_ATTR Segment::getPixelColor(int i) const
{
if (!isActive() || i < 0) return 0; // not active or invalid index
@@ -1052,7 +1052,7 @@ void Segment::fadeToSecondaryBy(uint8_t fadeBy) const {
void Segment::fadeToBlackBy(uint8_t fadeBy) const {
if (!isActive() || fadeBy == 0) return; // optimization - no scaling to apply
const size_t rlength = rawLength(); // calculate only once
for (unsigned i = 0; i < rlength; i++) setPixelColorRaw(i, color_fade(getPixelColorRaw(i), 255-fadeBy));
for (unsigned i = 0; i < rlength; i++) setPixelColorRaw(i, fast_color_scale(getPixelColorRaw(i), 255-fadeBy));
}
/*
@@ -1072,25 +1072,19 @@ void Segment::blur(uint8_t blur_amount, bool smear) const {
uint8_t keep = smear ? 255 : 255 - blur_amount;
uint8_t seep = blur_amount >> 1;
unsigned vlength = vLength();
uint32_t carryover = BLACK;
uint32_t lastnew; // not necessary to initialize lastnew and last, as both will be initialized by the first loop iteration
uint32_t last;
uint32_t curnew = BLACK;
for (unsigned i = 0; i < vlength; i++) {
uint32_t cur = getPixelColorRaw(i);
uint32_t part = color_fade(cur, seep);
curnew = color_fade(cur, keep);
if (i > 0) {
if (carryover) curnew = color_add(curnew, carryover);
uint32_t prev = color_add(lastnew, part);
// optimization: only set pixel if color has changed
if (last != prev) setPixelColorRaw(i - 1, prev);
} else setPixelColorRaw(i, curnew); // first pixel
lastnew = curnew;
last = cur; // save original value for comparison on next iteration
// handle first pixel to avoid conditional in loop (faster)
uint32_t cur = getPixelColorRaw(0);
uint32_t carryover = fast_color_scale(cur, seep);
setPixelColorRaw(0, fast_color_scale(cur, keep));
for (unsigned i = 1; i < vlength; i++) {
cur = getPixelColorRaw(i);
uint32_t part = fast_color_scale(cur, seep);
cur = fast_color_scale(cur, keep);
cur = color_add(cur, carryover);
setPixelColorRaw(i - 1, color_add(getPixelColorRaw(i - 1), part)); // previous pixel
setPixelColorRaw(i, cur); // current pixel
carryover = part;
}
setPixelColorRaw(vlength - 1, curnew);
}
/*