mirror of
https://github.com/wled/WLED.git
synced 2025-04-19 20:37:23 +00:00
Reverting addition of bool unScale
, added new improvements and fixes
- Added pre-calculation for segment brightness: stored in _segBri. The impact on FPS is not huge but measurable (~1-2FPS in my test conditions) - Removed `bool unScaled` from `setPixelColor()` function again (it has no/minimal impact on speed but huge impact on flash usage: +850 bytes) - Removed negative checking in `setPixelColorXY()` and replaced it with a local typecast to unsigned, saves a few instructions (tested and working) - Changed int8_t to int in `moveX()` and `moveY()` - Removed a few functions from IRAM as they are now not called for every pixel but only once per segment update - Removed a `virtualWidth()` call from `ripple_base()` - Bugfix in `mode_colortwinkle()`
This commit is contained in:
parent
9114867578
commit
ffbc8c5f70
@ -2294,7 +2294,7 @@ uint16_t mode_colortwinkle() {
|
||||
bool fadeUp = bitRead(SEGENV.data[index], bitNum);
|
||||
|
||||
if (fadeUp) {
|
||||
CRGBW incrementalColor = color_fade(col, fadeUpAmount, true);
|
||||
CRGBW incrementalColor = color_fade(cur, fadeUpAmount, true);
|
||||
col = color_add(cur, incrementalColor);
|
||||
|
||||
if (col.r == 255 || col.g == 255 || col.b == 255) {
|
||||
@ -2528,7 +2528,7 @@ static uint16_t ripple_base() {
|
||||
} else {//randomly create new wave
|
||||
if (random16(IBN + 10000) <= (SEGMENT.intensity >> (SEGMENT.is2D()*3))) {
|
||||
ripples[i].state = 1;
|
||||
ripples[i].pos = SEGMENT.is2D() ? ((random8(SEGENV.virtualWidth())<<8) | (random8(SEGENV.virtualHeight()))) : random16(SEGLEN);
|
||||
ripples[i].pos = SEGMENT.is2D() ? ((random8(SEG_W)<<8) | (random8(SEG_H))) : random16(SEGLEN);
|
||||
ripples[i].color = random8(); //color
|
||||
}
|
||||
}
|
||||
|
26
wled00/FX.h
26
wled00/FX.h
@ -420,8 +420,8 @@ typedef struct Segment {
|
||||
};
|
||||
uint16_t _dataLen;
|
||||
static uint16_t _usedSegmentData;
|
||||
|
||||
static unsigned _vLength; // 1D dimension used for current effect
|
||||
static uint8_t _segBri; // Current brightness of segment
|
||||
static unsigned _vLength; // 1D dimension used for current effect
|
||||
static unsigned _vWidth, _vHeight; // 2D dimensions used for current effect
|
||||
static uint32_t _currentColors[NUM_COLORS]; // colors used for current effect
|
||||
static CRGBPalette16 _currentPalette; // palette used for current effect (includes transition, used in color_from_palette())
|
||||
@ -546,7 +546,7 @@ typedef struct Segment {
|
||||
inline static unsigned vHeight() { return Segment::_vHeight; }
|
||||
inline static uint32_t getCurrentColor(unsigned i) { return Segment::_currentColors[i]; } // { return i < 3 ? Segment::_currentColors[i] : 0; }
|
||||
inline static const CRGBPalette16 &getCurrentPalette() { return Segment::_currentPalette; }
|
||||
|
||||
inline static uint8_t getCurrentBrightness() { return Segment::_segBri; }
|
||||
static void handleRandomPalette();
|
||||
|
||||
void beginDraw(); // set up parameters for current effect
|
||||
@ -589,8 +589,8 @@ typedef struct Segment {
|
||||
|
||||
// 1D strip
|
||||
[[gnu::hot]] uint16_t virtualLength() const;
|
||||
[[gnu::hot]] void setPixelColor(int n, uint32_t c, bool unScaled = true); // set relative pixel within segment with color
|
||||
inline void setPixelColor(unsigned n, uint32_t c, bool unScaled = true) { setPixelColor(int(n), c, unScaled); }
|
||||
[[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)); }
|
||||
#ifdef WLED_USE_AA_PIXELS
|
||||
@ -629,8 +629,8 @@ typedef struct Segment {
|
||||
uint16_t nrOfVStrips() const; // returns number of virtual vertical strips in 2D matrix (used to expand 1D effects into 2D)
|
||||
#ifndef WLED_DISABLE_2D
|
||||
[[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, bool unScaled = true); // set relative pixel within segment with color
|
||||
inline void setPixelColorXY(unsigned x, unsigned y, uint32_t c, bool unScaled = true) { setPixelColorXY(int(x), int(y), c, unScaled); }
|
||||
[[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)); }
|
||||
inline void setPixelColorXY(unsigned x, unsigned y, CRGB c) { setPixelColorXY(int(x), int(y), RGBW32(c.r,c.g,c.b,0)); }
|
||||
@ -651,8 +651,8 @@ typedef struct Segment {
|
||||
void blur2D(uint8_t blur_amount, bool smear = false);
|
||||
void blurRow(int row, fract8 blur_amount, bool smear = false);
|
||||
void blurCol(int col, fract8 blur_amount, bool smear = false);
|
||||
void moveX(int8_t delta, bool wrap = false);
|
||||
void moveY(int8_t delta, bool wrap = false);
|
||||
void moveX(int delta, bool wrap = false);
|
||||
void moveY(int delta, bool wrap = false);
|
||||
void move(uint8_t dir, uint8_t delta, bool wrap = false);
|
||||
void drawCircle(uint16_t cx, uint16_t cy, uint8_t radius, uint32_t c, bool soft = false);
|
||||
inline void drawCircle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c, bool soft = false) { drawCircle(cx, cy, radius, RGBW32(c.r,c.g,c.b,0), soft); }
|
||||
@ -668,8 +668,8 @@ typedef struct Segment {
|
||||
inline void fill_solid(CRGB c) { fill(RGBW32(c.r,c.g,c.b,0)); }
|
||||
#else
|
||||
inline uint16_t XY(int x, int y) { return x; }
|
||||
inline void setPixelColorXY(int x, int y, uint32_t c, bool unScaled = true) { setPixelColor(x, c, unScaled); }
|
||||
inline void setPixelColorXY(unsigned x, unsigned y, uint32_t c, bool unScaled = true) { setPixelColor(int(x), c, unScaled); }
|
||||
inline void setPixelColorXY(int x, int y, uint32_t c) { setPixelColor(x, c); }
|
||||
inline void setPixelColorXY(unsigned x, unsigned y, uint32_t c) { setPixelColor(int(x), c); }
|
||||
inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColor(x, RGBW32(r,g,b,w)); }
|
||||
inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColor(x, RGBW32(c.r,c.g,c.b,0)); }
|
||||
inline void setPixelColorXY(unsigned x, unsigned y, CRGB c) { setPixelColor(int(x), RGBW32(c.r,c.g,c.b,0)); }
|
||||
@ -689,8 +689,8 @@ typedef struct Segment {
|
||||
inline void blur2D(uint8_t blur_amount, bool smear = false) {}
|
||||
inline void blurRow(int row, fract8 blur_amount, bool smear = false) {}
|
||||
inline void blurCol(int col, fract8 blur_amount, bool smear = false) {}
|
||||
inline void moveX(int8_t delta, bool wrap = false) {}
|
||||
inline void moveY(int8_t delta, bool wrap = false) {}
|
||||
inline void moveX(int delta, bool wrap = false) {}
|
||||
inline void moveY(int delta, bool wrap = false) {}
|
||||
inline void move(uint8_t dir, uint8_t delta, bool wrap = false) {}
|
||||
inline void drawCircle(uint16_t cx, uint16_t cy, uint8_t radius, uint32_t c, bool soft = false) {}
|
||||
inline void drawCircle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c, bool soft = false) {}
|
||||
|
@ -168,16 +168,16 @@ uint16_t IRAM_ATTR_YN Segment::XY(int x, int y)
|
||||
return isActive() ? (x%vW) + (y%vH) * vW : 0;
|
||||
}
|
||||
|
||||
void IRAM_ATTR_YN Segment::setPixelColorXY(int x, int y, uint32_t col, bool unScaled)
|
||||
void IRAM_ATTR_YN Segment::setPixelColorXY(int x, int y, uint32_t col)
|
||||
{
|
||||
if (!isActive()) return; // not active
|
||||
|
||||
|
||||
const int vW = vWidth(); // segment width in logical pixels (can be 0 if segment is inactive)
|
||||
const int vH = vHeight(); // segment height in logical pixels (is always >= 1)
|
||||
if (x >= vW|| y >= vH || x<0 || y<0) return; // if pixel would fall out of virtual segment just exit
|
||||
if (unsigned(x) >= vW || unsigned(y) >= vH) return; // if pixel would fall out of virtual segment just exit
|
||||
|
||||
// if color is unscaled
|
||||
if (unScaled) col = color_fade(col, currentBri());
|
||||
if(getCurrentBrightness() < 255)
|
||||
col = color_fade(col, getCurrentBrightness()); // scale brightness
|
||||
|
||||
if (reverse ) x = vW - x - 1;
|
||||
if (reverse_y) y = vH - y - 1;
|
||||
@ -459,7 +459,7 @@ void Segment::box_blur(unsigned radius, bool smear) {
|
||||
delete[] tmpWSum;
|
||||
}
|
||||
|
||||
void Segment::moveX(int8_t delta, bool wrap) {
|
||||
void Segment::moveX(int delta, bool wrap) {
|
||||
if (!isActive()) return; // not active
|
||||
const int vW = vWidth(); // segment width in logical pixels (can be 0 if segment is inactive)
|
||||
const int vH = vHeight(); // segment height in logical pixels (is always >= 1)
|
||||
@ -477,7 +477,7 @@ void Segment::moveX(int8_t delta, bool wrap) {
|
||||
}
|
||||
}
|
||||
|
||||
void Segment::moveY(int8_t delta, bool wrap) {
|
||||
void Segment::moveY(int delta, bool wrap) {
|
||||
if (!isActive()) return; // not active
|
||||
const int vW = vWidth(); // segment width in logical pixels (can be 0 if segment is inactive)
|
||||
const int vH = vHeight(); // segment height in logical pixels (is always >= 1)
|
||||
@ -545,20 +545,18 @@ void Segment::drawCircle(uint16_t cx, uint16_t cy, uint8_t radius, uint32_t col,
|
||||
x++;
|
||||
}
|
||||
} else {
|
||||
// pre-scale color for all pixels
|
||||
col = color_fade(col, currentBri());
|
||||
// Bresenham’s Algorithm
|
||||
int d = 3 - (2*radius);
|
||||
int y = radius, x = 0;
|
||||
while (y >= x) {
|
||||
setPixelColorXY(cx+x, cy+y, col, false);
|
||||
setPixelColorXY(cx-x, cy+y, col, false);
|
||||
setPixelColorXY(cx+x, cy-y, col, false);
|
||||
setPixelColorXY(cx-x, cy-y, col, false);
|
||||
setPixelColorXY(cx+y, cy+x, col, false);
|
||||
setPixelColorXY(cx-y, cy+x, col, false);
|
||||
setPixelColorXY(cx+y, cy-x, col, false);
|
||||
setPixelColorXY(cx-y, cy-x, col, false);
|
||||
setPixelColorXY(cx+x, cy+y, col);
|
||||
setPixelColorXY(cx-x, cy+y, col);
|
||||
setPixelColorXY(cx+x, cy-y, col);
|
||||
setPixelColorXY(cx-x, cy-y, col);
|
||||
setPixelColorXY(cx+y, cy+x, col);
|
||||
setPixelColorXY(cx-y, cy+x, col);
|
||||
setPixelColorXY(cx+y, cy-x, col);
|
||||
setPixelColorXY(cx-y, cy-x, col);
|
||||
x++;
|
||||
if (d > 0) {
|
||||
y--;
|
||||
@ -577,15 +575,13 @@ void Segment::fillCircle(uint16_t cx, uint16_t cy, uint8_t radius, uint32_t col,
|
||||
const int vH = vHeight(); // segment height in logical pixels (is always >= 1)
|
||||
// draw soft bounding circle
|
||||
if (soft) drawCircle(cx, cy, radius, col, soft);
|
||||
// pre-scale color for all pixels
|
||||
col = color_fade(col, currentBri());
|
||||
// fill it
|
||||
for (int y = -radius; y <= radius; y++) {
|
||||
for (int x = -radius; x <= radius; x++) {
|
||||
if (x * x + y * y <= radius * radius &&
|
||||
int(cx)+x >= 0 && int(cy)+y >= 0 &&
|
||||
int(cx)+x < vW && int(cy)+y < vH)
|
||||
setPixelColorXY(cx + x, cy + y, col, false);
|
||||
setPixelColorXY(cx + x, cy + y, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -633,12 +629,10 @@ void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint3
|
||||
if (steep) std::swap(x,y); // restore if steep
|
||||
}
|
||||
} else {
|
||||
// pre-scale color for all pixels
|
||||
c = color_fade(c, currentBri());
|
||||
// Bresenham's algorithm
|
||||
int err = (dx>dy ? dx : -dy)/2; // error direction
|
||||
for (;;) {
|
||||
setPixelColorXY(x0, y0, c, false);
|
||||
setPixelColorXY(x0, y0, c);
|
||||
if (x0==x1 && y0==y1) break;
|
||||
int e2 = err;
|
||||
if (e2 >-dx) { err -= dy; x0 += sx; }
|
||||
|
@ -86,6 +86,9 @@ uint16_t Segment::maxHeight = 1;
|
||||
unsigned Segment::_vLength = 0;
|
||||
unsigned Segment::_vWidth = 0;
|
||||
unsigned Segment::_vHeight = 0;
|
||||
uint8_t Segment::_segBri = 0;
|
||||
//uint8_t Segment::_currentBrightness2 = 0;
|
||||
//uint8_t Segment::_currentBrightness3 = 0;
|
||||
uint32_t Segment::_currentColors[NUM_COLORS] = {0,0,0};
|
||||
CRGBPalette16 Segment::_currentPalette = CRGBPalette16(CRGB::Black);
|
||||
CRGBPalette16 Segment::_randomPalette = generateRandomPalette(); // was CRGBPalette16(DEFAULT_COLOR);
|
||||
@ -413,7 +416,7 @@ void Segment::restoreSegenv(tmpsegd_t &tmpSeg) {
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t IRAM_ATTR Segment::currentBri(bool useCct) const {
|
||||
uint8_t Segment::currentBri(bool useCct) const {
|
||||
unsigned prog = progress();
|
||||
if (prog < 0xFFFFU) {
|
||||
unsigned curBri = (useCct ? cct : (on ? opacity : 0)) * prog;
|
||||
@ -445,6 +448,7 @@ void Segment::beginDraw() {
|
||||
_vWidth = virtualWidth();
|
||||
_vHeight = virtualHeight();
|
||||
_vLength = virtualLength();
|
||||
_segBri = currentBri();
|
||||
// adjust gamma for effects
|
||||
for (unsigned i = 0; i < NUM_COLORS; i++) {
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
@ -624,21 +628,21 @@ void Segment::setPalette(uint8_t pal) {
|
||||
}
|
||||
|
||||
// 2D matrix
|
||||
uint16_t IRAM_ATTR Segment::virtualWidth() const {
|
||||
uint16_t Segment::virtualWidth() const {
|
||||
unsigned groupLen = groupLength();
|
||||
unsigned vWidth = ((transpose ? height() : width()) + groupLen - 1) / groupLen;
|
||||
if (mirror) vWidth = (vWidth + 1) /2; // divide by 2 if mirror, leave at least a single LED
|
||||
return vWidth;
|
||||
}
|
||||
|
||||
uint16_t IRAM_ATTR Segment::virtualHeight() const {
|
||||
uint16_t Segment::virtualHeight() const {
|
||||
unsigned groupLen = groupLength();
|
||||
unsigned vHeight = ((transpose ? width() : height()) + groupLen - 1) / groupLen;
|
||||
if (mirror_y) vHeight = (vHeight + 1) /2; // divide by 2 if mirror, leave at least a single LED
|
||||
return vHeight;
|
||||
}
|
||||
|
||||
uint16_t IRAM_ATTR_YN Segment::nrOfVStrips() const {
|
||||
uint16_t Segment::nrOfVStrips() const {
|
||||
unsigned vLen = 1;
|
||||
#ifndef WLED_DISABLE_2D
|
||||
if (is2D() && map1D2D == M12_pBar) vLen = virtualWidth();
|
||||
@ -683,7 +687,7 @@ static int getPinwheelLength(int vW, int vH) {
|
||||
#endif
|
||||
|
||||
// 1D strip
|
||||
uint16_t IRAM_ATTR Segment::virtualLength() const {
|
||||
uint16_t Segment::virtualLength() const {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
if (is2D()) {
|
||||
unsigned vW = virtualWidth();
|
||||
@ -715,7 +719,7 @@ uint16_t IRAM_ATTR Segment::virtualLength() const {
|
||||
return vLength;
|
||||
}
|
||||
|
||||
void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col, bool unScaled)
|
||||
void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col)
|
||||
{
|
||||
if (!isActive() || i < 0) return; // not active or invalid index
|
||||
#ifndef WLED_DISABLE_2D
|
||||
@ -739,22 +743,20 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col, bool unScaled)
|
||||
if (is2D()) {
|
||||
const int vW = vWidth(); // segment width in logical pixels (can be 0 if segment is inactive)
|
||||
const int vH = vHeight(); // segment height in logical pixels (is always >= 1)
|
||||
// pre-scale color for all pixels
|
||||
col = color_fade(col, currentBri());
|
||||
switch (map1D2D) {
|
||||
case M12_Pixels:
|
||||
// use all available pixels as a long strip
|
||||
setPixelColorXY(i % vW, i / vW, col, false);
|
||||
setPixelColorXY(i % vW, i / vW, col);
|
||||
break;
|
||||
case M12_pBar:
|
||||
// expand 1D effect vertically or have it play on virtual strips
|
||||
if (vStrip > 0) setPixelColorXY(vStrip - 1, vH - i - 1, col, false);
|
||||
else for (int x = 0; x < vW; x++) setPixelColorXY(x, vH - i - 1, col, false);
|
||||
if (vStrip > 0) setPixelColorXY(vStrip - 1, vH - i - 1, col);
|
||||
else for (int x = 0; x < vW; x++) setPixelColorXY(x, vH - i - 1, col);
|
||||
break;
|
||||
case M12_pArc:
|
||||
// expand in circular fashion from center
|
||||
if (i == 0)
|
||||
setPixelColorXY(0, 0, col, false);
|
||||
setPixelColorXY(0, 0, col);
|
||||
else {
|
||||
float r = i;
|
||||
float step = HALF_PI / (2.8284f * r + 4); // we only need (PI/4)/(r/sqrt(2)+1) steps
|
||||
@ -762,8 +764,8 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col, bool unScaled)
|
||||
int x = roundf(sin_t(rad) * r);
|
||||
int y = roundf(cos_t(rad) * r);
|
||||
// exploit symmetry
|
||||
setPixelColorXY(x, y, col, false);
|
||||
setPixelColorXY(y, x, col, false);
|
||||
setPixelColorXY(x, y, col);
|
||||
setPixelColorXY(y, x, col);
|
||||
}
|
||||
// Bresenham’s Algorithm (may not fill every pixel)
|
||||
//int d = 3 - (2*i);
|
||||
@ -782,8 +784,8 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col, bool unScaled)
|
||||
}
|
||||
break;
|
||||
case M12_pCorner:
|
||||
for (int x = 0; x <= i; x++) setPixelColorXY(x, i, col, false);
|
||||
for (int y = 0; y < i; y++) setPixelColorXY(i, y, col, false);
|
||||
for (int x = 0; x <= i; x++) setPixelColorXY(x, i, col);
|
||||
for (int y = 0; y < i; y++) setPixelColorXY(i, y, col);
|
||||
break;
|
||||
case M12_sPinwheel: {
|
||||
// i = angle --> 0 - 296 (Big), 0 - 192 (Medium), 0 - 72 (Small)
|
||||
@ -822,7 +824,7 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col, bool unScaled)
|
||||
int x = posx / Fixed_Scale;
|
||||
int y = posy / Fixed_Scale;
|
||||
// set pixel
|
||||
if (x != lastX || y != lastY) setPixelColorXY(x, y, col, false); // only paint if pixel position is different
|
||||
if (x != lastX || y != lastY) setPixelColorXY(x, y, col); // only paint if pixel position is different
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
// advance to next position
|
||||
@ -846,9 +848,8 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col, bool unScaled)
|
||||
#endif
|
||||
|
||||
unsigned len = length();
|
||||
// if color is unscaled
|
||||
if (unScaled) col = color_fade(col, currentBri());
|
||||
|
||||
if(getCurrentBrightness() < 255) //!!! test without this if
|
||||
col = color_fade(col, getCurrentBrightness()); // scale brightness
|
||||
// expand pixel (taking into account start, grouping, spacing [and offset])
|
||||
i = i * groupLength();
|
||||
if (reverse) { // is segment reversed?
|
||||
@ -1070,11 +1071,9 @@ void Segment::fill(uint32_t c) {
|
||||
if (!isActive()) return; // not active
|
||||
const int cols = is2D() ? vWidth() : vLength();
|
||||
const int rows = vHeight(); // will be 1 for 1D
|
||||
// pre-scale color for all pixels
|
||||
c = color_fade(c, currentBri());
|
||||
for (int y = 0; y < rows; y++) for (int x = 0; x < cols; x++) {
|
||||
if (is2D()) setPixelColorXY(x, y, c, false);
|
||||
else setPixelColor(x, c, false);
|
||||
if (is2D()) setPixelColorXY(x, y, c);
|
||||
else setPixelColor(x, c);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user