Optimize ledstip by disabling unassigned overlays

The current design continuously runs timer loops for all overlays regardless of whether or not any LEDs are actually using the overlay.  Then each overlay function iterates through all configured LED's to apply if needed.

This optimization "looks ahead" and turns off any overlays that are not assigned to any LEDs.  The most optimization is achieved when no overlays are used, and regresses to match the current performance level if every overlay is assigned.
This commit is contained in:
Bruce Luckcuck 2018-02-21 19:44:37 -05:00
parent dbdeb7b445
commit 539cc19c32
2 changed files with 39 additions and 8 deletions

View File

@ -251,6 +251,7 @@ void reevaluateLedConfig(void)
updateLedCount();
updateDimensions();
updateLedRingCounts();
updateRequiredOverlay();
}
// get specialColor by index
@ -1013,6 +1014,7 @@ typedef enum {
} timId_e;
static timeUs_t timerVal[timTimerCount];
static bool requiredTimerLayer[timTimerCount];
// function to apply layer.
// function must replan self using timer pointer
@ -1040,6 +1042,31 @@ static applyLayerFn_timed* layerTable[] = {
[timRing] = &applyLedThrustRingLayer
};
bool isOverlayTypeUsed(ledOverlayId_e overlayType)
{
for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) {
const ledConfig_t *ledConfig = &ledStripConfig()->ledConfigs[ledIndex];
if (ledGetOverlayBit(ledConfig, overlayType)) {
return true;
}
}
return false;
}
void updateRequiredOverlay(void)
{
for (int timID = 0; timID < timTimerCount; timID++) {
requiredTimerLayer[timID] = true;
}
requiredTimerLayer[timBlink] = isOverlayTypeUsed(LED_OVERLAY_BLINK);
requiredTimerLayer[timLarson] = isOverlayTypeUsed(LED_OVERLAY_LARSON_SCANNER);
requiredTimerLayer[timWarning] = isOverlayTypeUsed(LED_OVERLAY_WARNING);
#ifdef USE_VTX_COMMON
requiredTimerLayer[timVtx] = isOverlayTypeUsed(LED_OVERLAY_VTX);
#endif
requiredTimerLayer[timIndicator] = isOverlayTypeUsed(LED_OVERLAY_INDICATOR);
}
void ledStripUpdate(timeUs_t currentTimeUs)
{
if (!(ledStripInitialised && isWS2811LedStripReady())) {
@ -1060,14 +1087,16 @@ void ledStripUpdate(timeUs_t currentTimeUs)
// test all led timers, setting corresponding bits
uint32_t timActive = 0;
for (timId_e timId = 0; timId < timTimerCount; timId++) {
// sanitize timer value, so that it can be safely incremented. Handles inital timerVal value.
const timeDelta_t delta = cmpTimeUs(now, timerVal[timId]);
// max delay is limited to 5s
if (delta < 0 && delta > -MAX_TIMER_DELAY)
continue; // not ready yet
timActive |= 1 << timId;
if (delta >= 100 * 1000 || delta < 0) {
timerVal[timId] = now;
if (requiredTimerLayer[timId]) {
// sanitize timer value, so that it can be safely incremented. Handles inital timerVal value.
const timeDelta_t delta = cmpTimeUs(now, timerVal[timId]);
// max delay is limited to 5s
if (delta < 0 && delta > -MAX_TIMER_DELAY)
continue; // not ready yet
timActive |= 1 << timId;
if (delta >= 100 * 1000 || delta < 0) {
timerVal[timId] = now;
}
}
}

View File

@ -187,3 +187,5 @@ void applyDefaultLedStripConfig(ledConfig_t *ledConfig);
void applyDefaultColors(hsvColor_t *colors);
void applyDefaultModeColors(modeColorIndexes_t *modeColors);
void applyDefaultSpecialColors(specialColorIndexes_t *specialColors);
void updateRequiredOverlay(void);