Skip to content

Commit 186dbdd

Browse files
committed
Prevent effect speeding when in transition
1 parent d883c9e commit 186dbdd

2 files changed

Lines changed: 30 additions & 18 deletions

File tree

wled00/FX.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -684,9 +684,10 @@ class Segment {
684684
*/
685685
inline Segment &markForReset() { reset = true; return *this; } // setOption(SEG_OPTION_RESET, true)
686686

687-
void startTransition(uint16_t dur, bool segmentCopy = true); // transition has to start before actual segment values change
688-
uint8_t currentCCT() const; // current segment's CCT (blended while in transition)
689-
uint8_t currentBri() const; // current segment's opacity/brightness (blended while in transition)
687+
void startTransition(uint16_t dur, bool segmentCopy = true); // transition has to start before actual segment values change
688+
uint8_t currentCCT() const; // current segment's CCT (blended while in transition)
689+
uint8_t currentBri() const; // current segment's opacity/brightness (blended while in transition)
690+
bool needsUpdate(unsigned long time) const; // is it time for segment to be updated?
690691

691692
// 1D strip
692693
uint16_t virtualLength() const;

wled00/FX_fcn.cpp

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,12 @@ uint8_t Segment::currentBri() const {
340340
return curBri;
341341
}
342342

343+
bool Segment::needsUpdate(unsigned long time) const {
344+
if (time > next_time) return true;
345+
if (isInTransition() && _t->_oldSegment && time > _t->_oldSegment->next_time) return true;
346+
return false;
347+
}
348+
343349
// pre-calculate drawing parameters for faster access (based on the idea from @softhack007 from MM fork)
344350
// and blends colors and palettes if necessary
345351
// prog is the progress of the transition (0-65535) and is passed to the function as it may be called in the context of old segment
@@ -1244,34 +1250,39 @@ void WS2812FX::service() {
12441250

12451251
if (!seg.isActive()) continue;
12461252

1253+
const bool mustUpdate = _triggered || (doShow && seg.mode == FX_MODE_STATIC);
12471254
// last condition ensures all solid segments are updated at the same time
1248-
if (nowUp > seg.next_time || _triggered || (doShow && seg.mode == FX_MODE_STATIC))
1249-
{
1255+
if (mustUpdate || seg.needsUpdate(nowUp)) {
12501256
doShow = true;
12511257
unsigned frameDelay = FRAMETIME;
12521258

12531259
if (!seg.freeze) { //only run effect function if not frozen
12541260
// Effect blending
12551261
uint16_t prog = seg.progress();
1256-
seg.beginDraw(prog); // set up parameters for get/setPixelColor() (will also blend colors and palette if blend style is FADE)
1257-
_currentSegment = &seg; // set current segment for effect functions (SEGMENT & SEGENV)
1258-
// workaround for on/off transition to respect blending style
1259-
frameDelay = (*_mode[seg.mode])(); // run new/current mode (needed for bri workaround)
1260-
seg.call++;
1262+
// rely on segment's pixel buffer to maintain pixel values if effect function is not called
1263+
if (mustUpdate || nowUp > seg.next_time) {
1264+
seg.beginDraw(prog); // set up parameters for get/setPixelColor() (will also blend colors and palette if blend style is FADE)
1265+
_currentSegment = &seg; // set current segment for effect functions (SEGMENT & SEGENV)
1266+
// workaround for on/off transition to respect blending style
1267+
frameDelay = (*_mode[seg.mode])(); // run new/current mode (needed for bri workaround)
1268+
seg.call++;
1269+
}
12611270
// if segment is in transition and no old segment exists we don't need to run the old mode
12621271
// (blendSegments() takes care of On/Off transitions and clipping)
12631272
Segment *segO = seg.getOldSegment();
12641273
if (segO && segO->isActive() && (seg.mode != segO->mode || transitionStyle != TRANSITION_FADE ||
12651274
(segO->name != seg.name && segO->name && seg.name && strncmp(segO->name, seg.name, WLED_MAX_SEGNAME_LEN) != 0))) {
1266-
Segment::modeBlend(true); // set semaphore for beginDraw() to blend colors and palette
1267-
segO->beginDraw(prog); // set up palette & colors (also sets draw dimensions), parent segment has transition progress
1268-
_currentSegment = segO; // set current segment
1269-
// workaround for on/off transition to respect blending style
1270-
frameDelay = min(frameDelay, (unsigned)(*_mode[segO->mode])()); // run old mode (needed for bri workaround; semaphore!!)
1271-
segO->call++; // increment old mode run counter
1272-
Segment::modeBlend(false); // unset semaphore
1275+
// rely on old segment's pixel buffer to maintain pixel values if effect function is not called
1276+
if (mustUpdate || nowUp > segO->next_time) {
1277+
Segment::modeBlend(true); // set semaphore for beginDraw() to blend colors and palette
1278+
segO->beginDraw(prog); // set up palette & colors (also sets draw dimensions), parent segment has transition progress
1279+
_currentSegment = segO; // set current segment
1280+
// workaround for on/off transition to respect blending style
1281+
frameDelay = min(frameDelay, (unsigned)(*_mode[segO->mode])()); // run old mode (needed for bri workaround; semaphore!!)
1282+
segO->call++; // increment old mode run counter
1283+
Segment::modeBlend(false); // unset semaphore
1284+
}
12731285
}
1274-
if (seg.isInTransition() && frameDelay > FRAMETIME) frameDelay = FRAMETIME; // force faster updates during transition
12751286
}
12761287

12771288
seg.next_time = nowUp + frameDelay;

0 commit comments

Comments
 (0)