From 59a144baedf47a9e5ccd8479b92a18f643ce0bd9 Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Wed, 5 Jul 2023 23:57:46 +0200 Subject: [PATCH] Disable global buffer on ESP8266 by default Remove global dependency from Bus class and subclasses Remove timings --- wled00/FX_fcn.cpp | 6 ++++++ wled00/bus_manager.cpp | 15 ++++++++++----- wled00/bus_manager.h | 8 +++++--- wled00/cfg.cpp | 4 ++-- wled00/set.cpp | 2 +- wled00/wled.cpp | 31 ------------------------------- wled00/wled.h | 8 ++++++-- 7 files changed, 30 insertions(+), 44 deletions(-) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index e3256134..3c009592 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -1219,9 +1219,11 @@ uint8_t WS2812FX::estimateCurrentAndLimitBri() { } void WS2812FX::show(void) { + #ifdef WLED_DEBUG static unsigned long sumMicros = 0, sumCurrent = 0; static size_t calls = 0; unsigned long microsStart = micros(); + #endif // avoid race condition, caputre _callback value show_callback callback = _callback; @@ -1229,7 +1231,9 @@ void WS2812FX::show(void) { uint8_t busBrightness = estimateCurrentAndLimitBri(); busses.setBrightness(busBrightness); + #ifdef WLED_DEBUG sumCurrent += micros() - microsStart; + #endif // some buses send asynchronously and this method will return before // all of the data has been sent. @@ -1242,12 +1246,14 @@ void WS2812FX::show(void) { _cumulativeFps = (3 * _cumulativeFps + fpsCurr) >> 2; _lastShow = now; + #ifdef WLED_DEBUG sumMicros += micros() - microsStart; if (++calls == 100) { DEBUG_PRINTF("show calls: %d micros: %lu avg: %lu (current: %lu avg: %lu)\n", calls, sumMicros, sumMicros/calls, sumCurrent, sumCurrent/calls); sumMicros = sumCurrent = 0; calls = 0; } + #endif } /** diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index 4883fff1..24c2ea40 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -116,7 +116,8 @@ BusDigital::BusDigital(BusConfig &bc, uint8_t nr, const ColorOrderMap &com) : Bu _colorOrder = bc.colorOrder; _iType = PolyBus::getI(bc.type, _pins, nr); if (_iType == I_NONE) return; - if (useGlobalLedBuffer && !allocData(_len * (Bus::hasWhite(_type) + 3*Bus::hasRGB(_type)))) return; //warning: hardcoded channel count + if (bc.doubleBuffer && !allocData(_len * (Bus::hasWhite(_type) + 3*Bus::hasRGB(_type)))) return; //warning: hardcoded channel count + buffering = bc.doubleBuffer; uint16_t lenToCreate = _len; if (bc.type == TYPE_WS2812_1CH_X3) lenToCreate = NUM_ICS_WS2812_1CH_3X(_len); // only needs a third of "RGB" LEDs for NeoPixelBus _busPtr = PolyBus::create(_iType, _pins, lenToCreate + _skip, nr, _frequencykHz); @@ -126,11 +127,13 @@ BusDigital::BusDigital(BusConfig &bc, uint8_t nr, const ColorOrderMap &com) : Bu void BusDigital::show() { if (!_valid) return; + #ifdef WLED_DEBUG static unsigned long sumMicros = 0; static size_t calls = 0; unsigned long microsStart = micros(); + #endif PolyBus::setBrightness(_busPtr, _iType, _bri); - if (useGlobalLedBuffer) { + if (buffering) { // should be _data != nullptr, but that causes ~20% FPS drop size_t channels = Bus::hasWhite(_type) + 3*Bus::hasRGB(_type); for (size_t i=0; i<_len; i++) { size_t offset = i*channels; @@ -155,12 +158,14 @@ void BusDigital::show() { } PolyBus::show(_busPtr, _iType); PolyBus::setBrightness(_busPtr, _iType, 255); // restore full brightness at bus level (setting unscaled pixel color) + #ifdef WLED_DEBUG sumMicros += micros() - microsStart; if (++calls == 100) { DEBUG_PRINTF("Bus calls: %d micros: %lu avg: %lu\n", calls, sumMicros, sumMicros/calls); sumMicros = 0; calls = 0; } + #endif } bool BusDigital::canShow() { @@ -191,7 +196,7 @@ void IRAM_ATTR BusDigital::setPixelColor(uint16_t pix, uint32_t c) { if (!_valid) return; if (Bus::hasWhite(_type)) c = autoWhiteCalc(c); if (_cct >= 1900) c = colorBalanceFromKelvin(_cct, c); //color correction from CCT - if (useGlobalLedBuffer) { + if (buffering) { // should be _data != nullptr, but that causes ~20% FPS drop size_t channels = Bus::hasWhite(_type) + 3*Bus::hasRGB(_type); size_t offset = pix*channels; if (Bus::hasRGB(_type)) { @@ -220,7 +225,7 @@ void IRAM_ATTR BusDigital::setPixelColor(uint16_t pix, uint32_t c) { uint32_t BusDigital::getPixelColor(uint16_t pix) { if (!_valid) return 0; - if (useGlobalLedBuffer) { + if (buffering) { // should be _data != nullptr, but that causes ~20% FPS drop size_t channels = Bus::hasWhite(_type) + 3*Bus::hasRGB(_type); size_t offset = pix*channels; uint32_t c; @@ -272,7 +277,7 @@ void BusDigital::cleanup() { _iType = I_NONE; _valid = false; _busPtr = nullptr; - if (useGlobalLedBuffer) freeData(); + if (_data != nullptr) freeData(); pinManager.deallocatePin(_pins[1], PinOwner::BusDigital); pinManager.deallocatePin(_pins[0], PinOwner::BusDigital); } diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index fe9690c7..7f138cc0 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -34,10 +34,11 @@ struct BusConfig { uint8_t autoWhite; uint8_t pins[5] = {LEDPIN, 255, 255, 255, 255}; uint16_t frequency; - BusConfig(uint8_t busType, uint8_t* ppins, uint16_t pstart, uint16_t len = 1, uint8_t pcolorOrder = COL_ORDER_GRB, bool rev = false, uint8_t skip = 0, byte aw=RGBW_MODE_MANUAL_ONLY, uint16_t clock_kHz=0U) { + bool doubleBuffer; + BusConfig(uint8_t busType, uint8_t* ppins, uint16_t pstart, uint16_t len = 1, uint8_t pcolorOrder = COL_ORDER_GRB, bool rev = false, uint8_t skip = 0, byte aw=RGBW_MODE_MANUAL_ONLY, uint16_t clock_kHz=0U, bool dblBfr=false) { refreshReq = (bool) GET_BIT(busType,7); type = busType & 0x7F; // bit 7 may be/is hacked to include refresh info (1=refresh in off state, 0=no refresh) - count = len; start = pstart; colorOrder = pcolorOrder; reversed = rev; skipAmount = skip; autoWhite = aw; frequency = clock_kHz; + count = len; start = pstart; colorOrder = pcolorOrder; reversed = rev; skipAmount = skip; autoWhite = aw; frequency = clock_kHz; doubleBuffer = dblBfr; uint8_t nPins = 1; if (type >= TYPE_NET_DDP_RGB && type < 96) nPins = 4; //virtual network bus. 4 "pins" store IP address else if (type > 47) nPins = 2; @@ -181,7 +182,7 @@ class Bus { uint32_t autoWhiteCalc(uint32_t c); uint8_t *allocData(size_t size = 1); - void freeData() { if (_data) free(_data); _data = nullptr; } + void freeData() { if (_data != nullptr) free(_data); _data = nullptr; } }; @@ -235,6 +236,7 @@ class BusDigital : public Bus { uint16_t _frequencykHz = 0U; void * _busPtr = nullptr; const ColorOrderMap &_colorOrderMap; + bool buffering = false; // temporary until we figure out why comparison "_data != nullptr" causes severe FPS drop inline uint32_t restoreColorLossy(uint32_t c, uint_fast8_t _restaurationBri) { if (_bri == 255) return c; diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 6c2e9422..6730fe5f 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -161,7 +161,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { ledType |= refresh << 7; // hack bit 7 to indicate strip requires off refresh uint8_t AWmode = elm[F("rgbwm")] | autoWhiteMode; if (fromFS) { - BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode, freqkHz); + BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode, freqkHz, useGlobalLedBuffer); mem += BusManager::memUsage(bc); if (useGlobalLedBuffer && start + length > maxlen) { maxlen = start + length; @@ -170,7 +170,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { if (mem + globalBufMem <= MAX_LED_MEMORY) if (busses.add(bc) == -1) break; // finalization will be done in WLED::beginStrip() } else { if (busConfigs[s] != nullptr) delete busConfigs[s]; - busConfigs[s] = new BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode); + busConfigs[s] = new BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode, freqkHz, useGlobalLedBuffer); busesChanged = true; } s++; diff --git a/wled00/set.cpp b/wled00/set.cpp index 3420f22c..fb3e40c2 100644 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -153,7 +153,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) // actual finalization is done in WLED::loop() (removing old busses and adding new) // this may happen even before this loop is finished so we do "doInitBusses" after the loop if (busConfigs[s] != nullptr) delete busConfigs[s]; - busConfigs[s] = new BusConfig(type, pins, start, length, colorOrder | (channelSwap<<4), request->hasArg(cv), skip, awmode, freqHz); + busConfigs[s] = new BusConfig(type, pins, start, length, colorOrder | (channelSwap<<4), request->hasArg(cv), skip, awmode, freqHz, useGlobalLedBuffer); busesChanged = true; } //doInitBusses = busesChanged; // we will do that below to ensure all input data is processed diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 8f80b89f..83a79358 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -35,19 +35,12 @@ void WLED::reset() void WLED::loop() { #ifdef WLED_DEBUG - static unsigned serviceCount = 0; static unsigned long maxUsermodMillis = 0; static size_t avgUsermodMillis = 0; static unsigned long maxStripMillis = 0; static size_t avgStripMillis = 0; - static size_t avgHandlingMillis = 0; - static size_t avgHandling2Millis = 0; - static size_t avgHandling3Millis = 0; #endif - #ifdef WLED_DEBUG - unsigned long handlingMillis = millis(); - #endif handleTime(); #ifndef WLED_DISABLE_INFRARED handleIR(); // 2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too @@ -60,10 +53,6 @@ void WLED::loop() #ifdef WLED_ENABLE_DMX handleDMX(); #endif - #ifdef WLED_DEBUG - handlingMillis = millis() - handlingMillis; - avgHandlingMillis += handlingMillis; - #endif userLoop(); #ifdef WLED_DEBUG @@ -76,9 +65,6 @@ void WLED::loop() if (usermodMillis > maxUsermodMillis) maxUsermodMillis = usermodMillis; #endif - #ifdef WLED_DEBUG - unsigned long handling2Millis = millis(); - #endif yield(); handleIO(); #ifndef WLED_DISABLE_INFRARED @@ -87,10 +73,6 @@ void WLED::loop() #ifndef WLED_DISABLE_ALEXA handleAlexa(); #endif - #ifdef WLED_DEBUG - handling2Millis = millis() - handling2Millis; - avgHandling2Millis += handling2Millis; - #endif if (doCloseFile) { closeFile(); @@ -195,16 +177,9 @@ void WLED::loop() yield(); if (doSerializeConfig) serializeConfig(); - #ifdef WLED_DEBUG - unsigned long handling3Millis = millis(); - #endif yield(); handleWs(); handleStatusLED(); - #ifdef WLED_DEBUG - handling3Millis = millis() - handling3Millis; - avgHandling3Millis += handling3Millis; - #endif // DEBUG serial logging (every 30s) #ifdef WLED_DEBUG @@ -232,9 +207,6 @@ void WLED::loop() DEBUG_PRINT(F("Loops/sec: ")); DEBUG_PRINTLN(loops / 30); DEBUG_PRINT(F("UM time[ms]: ")); DEBUG_PRINT(avgUsermodMillis/loops); DEBUG_PRINT("/");DEBUG_PRINTLN(maxUsermodMillis); DEBUG_PRINT(F("Strip time[ms]: ")); DEBUG_PRINT(avgStripMillis/loops); DEBUG_PRINT("/"); DEBUG_PRINTLN(maxStripMillis); - DEBUG_PRINT(F("Handling 1 time[ms]: ")); DEBUG_PRINTLN(avgHandlingMillis/loops); - DEBUG_PRINT(F("Handling 2 time[ms]: ")); DEBUG_PRINTLN(avgHandling2Millis/loops); - DEBUG_PRINT(F("Handling 3 time[ms]: ")); DEBUG_PRINTLN(avgHandling3Millis/loops); } strip.printSize(); loops = 0; @@ -242,9 +214,6 @@ void WLED::loop() maxStripMillis = 0; avgUsermodMillis = 0; avgStripMillis = 0; - avgHandlingMillis = 0; - avgHandling2Millis = 0; - avgHandling3Millis = 0; debugTime = millis(); } loops++; diff --git a/wled00/wled.h b/wled00/wled.h index 2d6d5b54..28b11a06 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2307020 +#define VERSION 2307050 //uncomment this if you have a "my_config.h" file you'd like to use //#define WLED_USE_MY_CONFIG @@ -332,7 +332,11 @@ WLED_GLOBAL byte bootPreset _INIT(0); // save preset to load //if false, only one segment spanning the total LEDs is created, //but not on LED settings save if there is more than one segment currently WLED_GLOBAL bool autoSegments _INIT(false); -WLED_GLOBAL bool useGlobalLedBuffer _INIT(true); +#ifdef ESP8266 +WLED_GLOBAL bool useGlobalLedBuffer _INIT(false); // double buffering disabled on ESP8266 +#else +WLED_GLOBAL bool useGlobalLedBuffer _INIT(true); // double buffering enabled on ESP32 +#endif WLED_GLOBAL bool correctWB _INIT(false); // CCT color correction of RGB color WLED_GLOBAL bool cctFromRgb _INIT(false); // CCT is calculated from RGB instead of using seg.cct WLED_GLOBAL bool gammaCorrectCol _INIT(true); // use gamma correction on colors