Skip to content

Commit 2aec21a

Browse files
committed
Palette loading optimisation
- fixes #3978 - FX: Firenoise can use selected palette
1 parent ecc9443 commit 2aec21a

4 files changed

Lines changed: 26 additions & 95 deletions

File tree

platformio_override.ini.sample

Lines changed: 0 additions & 65 deletions
This file was deleted.

wled00/FX.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4863,25 +4863,25 @@ uint16_t mode_2Dfirenoise(void) { // firenoise2d. By Andrew Tuline
48634863
SEGMENT.fill(BLACK);
48644864
}
48654865

4866-
uint16_t xscale = SEGMENT.intensity*4;
4867-
uint32_t yscale = SEGMENT.speed*8;
4868-
uint8_t indexx = 0;
4866+
unsigned xscale = SEGMENT.intensity*4;
4867+
unsigned yscale = SEGMENT.speed*8;
4868+
unsigned indexx = 0;
48694869

4870-
SEGPALETTE = CRGBPalette16( CRGB(0,0,0), CRGB(0,0,0), CRGB(0,0,0), CRGB(0,0,0),
4871-
CRGB::Red, CRGB::Red, CRGB::Red, CRGB::DarkOrange,
4872-
CRGB::DarkOrange,CRGB::DarkOrange, CRGB::Orange, CRGB::Orange,
4873-
CRGB::Yellow, CRGB::Orange, CRGB::Yellow, CRGB::Yellow);
4870+
CRGBPalette16 pal = SEGMENT.check1 ? SEGPALETTE : CRGBPalette16(CRGB::Black, CRGB::Black, CRGB::Black, CRGB::Black,
4871+
CRGB::Red, CRGB::Red, CRGB::Red, CRGB::DarkOrange,
4872+
CRGB::DarkOrange,CRGB::DarkOrange, CRGB::Orange, CRGB::Orange,
4873+
CRGB::Yellow, CRGB::Orange, CRGB::Yellow, CRGB::Yellow);
48744874

48754875
for (int j=0; j < cols; j++) {
48764876
for (int i=0; i < rows; i++) {
4877-
indexx = inoise8(j*yscale*rows/255, i*xscale+millis()/4); // We're moving along our Perlin map.
4878-
SEGMENT.setPixelColorXY(j, i, ColorFromPalette(SEGPALETTE, min(i*(indexx)>>4, 255), i*255/cols, LINEARBLEND)); // With that value, look up the 8 bit colour palette value and assign it to the current LED.
4877+
indexx = inoise8(j*yscale*rows/255, i*xscale+strip.now/4); // We're moving along our Perlin map.
4878+
SEGMENT.setPixelColorXY(j, i, ColorFromPalette(pal, min(i*(indexx)>>4, 255U), i*255/cols, LINEARBLEND)); // With that value, look up the 8 bit colour palette value and assign it to the current LED.
48794879
} // for i
48804880
} // for j
48814881

48824882
return FRAMETIME;
48834883
} // mode_2Dfirenoise()
4884-
static const char _data_FX_MODE_2DFIRENOISE[] PROGMEM = "Firenoise@X scale,Y scale;;!;2";
4884+
static const char _data_FX_MODE_2DFIRENOISE[] PROGMEM = "Firenoise@X scale,Y scale,,,,Palette;;!;2;pal=66";
48854885

48864886

48874887
//////////////////////////////

wled00/FX.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
//#define SEGCOLOR(x) strip._segments[strip.getCurrSegmentId()].currentColor(x, strip._segments[strip.getCurrSegmentId()].colors[x])
9292
//#define SEGLEN strip._segments[strip.getCurrSegmentId()].virtualLength()
9393
#define SEGCOLOR(x) strip.segColor(x) /* saves us a few kbytes of code */
94-
#define SEGPALETTE strip._currentPalette
94+
#define SEGPALETTE Segment::getCurrentPalette()
9595
#define SEGLEN strip._virtualSegmentLength /* saves us a few kbytes of code */
9696
#define SPEED_FORMULA_L (5U + (50U*(255U - SEGMENT.speed))/SEGLEN)
9797

