From 08e2bfe9a2fbe24dd71587fb39b2b6af6176fac2 Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Sat, 18 Mar 2023 18:22:31 +0100 Subject: [PATCH] Scale 2D peek for large matrices. --- wled00/ws.cpp | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/wled00/ws.cpp b/wled00/ws.cpp index c09005bd..9ec06c23 100644 --- a/wled00/ws.cpp +++ b/wled00/ws.cpp @@ -111,9 +111,17 @@ void sendDataWs(AsyncWebSocketClient * client) DEBUG_PRINTF("JSON buffer size: %u for WS request (%u).\n", doc.memoryUsage(), len); size_t heap1 = ESP.getFreeHeap(); + DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap()); + #ifdef ESP8266 + if (len>heap1) { + DEBUG_PRINTLN(F("Out of memory (WS)!")); + return; + } + #endif buffer = ws.makeBuffer(len); // will not allocate correct memory sometimes on ESP8266 #ifdef ESP8266 size_t heap2 = ESP.getFreeHeap(); + DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap()); #else size_t heap2 = 0; // ESP32 variants do not have the same issue and will work without checking heap allocation #endif @@ -148,11 +156,17 @@ bool sendLiveLedsWs(uint32_t wsClient) AsyncWebSocketClient * wsc = ws.client(wsClient); if (!wsc || wsc->queueLength() > 0) return false; //only send if queue free - uint16_t used = strip.getLengthTotal(); - const uint16_t MAX_LIVE_LEDS_WS = strip.isMatrix ? 1024 : 256; - uint16_t n = ((used -1)/MAX_LIVE_LEDS_WS) +1; //only serve every n'th LED if count over MAX_LIVE_LEDS_WS - uint16_t pos = (strip.isMatrix ? 4 : 2); - uint16_t bufSize = pos + (used/n)*3; + size_t used = strip.getLengthTotal(); +#ifdef ESP8266 + const size_t MAX_LIVE_LEDS_WS = 256U; +#else + const size_t MAX_LIVE_LEDS_WS = 1024U; +#endif + size_t n = ((used -1)/MAX_LIVE_LEDS_WS) +1; //only serve every n'th LED if count over MAX_LIVE_LEDS_WS + size_t pos = (strip.isMatrix ? 4 : 2); // start of data + size_t bufSize = pos + (used/n)*3; + size_t skipLines = 0; + AsyncWebSocketMessageBuffer * wsBuf = ws.makeBuffer(bufSize); if (!wsBuf) return false; //out of memory uint8_t* buffer = wsBuf->get(); @@ -163,11 +177,25 @@ bool sendLiveLedsWs(uint32_t wsClient) buffer[1] = 2; //version buffer[2] = Segment::maxWidth; buffer[3] = Segment::maxHeight; + if (Segment::maxWidth * Segment::maxHeight > MAX_LIVE_LEDS_WS*4) { + buffer[2] = Segment::maxWidth/4; + buffer[3] = Segment::maxHeight/4; + skipLines = 3; + } else if (Segment::maxWidth * Segment::maxHeight > MAX_LIVE_LEDS_WS) { + buffer[2] = Segment::maxWidth/2; + buffer[3] = Segment::maxHeight/2; + skipLines = 1; + } } #endif - for (uint16_t i = 0; pos < bufSize -2; i += n) + for (size_t i = 0; pos < bufSize -2; i += n) { +#ifndef WLED_DISABLE_2D + if (strip.isMatrix && skipLines) { + if ((i/Segment::maxWidth)%(skipLines+1)) i += Segment::maxWidth * skipLines; + } +#endif uint32_t c = strip.getPixelColor(i); buffer[pos++] = qadd8(W(c), R(c)); //R, add white channel to RGB channels as a simple RGBW -> RGB map buffer[pos++] = qadd8(W(c), G(c)); //G