simplify sheduler logic

* _frametime ensures that effects are not serviced too often
*  MIN_SHOW_DELAY is the minimum allowed FRAMETIME that can be requested by effects
This commit is contained in:
Frank 2024-11-04 20:11:10 +01:00
parent cf1630a94a
commit 029293a086
2 changed files with 5 additions and 11 deletions

View File

@ -47,8 +47,7 @@
#define FRAMETIME_FIXED (1000/WLED_FPS) #define FRAMETIME_FIXED (1000/WLED_FPS)
#define FRAMETIME strip.getFrameTime() #define FRAMETIME strip.getFrameTime()
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) // all ESP32 except -C3(very slow, untested) #if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) // all ESP32 except -C3(very slow, untested)
#define MIN_SHOW_DELAY (max(2, (_frametime*5)/8)) // supports higher framerates and better animation control -- 5/8 = 62% #define MIN_SHOW_DELAY 3 // supports higher framerates and better animation control
// used to initialize for strip attributes:
#else #else
#define MIN_SHOW_DELAY (_frametime < 16 ? 8 : 15) // legacy MIN_SHOW_DELAY - creates more idle loops, but reduces framerates #define MIN_SHOW_DELAY (_frametime < 16 ? 8 : 15) // legacy MIN_SHOW_DELAY - creates more idle loops, but reduces framerates
#endif #endif

View File

@ -1312,20 +1312,15 @@ void WS2812FX::service() {
if (_suspend) return; if (_suspend) return;
unsigned long elapsed = nowUp - _lastServiceShow; unsigned long elapsed = nowUp - _lastServiceShow;
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) if (elapsed < 2) return; // keep wifi alive - no matter if triggered or unlimited
if (elapsed < 2) return; // keep wifi alive if ( !_triggered && (_targetFps != FPS_UNLIMITED)) { // unlimited mode = no frametime
if ( !_triggered && (_targetFps != FPS_UNLIMITED)) { if (elapsed < _frametime) return; // too early for service
if (elapsed < MIN_SHOW_DELAY) return; // WLEDMM too early for service
} }
#else // legacy
if (nowUp - _lastShow < MIN_SHOW_DELAY) return;
#endif
bool doShow = false; bool doShow = false;
_isServicing = true; _isServicing = true;
_segment_index = 0; _segment_index = 0;
unsigned speedLimit = (_targetFps != FPS_UNLIMITED) ? (0.85f * FRAMETIME) : 1; // lower limit for effect frametime
for (segment &seg : _segments) { for (segment &seg : _segments) {
if (_suspend) return; // immediately stop processing segments if suspend requested during service() if (_suspend) return; // immediately stop processing segments if suspend requested during service()
@ -1362,7 +1357,6 @@ void WS2812FX::service() {
// would need to be allocated for each effect and then blended together for each pixel. // would need to be allocated for each effect and then blended together for each pixel.
[[maybe_unused]] uint8_t tmpMode = seg.currentMode(); // this will return old mode while in transition [[maybe_unused]] uint8_t tmpMode = seg.currentMode(); // this will return old mode while in transition
frameDelay = (*_mode[seg.mode])(); // run new/current mode frameDelay = (*_mode[seg.mode])(); // run new/current mode
if (frameDelay < speedLimit) frameDelay = FRAMETIME; // limit effects that want to go faster than target FPS
#ifndef WLED_DISABLE_MODE_BLEND #ifndef WLED_DISABLE_MODE_BLEND
if (modeBlending && seg.mode != tmpMode) { if (modeBlending && seg.mode != tmpMode) {
Segment::tmpsegd_t _tmpSegData; Segment::tmpsegd_t _tmpSegData;
@ -1375,6 +1369,7 @@ void WS2812FX::service() {
Segment::modeBlend(false); // unset semaphore Segment::modeBlend(false); // unset semaphore
} }
#endif #endif
frameDelay = max(frameDelay, unsigned(MIN_SHOW_DELAY)); // limit effects that want to go faster than target FPS
seg.call++; seg.call++;
if (seg.isInTransition() && frameDelay > FRAMETIME) frameDelay = FRAMETIME; // force faster updates during transition if (seg.isInTransition() && frameDelay > FRAMETIME) frameDelay = FRAMETIME; // force faster updates during transition
BusManager::setSegmentCCT(oldCCT); // restore old CCT for ABL adjustments BusManager::setSegmentCCT(oldCCT); // restore old CCT for ABL adjustments