fix: address review findings on prewarm gating and gitignore
Revalidate the section under RenderLock before the idle prewarm scan, add a largest-block floor to its heap gate, rebuild the differential baseline when the grayscale scratch allocation fails after an async refresh, and anchor generated-file gitignore patterns to the repo root.
This commit is contained in:
+4
-4
@@ -27,7 +27,7 @@ lib/EpdFont/scripts/output/
|
|||||||
!.claude/skills/
|
!.claude/skills/
|
||||||
/managed_components
|
/managed_components
|
||||||
/.dummy
|
/.dummy
|
||||||
CMakeLists.txt
|
/CMakeLists.txt
|
||||||
dependencies.lock
|
/dependencies.lock
|
||||||
sdkconfig.default
|
/sdkconfig.default
|
||||||
sdkconfig.defaults
|
/sdkconfig.defaults
|
||||||
|
|||||||
@@ -285,20 +285,25 @@ void EpubReaderActivity::loop() {
|
|||||||
constexpr unsigned long IDLE_PREWARM_DEBOUNCE_MS = 400;
|
constexpr unsigned long IDLE_PREWARM_DEBOUNCE_MS = 400;
|
||||||
if (section && !section->isBuilding() && !RenderLock::peek() && renderer.hasFrameBuffer() &&
|
if (section && !section->isBuilding() && !RenderLock::peek() && renderer.hasFrameBuffer() &&
|
||||||
lastRenderCompleteMs != 0 && millis() - lastRenderCompleteMs > IDLE_PREWARM_DEBOUNCE_MS &&
|
lastRenderCompleteMs != 0 && millis() - lastRenderCompleteMs > IDLE_PREWARM_DEBOUNCE_MS &&
|
||||||
ESP.getFreeHeap() > RENDER_MIN_FREE_HEAP &&
|
ESP.getFreeHeap() > RENDER_MIN_FREE_HEAP && ESP.getMaxAllocHeap() > BACKGROUND_BUILD_MIN_MAX_ALLOC &&
|
||||||
(idlePrewarmSpine != currentSpineIndex || idlePrewarmPage != section->currentPage)) {
|
(idlePrewarmSpine != currentSpineIndex || idlePrewarmPage != section->currentPage)) {
|
||||||
idlePrewarmSpine = currentSpineIndex;
|
RenderLock lock; // the page table must not change under the scan
|
||||||
idlePrewarmPage = section->currentPage;
|
// Re-check under the lock: peek() and acquisition are not atomic, so the render
|
||||||
const int nextPage = section->currentPage + 1;
|
// task may have reset/replaced the section or moved the page in between.
|
||||||
if (nextPage < static_cast<int>(section->pageCount)) {
|
if (section && !section->isBuilding() &&
|
||||||
RenderLock lock; // the page table must not change under the scan
|
(idlePrewarmSpine != currentSpineIndex || idlePrewarmPage != section->currentPage)) {
|
||||||
if (const auto p = section->loadPage(nextPage)) {
|
idlePrewarmSpine = currentSpineIndex;
|
||||||
if (auto* fcm = renderer.getFontCacheManager()) {
|
idlePrewarmPage = section->currentPage;
|
||||||
const auto t0 = millis();
|
const int nextPage = section->currentPage + 1;
|
||||||
auto scope = fcm->createPrewarmScope();
|
if (nextPage < static_cast<int>(section->pageCount)) {
|
||||||
p->render(renderer, SETTINGS.getReaderFontId(), 0, 0); // scan only, no pixels
|
if (const auto p = section->loadPage(nextPage)) {
|
||||||
scope.endScanAndPrewarm();
|
if (auto* fcm = renderer.getFontCacheManager()) {
|
||||||
LOG_DBG("ERS", "Idle prewarm: page %d in %lums", nextPage, millis() - t0);
|
const auto t0 = millis();
|
||||||
|
auto scope = fcm->createPrewarmScope();
|
||||||
|
p->render(renderer, SETTINGS.getReaderFontId(), 0, 0); // scan only, no pixels
|
||||||
|
scope.endScanAndPrewarm();
|
||||||
|
LOG_DBG("ERS", "Idle prewarm: page %d in %lums", nextPage, millis() - t0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1526,6 +1531,13 @@ void EpubReaderActivity::renderContents(std::unique_ptr<Page> page, const int or
|
|||||||
renderer.waitRefreshComplete();
|
renderer.waitRefreshComplete();
|
||||||
if (!scratch) {
|
if (!scratch) {
|
||||||
LOG_ERR("ERS", "OOM: grayscale strip scratch (%d bytes); skipping AA this page", gwBytes * STRIP_ROWS);
|
LOG_ERR("ERS", "OOM: grayscale strip scratch (%d bytes); skipping AA this page", gwBytes * STRIP_ROWS);
|
||||||
|
if (overlapRefresh) {
|
||||||
|
// The BW refresh ran the shadow-free async path, so controller RAM's
|
||||||
|
// differential baseline was never rebuilt. Even with AA skipped it must
|
||||||
|
// be re-synced from the intact BW framebuffer, or the next differential
|
||||||
|
// update diffs against stale contents.
|
||||||
|
renderer.cleanupGrayscaleWithFrameBuffer();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Bands may be streamed in any order: X4 windows each via setRamArea,
|
// Bands may be streamed in any order: X4 windows each via setRamArea,
|
||||||
// X3 via PTL.
|
// X3 via PTL.
|
||||||
|
|||||||
Reference in New Issue
Block a user