@@ -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