Skip to content

Commit 8fae964

Browse files
authored
Allocate segment data based on currently active segments (wled#2217)
1 parent baf49b8 commit 8fae964

File tree

3 files changed

+45
-26
lines changed

3 files changed

+45
-26
lines changed

wled00/FX.cpp

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2614,7 +2614,7 @@ uint16_t WS2812FX::mode_glitter()
26142614

26152615

26162616

2617-
//each needs 11 bytes
2617+
//each needs 12 bytes
26182618
//Spark type is used for popcorn, 1D fireworks, and drip
26192619
typedef struct Spark {
26202620
float pos;
@@ -2629,7 +2629,7 @@ typedef struct Spark {
26292629
*/
26302630
uint16_t WS2812FX::mode_popcorn(void) {
26312631
//allocate segment data
2632-
uint16_t maxNumPopcorn = 22; // max 22 on 18 segment ESP8266
2632+
uint16_t maxNumPopcorn = 21; // max 21 on 16 segment ESP8266
26332633
uint16_t dataSize = sizeof(spark) * maxNumPopcorn;
26342634
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
26352635

@@ -2688,7 +2688,7 @@ uint16_t WS2812FX::candle(bool multi)
26882688
if (multi)
26892689
{
26902690
//allocate segment data
2691-
uint16_t dataSize = (SEGLEN -1) *3; // max length of segment on 18 segment ESP8266 is 75 pixels
2691+
uint16_t dataSize = (SEGLEN -1) *3; //max. 1365 pixels (ESP8266)
26922692
if (!SEGENV.allocateData(dataSize)) return candle(false); //allocation failed
26932693
}
26942694

@@ -2776,13 +2776,11 @@ uint16_t WS2812FX::mode_candle_multi()
27762776
/ Speed sets frequency of new starbursts, intensity is the intensity of the burst
27772777
*/
27782778
#ifdef ESP8266
2779-
#define STARBURST_MAX_FRAG 4
2780-
#define STARBURST_MAX_STARS 6
2779+
#define STARBURST_MAX_FRAG 8 //52 bytes / star
27812780
#else
2782-
#define STARBURST_MAX_FRAG 10
2783-
#define STARBURST_MAX_STARS 11
2781+
#define STARBURST_MAX_FRAG 10 //60 bytes / star
27842782
#endif
2785-
//each needs 18+STARBURST_MAX_FRAG*4 bytes
2783+
//each needs 20+STARBURST_MAX_FRAG*4 bytes
27862784
typedef struct particle {
27872785
CRGB color;
27882786
uint32_t birth =0;
@@ -2793,8 +2791,14 @@ typedef struct particle {
27932791
} star;
27942792

27952793
uint16_t WS2812FX::mode_starburst(void) {
2794+
uint16_t maxData = FAIR_DATA_PER_SEG; //ESP8266: 256 ESP32: 640
2795+
uint8_t segs = getActiveSegmentsNum();
2796+
if (segs <= (MAX_NUM_SEGMENTS /2)) maxData *= 2; //ESP8266: 512 if <= 8 segs ESP32: 1280 if <= 16 segs
2797+
if (segs <= (MAX_NUM_SEGMENTS /4)) maxData *= 2; //ESP8266: 1024 if <= 4 segs ESP32: 2560 if <= 8 segs
2798+
uint16_t maxStars = maxData / sizeof(star); //ESP8266: max. 4/9/19 stars/seg, ESP32: max. 10/21/42 stars/seg
2799+
27962800
uint8_t numStars = 1 + (SEGLEN >> 3);
2797-
if (numStars > STARBURST_MAX_STARS) numStars = STARBURST_MAX_STARS; // 11 * 58 * 32 = 19k (ESP32), 6 * 34 * 18 = 4k (ESP8266)
2801+
if (numStars > maxStars) numStars = maxStars;
27982802
uint16_t dataSize = sizeof(star) * numStars;
27992803

28002804
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
@@ -2902,18 +2906,24 @@ uint16_t WS2812FX::mode_starburst(void) {
29022906
* Exploding fireworks effect
29032907
* adapted from: http://www.anirama.com/1000leds/1d-fireworks/
29042908
*/
2905-
#ifdef ESP8266
2906-
#define MAX_SPARKS 20 // number of fragments
2907-
#else
2908-
#define MAX_SPARKS 58 // number of fragments
2909-
#endif
29102909
uint16_t WS2812FX::mode_exploding_fireworks(void)
29112910
{
29122911
//allocate segment data
2913-
uint16_t numSparks = min(2 + (SEGLEN >> 1), MAX_SPARKS); // max 58 for 32 segment ESP32, 20 for 18 segment ESP8266
2912+
uint16_t maxData = FAIR_DATA_PER_SEG; //ESP8266: 256 ESP32: 640
2913+
uint8_t segs = getActiveSegmentsNum();
2914+
if (segs <= (MAX_NUM_SEGMENTS /2)) maxData *= 2; //ESP8266: 512 if <= 8 segs ESP32: 1280 if <= 16 segs
2915+
if (segs <= (MAX_NUM_SEGMENTS /4)) maxData *= 2; //ESP8266: 1024 if <= 4 segs ESP32: 2560 if <= 8 segs
2916+
int maxSparks = maxData / sizeof(spark); //ESP8266: max. 21/42/85 sparks/seg, ESP32: max. 53/106/213 sparks/seg
2917+
2918+
uint16_t numSparks = min(2 + (SEGLEN >> 1), maxSparks);
29142919
uint16_t dataSize = sizeof(spark) * numSparks;
29152920
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
29162921

2922+
if (dataSize != SEGENV.aux1) { //reset to flare if sparks were reallocated
2923+
SEGENV.aux0 = 0;
2924+
SEGENV.aux1 = dataSize;
2925+
}
2926+
29172927
fill(BLACK);
29182928

29192929
bool actuallyReverse = SEGMENT.getOption(SEG_OPTION_REVERSED);

wled00/FX.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@
6666
#define MAX_SEGMENT_DATA 20480
6767
#endif
6868

69+
/* How much data bytes each segment should max allocate to leave enough space for other segments,
70+
assuming each segment uses the same amount of data. 256 for ESP8266, 640 for ESP32. */
71+
#define FAIR_DATA_PER_SEG (MAX_SEGMENT_DATA / MAX_NUM_SEGMENTS)
72+
6973
#define LED_SKIP_AMOUNT 1
7074
#define MIN_SHOW_DELAY 15
7175

@@ -657,6 +661,7 @@ class WS2812FX {
657661
getModeCount(void),
658662
getPaletteCount(void),
659663
getMaxSegments(void),
664+
getActiveSegmentsNum(void),
660665
//getFirstSelectedSegment(void),
661666
getMainSegmentId(void),
662667
gamma8(uint8_t),

wled00/FX_fcn.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -129,25 +129,20 @@ void WS2812FX::finalizeInit(uint16_t countPixels)
129129

130130
if (autoSegments) {
131131
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) {
132-
_segments[i].start = segStarts[i];
133-
_segments[i].stop = segStops [i];
132+
setSegment(i, segStarts[i], segStops[i]);
134133
}
135134
} else {
136135
//expand the main seg to the entire length, but only if there are no other segments
137136
uint8_t mainSeg = getMainSegmentId();
138-
bool isMultipleSegs = false;
139-
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
140-
{
141-
if (i != mainSeg && _segments[i].isActive()) isMultipleSegs = true;
142-
}
143-
if (!isMultipleSegs) {
144-
_segments[mainSeg].start = 0; _segments[mainSeg].stop = _length;
137+
138+
if (getActiveSegmentsNum() < 2) {
139+
setSegment(mainSeg, 0, _length);
145140
} else {
146141
//there are multiple segments, leave them, but prune length to total
147142
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
148143
{
149-
if (_segments[i].start > _length) _segments[i].stop = 0;
150-
if (_segments[i].stop > _length) _segments[i].stop = _length;
144+
if (_segments[i].start >= _length) setSegment(i, 0, 0);
145+
if (_segments[i].stop > _length) setSegment(i, _segments[i].start, _length);
151146
}
152147
}
153148
}
@@ -545,6 +540,15 @@ uint8_t WS2812FX::getMainSegmentId(void) {
545540
return 0;
546541
}
547542

543+
uint8_t WS2812FX::getActiveSegmentsNum(void) {
544+
uint8_t c = 0;
545+
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
546+
{
547+
if (_segments[i].isActive()) c++;
548+
}
549+
return c;
550+
}
551+
548552
uint32_t WS2812FX::getColor(void) {
549553
return _segments[getMainSegmentId()].colors[0];
550554
}

0 commit comments

Comments
 (0)