Skip to content

Commit

Permalink
Remove global LED buffer in favour of local buffers
Browse files Browse the repository at this point in the history
  • Loading branch information
blazoncek committed Feb 18, 2025
1 parent 2725d88 commit a66437b
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 30 deletions.
2 changes: 1 addition & 1 deletion wled00/FX_fcn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1473,7 +1473,7 @@ void WS2812FX::finalizeInit() {
// analog always has length 1
if (Bus::isPWM(dataType) || Bus::isOnOff(dataType)) count = 1;
prevLen += count;
BusConfig defCfg = BusConfig(dataType, defPin, start, count, DEFAULT_LED_COLOR_ORDER, false, 0, RGBW_MODE_MANUAL_ONLY, 0, useGlobalLedBuffer);
BusConfig defCfg = BusConfig(dataType, defPin, start, count, DEFAULT_LED_COLOR_ORDER, false, 0, RGBW_MODE_MANUAL_ONLY, 0/*, useGlobalLedBuffer*/);
mem += defCfg.memUsage(Bus::isDigital(dataType) && !Bus::is2Pin(dataType) ? digitalCount++ : 0);
if (BusManager::add(defCfg) == -1) break;
}
Expand Down
33 changes: 19 additions & 14 deletions wled00/bus_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ BusDigital::BusDigital(const BusConfig &bc, uint8_t nr)
, _colorOrder(bc.colorOrder)
, _milliAmpsPerLed(bc.milliAmpsPerLed)
, _milliAmpsMax(bc.milliAmpsMax)
, _data(nullptr)
//, _data(nullptr)
{
DEBUGBUS_PRINTLN(F("Bus: Creating digital bus."));
if (!isDigital(bc.type) || !bc.count) { DEBUGBUS_PRINTLN(F("Not digial or empty bus!")); return; }
Expand All @@ -145,10 +145,10 @@ BusDigital::BusDigital(const BusConfig &bc, uint8_t nr)
_hasRgb = hasRGB(bc.type);
_hasWhite = hasWhite(bc.type);
_hasCCT = hasCCT(bc.type);
if (bc.doubleBuffer) {
_data = (uint8_t*)d_calloc(_len, Bus::getNumberOfChannels(_type));
if (!_data) DEBUGBUS_PRINTLN(F("Bus: Buffer allocation failed!"));
}
// if (bc.doubleBuffer) {
// _data = (uint8_t*)d_calloc(_len, Bus::getNumberOfChannels(_type));
// if (!_data) DEBUGBUS_PRINTLN(F("Bus: Buffer allocation failed!"));
// }
uint16_t lenToCreate = bc.count;
if (bc.type == TYPE_WS2812_1CH_X3) lenToCreate = NUM_ICS_WS2812_1CH_3X(bc.count); // only needs a third of "RGB" LEDs for NeoPixelBus
_busPtr = PolyBus::create(_iType, _pins, lenToCreate + _skip, nr);
Expand Down Expand Up @@ -231,7 +231,7 @@ void BusDigital::show() {
uint8_t cctWW = 0, cctCW = 0;
unsigned newBri = estimateCurrentAndLimitBri(); // will fill _milliAmpsTotal (TODO: could use PolyBus::CalcTotalMilliAmpere())
if (newBri < _bri) PolyBus::setBrightness(_busPtr, _iType, newBri); // limit brightness to stay within current limits

/*
if (_data) {
size_t channels = getNumberOfChannels();
int16_t oldCCT = Bus::_cct; // temporarily save bus CCT
Expand Down Expand Up @@ -268,6 +268,7 @@ void BusDigital::show() {
for (int i=1; i<_skip; i++) PolyBus::setPixelColor(_busPtr, _iType, i, 0, _colorOrderMap.getPixelColorOrder(_start, _colorOrder)); // paint skipped pixels black
Bus::_cct = oldCCT;
} else {
*/
if (newBri < _bri) {
unsigned hwLen = _len;
if (_type == TYPE_WS2812_1CH_X3) hwLen = NUM_ICS_WS2812_1CH_3X(_len); // only needs a third of "RGB" LEDs for NeoPixelBus
Expand All @@ -278,8 +279,8 @@ void BusDigital::show() {
PolyBus::setPixelColor(_busPtr, _iType, i, c, 0, (cctCW<<8) | cctWW); // repaint all pixels with new brightness
}
}
}
PolyBus::show(_busPtr, _iType, !_data); // faster if buffer consistency is not important
// }
PolyBus::show(_busPtr, _iType/*, !_data*/); // faster if buffer consistency is not important
// restore bus brightness to its original value
// this is done right after show, so this is only OK if LED updates are completed before show() returns
// or async show has a separate buffer (ESP32 RMT and I2S are ok)
Expand Down Expand Up @@ -310,6 +311,7 @@ void IRAM_ATTR BusDigital::setPixelColor(unsigned pix, uint32_t c) {
if (!_valid) return;
if (hasWhite()) c = autoWhiteCalc(c);
if (Bus::_cct >= 1900) c = colorBalanceFromKelvin(Bus::_cct, c); //color correction from CCT
/*
if (_data) {
size_t offset = pix * getNumberOfChannels();
uint8_t* dataptr = _data + offset;
Expand All @@ -323,6 +325,7 @@ void IRAM_ATTR BusDigital::setPixelColor(unsigned pix, uint32_t c) {
// we need to store CCT value for each pixel (if there is a color correction in play, convert K in CCT ratio)
if (hasCCT()) *dataptr = Bus::_cct >= 1900 ? (Bus::_cct - 1900) >> 5 : (Bus::_cct < 0 ? 127 : Bus::_cct); // TODO: if _cct == -1 we simply ignore it
} else {
*/
if (_reversed) pix = _len - pix -1;
pix += _skip;
unsigned co = _colorOrderMap.getPixelColorOrder(pix+_start, _colorOrder);
Expand All @@ -344,12 +347,13 @@ void IRAM_ATTR BusDigital::setPixelColor(unsigned pix, uint32_t c) {
if (_type == TYPE_WS2812_WWA) c = RGBW32(cctWW, cctCW, 0, W(c));
}
PolyBus::setPixelColor(_busPtr, _iType, pix, c, co, wwcw);
}
// }
}

