mirror of
https://github.com/wled/WLED.git
synced 2025-07-19 08:46:34 +00:00
Effect buffer optimisations
setMode() fix for selecting gap UI error messages
This commit is contained in:
parent
08d9f7d967
commit
6332ee6edb
@ -5292,7 +5292,6 @@ uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams.
|
|||||||
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
|
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
memset(SEGMENT.data, 0, dataSize); // no falling spawns
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
SEGENV.step = 0;
|
SEGENV.step = 0;
|
||||||
}
|
}
|
||||||
|
10
wled00/FX.h
10
wled00/FX.h
@ -543,9 +543,9 @@ typedef struct Segment {
|
|||||||
|
|
||||||
// runtime data functions
|
// runtime data functions
|
||||||
inline uint16_t dataSize(void) const { return _dataLen; }
|
inline uint16_t dataSize(void) const { return _dataLen; }
|
||||||
bool allocateData(size_t len);
|
bool allocateData(size_t len); // allocates effect data buffer in heap and clears it
|
||||||
void deallocateData(void);
|
void deallocateData(void); // deallocates (frees) effect data buffer from heap
|
||||||
void resetIfRequired(void);
|
void resetIfRequired(void); // sets all SEGENV variables to 0 and clears data buffer
|
||||||
/**
|
/**
|
||||||
* Flags that before the next effect is calculated,
|
* Flags that before the next effect is calculated,
|
||||||
* the internal segment state should be reset.
|
* the internal segment state should be reset.
|
||||||
@ -559,8 +559,8 @@ typedef struct Segment {
|
|||||||
void stopTransition(void);
|
void stopTransition(void);
|
||||||
void handleTransition(void);
|
void handleTransition(void);
|
||||||
#ifndef WLED_DISABLE_MODE_BLEND
|
#ifndef WLED_DISABLE_MODE_BLEND
|
||||||
void swapSegenv(tmpsegd_t &tmpSegD);
|
void swapSegenv(tmpsegd_t &tmpSegD); // copies segment data into specifed buffer, if buffer is not a transition buffer, segment data is overwritten from transition buffer
|
||||||
void restoreSegenv(tmpsegd_t &tmpSegD);
|
void restoreSegenv(tmpsegd_t &tmpSegD); // restores segment data from buffer, if buffer is not transition buffer, changed values are copied to transition buffer
|
||||||
#endif
|
#endif
|
||||||
uint16_t progress(void); // transition progression between 0-65535
|
uint16_t progress(void); // transition progression between 0-65535
|
||||||
uint8_t currentBri(bool useCct = false);
|
uint8_t currentBri(bool useCct = false);
|
||||||
|
@ -143,27 +143,28 @@ Segment& Segment::operator= (Segment &&orig) noexcept {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// allocates effect data buffer on heap and initialises (erases) it
|
||||||
bool IRAM_ATTR Segment::allocateData(size_t len) {
|
bool IRAM_ATTR Segment::allocateData(size_t len) {
|
||||||
|
if (len == 0) return false; // nothing to do
|
||||||
if (data && _dataLen >= len) { // already allocated enough (reduce fragmentation)
|
if (data && _dataLen >= len) { // already allocated enough (reduce fragmentation)
|
||||||
if (call == 0) memset(data, 0, len); // erase buffer if called during effect initialisation
|
if (call == 0) memset(data, 0, len); // erase buffer if called during effect initialisation
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//DEBUG_PRINTF("-- Allocating data (%d): %p\n", len, this);
|
//DEBUG_PRINTF("-- Allocating data (%d): %p\n", len, this);
|
||||||
deallocateData();
|
deallocateData(); // if the old buffer was smaller release it first
|
||||||
if (len == 0) return false; // nothing to do
|
|
||||||
if (Segment::getUsedSegmentData() + len > MAX_SEGMENT_DATA) {
|
if (Segment::getUsedSegmentData() + len > MAX_SEGMENT_DATA) {
|
||||||
// not enough memory
|
// not enough memory
|
||||||
DEBUG_PRINT(F("!!! Effect RAM depleted: "));
|
DEBUG_PRINT(F("!!! Effect RAM depleted: "));
|
||||||
DEBUG_PRINTF("%d/%d !!!\n", len, Segment::getUsedSegmentData());
|
DEBUG_PRINTF("%d/%d !!!\n", len, Segment::getUsedSegmentData());
|
||||||
|
errorFlag = ERR_NORAM;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// do not use SPI RAM on ESP32 since it is slow
|
// do not use SPI RAM on ESP32 since it is slow
|
||||||
data = (byte*) malloc(len);
|
data = (byte*)calloc(len, sizeof(byte));
|
||||||
if (!data) { DEBUG_PRINTLN(F("!!! Allocation failed. !!!")); return false; } // allocation failed
|
if (!data) { DEBUG_PRINTLN(F("!!! Allocation failed. !!!")); return false; } // allocation failed
|
||||||
Segment::addUsedSegmentData(len);
|
Segment::addUsedSegmentData(len);
|
||||||
//DEBUG_PRINTF("--- Allocated data (%p): %d/%d -> %p\n", this, len, Segment::getUsedSegmentData(), data);
|
//DEBUG_PRINTF("--- Allocated data (%p): %d/%d -> %p\n", this, len, Segment::getUsedSegmentData(), data);
|
||||||
_dataLen = len;
|
_dataLen = len;
|
||||||
memset(data, 0, len);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +195,7 @@ void IRAM_ATTR Segment::deallocateData() {
|
|||||||
void Segment::resetIfRequired() {
|
void Segment::resetIfRequired() {
|
||||||
if (!reset) return;
|
if (!reset) return;
|
||||||
//DEBUG_PRINTF("-- Segment reset: %p\n", this);
|
//DEBUG_PRINTF("-- Segment reset: %p\n", this);
|
||||||
deallocateData();
|
if (data && _dataLen > 0) memset(data, 0, _dataLen); // prevent heap fragmentation (just erase buffer instead of deallocateData())
|
||||||
next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0;
|
next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0;
|
||||||
reset = false;
|
reset = false;
|
||||||
}
|
}
|
||||||
@ -561,8 +562,10 @@ void Segment::setOption(uint8_t n, bool val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Segment::setMode(uint8_t fx, bool loadDefaults) {
|
void Segment::setMode(uint8_t fx, bool loadDefaults) {
|
||||||
|
// skip reserved
|
||||||
|
while (fx < strip.getModeCount() && strncmp_P("RSVD", strip.getModeData(fx), 4) == 0) fx++;
|
||||||
|
if (fx >= strip.getModeCount()) fx = 0; // set solid mode
|
||||||
// if we have a valid mode & is not reserved
|
// if we have a valid mode & is not reserved
|
||||||
if (fx < strip.getModeCount() && strncmp_P("RSVD", strip.getModeData(fx), 4)) {
|
|
||||||
if (fx != mode) {
|
if (fx != mode) {
|
||||||
#ifndef WLED_DISABLE_MODE_BLEND
|
#ifndef WLED_DISABLE_MODE_BLEND
|
||||||
if (modeBlending) startTransition(strip.getTransition()); // set effect transitions
|
if (modeBlending) startTransition(strip.getTransition()); // set effect transitions
|
||||||
@ -591,7 +594,6 @@ void Segment::setMode(uint8_t fx, bool loadDefaults) {
|
|||||||
stateChanged = true; // send UDP/WS broadcast
|
stateChanged = true; // send UDP/WS broadcast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Segment::setPalette(uint8_t pal) {
|
void Segment::setPalette(uint8_t pal) {
|
||||||
if (pal < 245 && pal > GRADIENT_PALETTE_COUNT+13) pal = 0; // built in palettes
|
if (pal < 245 && pal > GRADIENT_PALETTE_COUNT+13) pal = 0; // built in palettes
|
||||||
|
@ -258,23 +258,8 @@ void BusDigital::setBrightness(uint8_t b) {
|
|||||||
if (_pins[0] == LED_BUILTIN || _pins[1] == LED_BUILTIN) reinit();
|
if (_pins[0] == LED_BUILTIN || _pins[1] == LED_BUILTIN) reinit();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
uint8_t prevBri = _bri;
|
|
||||||
Bus::setBrightness(b);
|
Bus::setBrightness(b);
|
||||||
PolyBus::setBrightness(_busPtr, _iType, b);
|
PolyBus::setBrightness(_busPtr, _iType, b);
|
||||||
/*
|
|
||||||
if (_data) return; // use _buffering this causes ~20% FPS drop
|
|
||||||
|
|
||||||
// must update/repaint every LED in the NeoPixelBus buffer to the new brightness
|
|
||||||
// the only case where repainting is unnecessary is when all pixels are set after the brightness change but before the next show
|
|
||||||
// (which we can't rely on)
|
|
||||||
uint16_t hwLen = _len;
|
|
||||||
if (_type == TYPE_WS2812_1CH_X3) hwLen = NUM_ICS_WS2812_1CH_3X(_len); // only needs a third of "RGB" LEDs for NeoPixelBus
|
|
||||||
for (unsigned i = 0; i < hwLen; i++) {
|
|
||||||
// use 0 as color order, actual order does not matter here as we just update the channel values as-is
|
|
||||||
uint32_t c = restoreColorLossy(PolyBus::getPixelColor(_busPtr, _iType, i, 0), prevBri);
|
|
||||||
PolyBus::setPixelColor(_busPtr, _iType, i, c, 0);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//If LEDs are skipped, it is possible to use the first as a status LED.
|
//If LEDs are skipped, it is possible to use the first as a status LED.
|
||||||
|
@ -345,6 +345,7 @@
|
|||||||
#define ERR_CONCURRENCY 2 // Conurrency (client active)
|
#define ERR_CONCURRENCY 2 // Conurrency (client active)
|
||||||
#define ERR_NOBUF 3 // JSON buffer was not released in time, request cannot be handled at this time
|
#define ERR_NOBUF 3 // JSON buffer was not released in time, request cannot be handled at this time
|
||||||
#define ERR_NOT_IMPL 4 // Not implemented
|
#define ERR_NOT_IMPL 4 // Not implemented
|
||||||
|
#define ERR_NORAM 8 // effect RAM depleted
|
||||||
#define ERR_JSON 9 // JSON parsing failed (input too large?)
|
#define ERR_JSON 9 // JSON parsing failed (input too large?)
|
||||||
#define ERR_FS_BEGIN 10 // Could not init filesystem (no partition?)
|
#define ERR_FS_BEGIN 10 // Could not init filesystem (no partition?)
|
||||||
#define ERR_FS_QUOTA 11 // The FS is full or the maximum file size is reached
|
#define ERR_FS_QUOTA 11 // The FS is full or the maximum file size is reached
|
||||||
|
@ -329,7 +329,6 @@ function openTab(tabI, force = false)
|
|||||||
var timeout;
|
var timeout;
|
||||||
function showToast(text, error = false)
|
function showToast(text, error = false)
|
||||||
{
|
{
|
||||||
if (error) gId('connind').style.backgroundColor = "var(--c-r)";
|
|
||||||
var x = gId('toast');
|
var x = gId('toast');
|
||||||
//if (error) text += '<i class="icons btn-icon" style="transform:rotate(45deg);position:absolute;top:10px;right:0px;" onclick="clearErrorToast(100);"></i>';
|
//if (error) text += '<i class="icons btn-icon" style="transform:rotate(45deg);position:absolute;top:10px;right:0px;" onclick="clearErrorToast(100);"></i>';
|
||||||
x.innerHTML = text;
|
x.innerHTML = text;
|
||||||
@ -342,6 +341,7 @@ function showToast(text, error = false)
|
|||||||
|
|
||||||
function showErrorToast()
|
function showErrorToast()
|
||||||
{
|
{
|
||||||
|
gId('connind').style.backgroundColor = "var(--c-r)";
|
||||||
showToast('Connection to light failed!', true);
|
showToast('Connection to light failed!', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1494,6 +1494,12 @@ function readState(s,command=false)
|
|||||||
if (s.error && s.error != 0) {
|
if (s.error && s.error != 0) {
|
||||||
var errstr = "";
|
var errstr = "";
|
||||||
switch (s.error) {
|
switch (s.error) {
|
||||||
|
case 8:
|
||||||
|
errstr = "Effect RAM depleted!";
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
errstr = "JSON parsing error!";
|
||||||
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
errstr = "Could not mount filesystem!";
|
errstr = "Could not mount filesystem!";
|
||||||
break;
|
break;
|
||||||
|
2742
wled00/html_ui.h
2742
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// version code in format yymmddb (b = daily build)
|
// version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 2312190
|
#define VERSION 2312270
|
||||||
|
|
||||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||||
//#define WLED_USE_MY_CONFIG
|
//#define WLED_USE_MY_CONFIG
|
||||||
|
Loading…
x
Reference in New Issue
Block a user