Make chunk size variable depending on available heap size
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
#include <HalGPIO.h>
|
#include <HalGPIO.h>
|
||||||
#include <Logging.h>
|
#include <Logging.h>
|
||||||
#include <Utf8.h>
|
#include <Utf8.h>
|
||||||
|
#include <esp_heap_caps.h>
|
||||||
|
|
||||||
#include "FontCacheManager.h"
|
#include "FontCacheManager.h"
|
||||||
|
|
||||||
@@ -33,7 +34,8 @@ void GfxRenderer::begin() {
|
|||||||
panelHeight = display.getDisplayHeight();
|
panelHeight = display.getDisplayHeight();
|
||||||
panelWidthBytes = display.getDisplayWidthBytes();
|
panelWidthBytes = display.getDisplayWidthBytes();
|
||||||
frameBufferSize = display.getBufferSize();
|
frameBufferSize = display.getBufferSize();
|
||||||
bwBufferChunks.assign((frameBufferSize + BW_BUFFER_CHUNK_SIZE - 1) / BW_BUFFER_CHUNK_SIZE, nullptr);
|
bwBufferChunkSize = BW_BUFFER_CHUNK_SIZE;
|
||||||
|
bwBufferChunks.assign((frameBufferSize + bwBufferChunkSize - 1) / bwBufferChunkSize, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GfxRenderer::insertFont(const int fontId, EpdFontFamily font) { fontMap.insert({fontId, font}); }
|
void GfxRenderer::insertFont(const int fontId, EpdFontFamily font) { fontMap.insert({fontId, font}); }
|
||||||
@@ -2037,32 +2039,56 @@ void GfxRenderer::freeBwBufferChunks() {
|
|||||||
* Returns true if buffer was stored successfully, false if allocation failed.
|
* Returns true if buffer was stored successfully, false if allocation failed.
|
||||||
*/
|
*/
|
||||||
bool GfxRenderer::storeBwBuffer() {
|
bool GfxRenderer::storeBwBuffer() {
|
||||||
// Allocate and copy each chunk
|
auto attemptStore = [&](size_t chunkSize) {
|
||||||
|
bwBufferChunks.assign((frameBufferSize + chunkSize - 1) / chunkSize, nullptr);
|
||||||
for (size_t i = 0; i < bwBufferChunks.size(); i++) {
|
for (size_t i = 0; i < bwBufferChunks.size(); i++) {
|
||||||
// Check if any chunks are already allocated
|
|
||||||
if (bwBufferChunks[i]) {
|
if (bwBufferChunks[i]) {
|
||||||
LOG_ERR("GFX", "!! BW buffer chunk %zu already stored - this is likely a bug, freeing chunk", i);
|
LOG_ERR("GFX", "!! BW buffer chunk %zu already stored - this is likely a bug, freeing chunk", i);
|
||||||
free(bwBufferChunks[i]);
|
free(bwBufferChunks[i]);
|
||||||
bwBufferChunks[i] = nullptr;
|
bwBufferChunks[i] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t offset = i * BW_BUFFER_CHUNK_SIZE;
|
const size_t offset = i * chunkSize;
|
||||||
const size_t chunkSize = std::min(BW_BUFFER_CHUNK_SIZE, static_cast<size_t>(frameBufferSize - offset));
|
const size_t allocSize = std::min(chunkSize, static_cast<size_t>(frameBufferSize - offset));
|
||||||
bwBufferChunks[i] = static_cast<uint8_t*>(malloc(chunkSize));
|
bwBufferChunks[i] = static_cast<uint8_t*>(malloc(allocSize));
|
||||||
|
|
||||||
if (!bwBufferChunks[i]) {
|
if (!bwBufferChunks[i]) {
|
||||||
LOG_ERR("GFX", "!! Failed to allocate BW buffer chunk %zu (%zu bytes)", i, chunkSize);
|
const uint32_t freeHeap = esp_get_free_heap_size();
|
||||||
// Free previously allocated chunks
|
const uint32_t contigHeap = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT);
|
||||||
|
LOG_ERR("GFX", "!! Failed to allocate BW buffer chunk %zu (%zu bytes): free=%u contig=%u", i, allocSize,
|
||||||
|
freeHeap, contigHeap);
|
||||||
freeBwBufferChunks();
|
freeBwBufferChunks();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(bwBufferChunks[i], frameBuffer + offset, chunkSize);
|
memcpy(bwBufferChunks[i], frameBuffer + offset, allocSize);
|
||||||
|
}
|
||||||
|
bwBufferChunkSize = chunkSize;
|
||||||
|
LOG_DBG("GFX", "Stored BW buffer in %zu chunks (%zu bytes each)", bwBufferChunks.size(), chunkSize);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (attemptStore(bwBufferChunkSize)) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DBG("GFX", "Stored BW buffer in %zu chunks (%zu bytes each)", bwBufferChunks.size(), BW_BUFFER_CHUNK_SIZE);
|
if (bwBufferChunkSize > 4096) {
|
||||||
|
LOG_INF("GFX", "BW buffer allocation failed with chunk size %zu, retrying with 4096", bwBufferChunkSize);
|
||||||
|
if (attemptStore(4096)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bwBufferChunkSize > 2048) {
|
||||||
|
LOG_INF("GFX", "BW buffer allocation still failed, retrying with 2048");
|
||||||
|
if (attemptStore(2048)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_ERR("GFX", "!! BW buffer storage failed after retrying smaller chunk sizes");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This can only be called if `storeBwBuffer` was called prior to the grayscale render.
|
* This can only be called if `storeBwBuffer` was called prior to the grayscale render.
|
||||||
@@ -2090,8 +2116,8 @@ void GfxRenderer::restoreBwBuffer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < bwBufferChunks.size(); i++) {
|
for (size_t i = 0; i < bwBufferChunks.size(); i++) {
|
||||||
const size_t offset = i * BW_BUFFER_CHUNK_SIZE;
|
const size_t offset = i * bwBufferChunkSize;
|
||||||
const size_t chunkSize = std::min(BW_BUFFER_CHUNK_SIZE, static_cast<size_t>(frameBufferSize - offset));
|
const size_t chunkSize = std::min(bwBufferChunkSize, static_cast<size_t>(frameBufferSize - offset));
|
||||||
memcpy(frameBuffer + offset, bwBufferChunks[i], chunkSize);
|
memcpy(frameBuffer + offset, bwBufferChunks[i], chunkSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ class GfxRenderer {
|
|||||||
uint16_t panelHeight = 0; // set in begin()
|
uint16_t panelHeight = 0; // set in begin()
|
||||||
uint16_t panelWidthBytes = 0; // set in begin()
|
uint16_t panelWidthBytes = 0; // set in begin()
|
||||||
uint32_t frameBufferSize = 0; // set in begin()
|
uint32_t frameBufferSize = 0; // set in begin()
|
||||||
|
size_t bwBufferChunkSize = BW_BUFFER_CHUNK_SIZE;
|
||||||
std::vector<uint8_t*> bwBufferChunks;
|
std::vector<uint8_t*> bwBufferChunks;
|
||||||
std::map<int, EpdFontFamily> fontMap;
|
std::map<int, EpdFontFamily> fontMap;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user