// returns original color if global buffering is enabled, else returns lossly restored color from bus
uint32_t IRAM_ATTR BusDigital::getPixelColor(unsigned pix) const {
if (!_valid) return 0;
/*
if (_data) {
const size_t offset = pix * getNumberOfChannels();
uint32_t c;
Expand All @@ -360,6 +364,7 @@ uint32_t IRAM_ATTR BusDigital::getPixelColor(unsigned pix) const {
}
return c;
} else {
*/
if (_reversed) pix = _len - pix -1;
pix += _skip;
const unsigned co = _colorOrderMap.getPixelColorOrder(pix+_start, _colorOrder);
Expand All @@ -379,7 +384,7 @@ uint32_t IRAM_ATTR BusDigital::getPixelColor(unsigned pix) const {
c = RGBW32(w, w, 0, w);
}
return c;
}
// }
}

size_t BusDigital::getPins(uint8_t* pinArray) const {
Expand All @@ -389,7 +394,7 @@ size_t BusDigital::getPins(uint8_t* pinArray) const {
}

size_t BusDigital::getBusSize() const {
return sizeof(BusDigital) + (isOk() ? PolyBus::getDataSize(_busPtr, _iType) + (_data ? _len * getNumberOfChannels() : 0) : 0);
return sizeof(BusDigital) + (isOk() ? PolyBus::getDataSize(_busPtr, _iType) /*+ (_data ? _len * getNumberOfChannels() : 0)*/ : 0);
}

void BusDigital::setColorOrder(uint8_t colorOrder) {
Expand Down Expand Up @@ -432,8 +437,8 @@ void BusDigital::begin() {
void BusDigital::cleanup() {
DEBUGBUS_PRINTLN(F("Digital Cleanup."));
PolyBus::cleanup(_busPtr, _iType);
d_free(_data);
_data = nullptr;
// d_free(_data);
// _data = nullptr;
_iType = I_NONE;
_valid = false;
_busPtr = nullptr;
Expand Down Expand Up @@ -803,7 +808,7 @@ size_t BusConfig::memUsage(unsigned nr) const {
if (Bus::isVirtual(type)) {
return sizeof(BusNetwork) + (count * Bus::getNumberOfChannels(type));
} else if (Bus::isDigital(type)) {
return sizeof(BusDigital) + PolyBus::memUsage(count + skipAmount, PolyBus::getI(type, pins, nr)) + doubleBuffer * (count + skipAmount) * Bus::getNumberOfChannels(type);
return sizeof(BusDigital) + PolyBus::memUsage(count + skipAmount, PolyBus::getI(type, pins, nr)) /*+ doubleBuffer * (count + skipAmount) * Bus::getNumberOfChannels(type)*/;
} else if (Bus::isOnOff(type)) {
return sizeof(BusOnOff);
} else {
Expand Down
8 changes: 4 additions & 4 deletions wled00/bus_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ class BusDigital : public Bus {
uint16_t _frequencykHz;
uint8_t _milliAmpsPerLed;
uint16_t _milliAmpsMax;
uint8_t *_data;
//uint8_t *_data;
void *_busPtr;

static uint16_t _milliAmpsTotal; // is overwitten/recalculated on each show()
Expand Down Expand Up @@ -367,19 +367,19 @@ struct BusConfig {
uint8_t autoWhite;
uint8_t pins[5] = {255, 255, 255, 255, 255};
uint16_t frequency;
bool doubleBuffer;
// bool doubleBuffer;
uint8_t milliAmpsPerLed;
uint16_t milliAmpsMax;

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, uint8_t maPerLed=LED_MILLIAMPS_DEFAULT, uint16_t maMax=ABL_MILLIAMPS_DEFAULT)
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,*/ uint8_t maPerLed=LED_MILLIAMPS_DEFAULT, uint16_t maMax=ABL_MILLIAMPS_DEFAULT)
: count(std::max(len,(uint16_t)1))
, start(pstart)
, colorOrder(pcolorOrder)
, reversed(rev)
, skipAmount(skip)
, autoWhite(aw)
, frequency(clock_kHz)
, doubleBuffer(dblBfr)
// , doubleBuffer(dblBfr)
, milliAmpsPerLed(maPerLed)
, milliAmpsMax(maMax)
{
Expand Down
10 changes: 5 additions & 5 deletions wled00/cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
uint8_t cctBlending = hw_led[F("cb")] | Bus::getCCTBlend();
Bus::setCCTBlend(cctBlending);
strip.setTargetFps(hw_led["fps"]); //NOP if 0, default 42 FPS
CJSON(useGlobalLedBuffer, hw_led[F("ld")]);
// CJSON(useGlobalLedBuffer, hw_led[F("ld")]);
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3)
CJSON(useParallelI2S, hw_led[F("prl")]);
#endif
Expand Down Expand Up @@ -198,8 +198,8 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
}
ledType |= refresh << 7; // hack bit 7 to indicate strip requires off refresh

//busConfigs.push_back(std::move(BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode, freqkHz, useGlobalLedBuffer, maPerLed, maMax)));
busConfigs.emplace_back(ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode, freqkHz, useGlobalLedBuffer, maPerLed, maMax);
//busConfigs.push_back(std::move(BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode, freqkHz, /*useGlobalLedBuffer,*/ maPerLed, maMax)));
busConfigs.emplace_back(ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode, freqkHz, /*useGlobalLedBuffer,*/ maPerLed, maMax);
doInit |= INIT_BUS; // finalization done in beginStrip()
if (!Bus::isVirtual(ledType)) s++; // have as many virtual buses as you want
}
Expand Down Expand Up @@ -782,14 +782,14 @@ void serializeConfig() {
JsonObject hw_led = hw.createNestedObject("led");
hw_led[F("total")] = strip.getLengthTotal(); //provided for compatibility on downgrade and per-output ABL
hw_led[F("maxpwr")] = BusManager::ablMilliampsMax();
hw_led[F("ledma")] = 0; // no longer used
// hw_led[F("ledma")] = 0; // no longer used
hw_led["cct"] = strip.correctWB;
hw_led[F("cr")] = strip.cctFromRgb;
hw_led[F("ic")] = cctICused;
hw_led[F("cb")] = Bus::getCCTBlend();
hw_led["fps"] = strip.getTargetFps();
hw_led[F("rgbwm")] = Bus::getGlobalAWMode(); // global auto white mode override
hw_led[F("ld")] = useGlobalLedBuffer;
// hw_led[F("ld")] = useGlobalLedBuffer; // no longer used
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3)
hw_led[F("prl")] = BusManager::hasParallelOutput();
#endif
Expand Down
2 changes: 1 addition & 1 deletion wled00/data/settings_leds.htm
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,7 @@ <h3>Hardware setup</h3>
<div id="prl" class="hide">Use parallel I2S: <input type="checkbox" name="PR"><br></div>
Make a segment for each output: <input type="checkbox" name="MS"><br>
Custom bus start indices: <input type="checkbox" onchange="tglSi(this.checked)" id="si"><br>
Use global LED buffer: <input type="checkbox" name="LD" onchange="UI()"><br>
<!--Use global LED buffer: <input type="checkbox" name="LD" onchange="UI()"><br>-->
<hr class="sml">
<div id="color_order_mapping">
Color Order Override:
Expand Down
4 changes: 2 additions & 2 deletions wled00/set.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
Bus::setCCTBlend(cctBlending);
Bus::setGlobalAWMode(request->arg(F("AW")).toInt());
strip.setTargetFps(request->arg(F("FR")).toInt());
useGlobalLedBuffer = request->hasArg(F("LD"));
//useGlobalLedBuffer = request->hasArg(F("LD"));
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3)
useParallelI2S = request->hasArg(F("PR"));
#endif
Expand Down Expand Up @@ -213,7 +213,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
type |= request->hasArg(rf) << 7; // off refresh override
// 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
busConfigs.emplace_back(type, pins, start, length, colorOrder | (channelSwap<<4), request->hasArg(cv), skip, awmode, freq, useGlobalLedBuffer, maPerLed, maMax);
busConfigs.emplace_back(type, pins, start, length, colorOrder | (channelSwap<<4), request->hasArg(cv), skip, awmode, freq, /*useGlobalLedBuffer,*/ maPerLed, maMax);
busesChanged = true;
}
//doInitBusses = busesChanged; // we will do that below to ensure all input data is processed
Expand Down
4 changes: 2 additions & 2 deletions wled00/wled.h
Original file line number Diff line number Diff line change
Expand Up @@ -407,9 +407,9 @@ 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
#ifdef ESP8266
WLED_GLOBAL bool useGlobalLedBuffer _INIT(false); // double buffering disabled on ESP8266
//WLED_GLOBAL bool useGlobalLedBuffer _INIT(false); // double buffering disabled on ESP8266
#else
WLED_GLOBAL bool useGlobalLedBuffer _INIT(true); // double buffering enabled on ESP32
//WLED_GLOBAL bool useGlobalLedBuffer _INIT(true); // double buffering enabled on ESP32
#ifndef CONFIG_IDF_TARGET_ESP32C3
WLED_GLOBAL bool useParallelI2S _INIT(false); // parallel I2S for ESP32
#endif
Expand Down
2 changes: 1 addition & 1 deletion wled00/xml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
printSetFormValue(settingsScript,PSTR("CB"),Bus::getCCTBlend());
printSetFormValue(settingsScript,PSTR("FR"),strip.getTargetFps());
printSetFormValue(settingsScript,PSTR("AW"),Bus::getGlobalAWMode());
printSetFormCheckbox(settingsScript,PSTR("LD"),useGlobalLedBuffer);
// printSetFormCheckbox(settingsScript,PSTR("LD"),useGlobalLedBuffer);
printSetFormCheckbox(settingsScript,PSTR("PR"),BusManager::hasParallelOutput()); // get it from bus manager not global variable

unsigned sumMa = 0;
Expand Down

0 comments on commit a66437b

Please sign in to comment.