@@ -414,6 +414,7 @@ typedef struct Segment {
414414
static uint16_t _usedSegmentData;
415415

416416
// perhaps this should be per segment, not static
417+
static CRGBPalette16 _currentPalette; // palette used for current effect (includes transition, used in color_from_palette())
417418
static CRGBPalette16 _randomPalette; // actual random palette
418419
static CRGBPalette16 _newRandomPalette; // target random palette
419420
static unsigned long _lastPaletteChange; // last random palette change time in millis()
@@ -530,6 +531,7 @@ typedef struct Segment {
530531
static void modeBlend(bool blend) { _modeBlend = blend; }
531532
#endif
532533
static void handleRandomPalette();
534+
inline static const CRGBPalette16 &getCurrentPalette(void) { return Segment::_currentPalette; }
533535

534536
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, uint8_t segId = 255);
535537
bool setColor(uint8_t slot, uint32_t c); //returns true if changed
@@ -567,7 +569,7 @@ typedef struct Segment {
567569
uint8_t currentMode(void);
568570
uint32_t currentColor(uint8_t slot);
569571
CRGBPalette16 &loadPalette(CRGBPalette16 &tgt, uint8_t pal);
570-
CRGBPalette16 &currentPalette(CRGBPalette16 &tgt, uint8_t paletteID);
572+
void setCurrentPalette(void);
571573

572574
// 1D strip
573575
uint16_t virtualLength(void) const;
@@ -693,7 +695,6 @@ class WS2812FX { // 96 bytes
693695
panels(1),
694696
#endif
695697
// semi-private (just obscured) used in effect functions through macros
696-
_currentPalette(CRGBPalette16(CRGB::Black)),
697698
_colors_t{0,0,0},
698699
_virtualSegmentLength(0),
699700
// true private variables
@@ -888,7 +889,6 @@ class WS2812FX { // 96 bytes
888889
// end 2D support
889890

890891
void loadCustomPalettes(void); // loads custom palettes from JSON
891-
CRGBPalette16 _currentPalette; // palette used for current effect (includes transition)
892892
std::vector<CRGBPalette16> customPalettes; // TODO: move custom palettes out of WS2812FX class
893893

894894
// using public variables to reduce code size increase due to inline function getSegment() (with bounds checking)

wled00/FX_fcn.cpp

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ uint16_t Segment::_usedSegmentData = 0U; // amount of RAM all segments use for t
7777
uint16_t Segment::maxWidth = DEFAULT_LED_COUNT;
7878
uint16_t Segment::maxHeight = 1;
7979

80+
CRGBPalette16 Segment::_currentPalette = CRGBPalette16(CRGB::Black);
8081
CRGBPalette16 Segment::_randomPalette = CRGBPalette16(DEFAULT_COLOR);
8182
CRGBPalette16 Segment::_newRandomPalette = CRGBPalette16(DEFAULT_COLOR);
8283
unsigned long Segment::_lastPaletteChange = 0; // perhaps it should be per segment
@@ -201,7 +202,7 @@ void Segment::resetIfRequired() {
201202

202203
CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) {
203204
if (pal < 245 && pal > GRADIENT_PALETTE_COUNT+13) pal = 0;
204-
if (pal > 245 && (strip.customPalettes.size() == 0 || 255U-pal > strip.customPalettes.size()-1)) pal = 0;
205+
if (pal > 245 && (strip.customPalettes.size() == 0 || 255U-pal > strip.customPalettes.size()-1)) pal = 0; // TODO remove strip dependency by moving customPalettes out of strip
205206
//default palette. Differs depending on effect
206207
if (pal == 0) switch (mode) {
207208
case FX_MODE_FIRE_2012 : pal = 35; break; // heat palette
@@ -343,8 +344,8 @@ void Segment::handleTransition() {
343344
// transition progression between 0-65535
344345
uint16_t Segment::progress() {
345346
if (isInTransition()) {
346-
unsigned long timeNow = millis();
347-
if (_t->_dur > 0 && timeNow - _t->_start < _t->_dur) return (timeNow - _t->_start) * 0xFFFFU / _t->_dur;
347+
unsigned diff = millis() - _t->_start;
348+
if (_t->_dur > 0 && diff < _t->_dur) return diff * 0xFFFFU / _t->_dur;
348349
}
349350
return 0xFFFFU;
350351
}
@@ -448,18 +449,17 @@ uint32_t Segment::currentColor(uint8_t slot) {
448449
#endif
449450
}
450451

451-
CRGBPalette16 &Segment::currentPalette(CRGBPalette16 &targetPalette, uint8_t pal) {
452-
loadPalette(targetPalette, pal);
453-
uint16_t prog = progress();
452+
void Segment::setCurrentPalette() {
453+
loadPalette(_currentPalette, palette);
454+
unsigned prog = progress();
454455
if (strip.paletteFade && prog < 0xFFFFU) {
455456
// blend palettes
456457
// there are about 255 blend passes of 48 "blends" to completely blend two palettes (in _dur time)
457458
// minimum blend time is 100ms maximum is 65535ms
458-
uint16_t noOfBlends = ((255U * prog) / 0xFFFFU) - _t->_prevPaletteBlends;
459-
for (int i=0; i<noOfBlends; i++, _t->_prevPaletteBlends++) nblendPaletteTowardPalette(_t->_palT, targetPalette, 48);
460-
targetPalette = _t->_palT; // copy transitioning/temporary palette
459+
unsigned noOfBlends = ((255U * prog) / 0xFFFFU) - _t->_prevPaletteBlends;
460+
for (unsigned i = 0; i < noOfBlends; i++, _t->_prevPaletteBlends++) nblendPaletteTowardPalette(_t->_palT, _currentPalette, 48);
461+
_currentPalette = _t->_palT; // copy transitioning/temporary palette
461462
}
462-
return targetPalette;
463463
}
464464

465465
// relies on WS2812FX::service() to call it max every 8ms or more (MIN_SHOW_DELAY)
@@ -1078,11 +1078,7 @@ uint32_t Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_
10781078
uint8_t paletteIndex = i;
10791079
if (mapping && virtualLength() > 1) paletteIndex = (i*255)/(virtualLength() -1);
10801080
if (!wrap && strip.paletteBlend != 3) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end"
1081-
CRGBPalette16 curPal;
1082-
curPal = currentPalette(curPal, palette);
1083-
//if (isInTransition()) curPal = _t->_palT;
1084-
//else loadPalette(curPal, palette);
1085-
CRGB fastled_col = ColorFromPalette(curPal, paletteIndex, pbri, (strip.paletteBlend == 3)? NOBLEND:LINEARBLEND); // NOTE: paletteBlend should be global
1081+
CRGB fastled_col = ColorFromPalette(_currentPalette, paletteIndex, pbri, (strip.paletteBlend == 3)? NOBLEND:LINEARBLEND); // NOTE: paletteBlend should be global
10861082

10871083
return RGBW32(fastled_col.r, fastled_col.g, fastled_col.b, 0);
10881084
}
@@ -1187,7 +1183,7 @@ void WS2812FX::service() {
11871183
_colors_t[0] = seg.currentColor(0);
11881184
_colors_t[1] = seg.currentColor(1);
11891185
_colors_t[2] = seg.currentColor(2);
1190-
seg.currentPalette(_currentPalette, seg.palette); // we need to pass reference
1186+
seg.setCurrentPalette(); // load actual palette
11911187

11921188
if (!cctFromRgb || correctWB) busses.setSegmentCCT(seg.currentBri(true), correctWB);
11931189
for (int c = 0; c < NUM_COLORS; c++) _colors_t[c] = gamma32(_colors_t[c]);

0 commit comments

Comments
 (0)