Render larger images on demand not by default

This commit is contained in:
jpirnay
2026-05-19 09:28:36 +02:00
parent d4b2a24e2a
commit d922b5a67a
9 changed files with 134 additions and 20 deletions
+3
View File
@@ -267,6 +267,9 @@ class CrossPointSettings {
uint8_t showFileExtensions = 0;
// Image rendering mode in EPUB reader
uint8_t imageRendering = IMAGES_DISPLAY;
// Show a placeholder for large images (>800×600 source pixels) instead of decoding immediately.
// The user can press OK on the placeholder page to decode the image on demand.
uint8_t largeImagePlaceholder = 1;
// Dithering mode for decoded images (EPUB/JPG/PNG)
uint8_t imageDithering = IMAGE_DITHER_BAYER;
// Tilt-based page turning (X3 only — requires QMI8658 IMU)
+2
View File
@@ -139,6 +139,8 @@ inline const std::vector<SettingInfo> list = {
SettingInfo::Enum(StrId::STR_IMAGES, &CrossPointSettings::imageRendering,
{StrId::STR_IMAGES_DISPLAY, StrId::STR_IMAGES_PLACEHOLDER, StrId::STR_IMAGES_SUPPRESS},
"imageRendering", StrId::STR_CAT_READER),
SettingInfo::Toggle(StrId::STR_LARGE_IMAGE_PLACEHOLDER, &CrossPointSettings::largeImagePlaceholder,
"largeImagePlaceholder", StrId::STR_CAT_READER),
SettingInfo::Value(StrId::STR_SCREEN_MARGIN, &CrossPointSettings::screenMargin, {5, 40, 5}, "screenMargin",
StrId::STR_CAT_READER)
.withSubmenu(StrId::STR_MENU_READER_SPACING),
+19 -5
View File
@@ -407,6 +407,12 @@ void EpubReaderActivity::loop() {
return;
}
if (ev.type == ButtonEventManager::PressType::Short) {
if (pageHasPlaceholders) {
forceLoadLargeImages = true;
pageHasPlaceholders = false;
requestUpdate();
return;
}
openReaderMenu();
return;
}
@@ -1512,6 +1518,8 @@ bool EpubReaderActivity::stepPageState(const bool isForwardTurn) {
}
lastPageTurnTime = millis();
forceLoadLargeImages = false;
pageHasPlaceholders = false;
return true;
}
@@ -1868,15 +1876,18 @@ void EpubReaderActivity::renderContents(std::unique_ptr<Page> page, const int or
}
lastRenderStats.textAntiAliasing = aaEnabledForThisRender;
// Force special handling for pages with images when anti-aliasing is on
bool imagePageWithAA = page->hasImages() && aaEnabledForThisRender;
// Force special handling for pages with real (non-placeholder) images when anti-aliasing is on
bool imagePageWithAA = page->hasImages() && !pageHasPlaceholders && aaEnabledForThisRender;
bool forceHalfRefreshThisPage = pendingHalfRefreshAfterImagePage && SETTINGS.halfRefreshAfterImagePage;
pendingHalfRefreshAfterImagePage = false;
lastRenderStats.imagePageWithAA = imagePageWithAA;
lastRenderStats.forcedHalfRefresh = forceHalfRefreshThisPage;
const bool effectiveForceLoad = forceLoadLargeImages || !SETTINGS.largeImagePlaceholder;
pageHasPlaceholders = page->hasPlaceholderImages(effectiveForceLoad);
logReaderMemSnapshot("before_bw_render");
page->render(renderer, getEffectiveReaderFontId(), orientedMarginLeft, contentTop);
page->render(renderer, getEffectiveReaderFontId(), orientedMarginLeft, contentTop, effectiveForceLoad);
renderStatusBar();
if (showTruncatedSectionHintThisRender) {
const int hintX = orientedMarginLeft + 4;
@@ -1912,7 +1923,7 @@ void EpubReaderActivity::renderContents(std::unique_ptr<Page> page, const int or
// Re-render page content to restore images into the blanked area
// Status bar is not re-rendered here to avoid reading stale dynamic values (e.g. battery %)
page->render(renderer, getEffectiveReaderFontId(), orientedMarginLeft, contentTop);
page->render(renderer, getEffectiveReaderFontId(), orientedMarginLeft, contentTop, effectiveForceLoad);
renderer.displayBuffer(HalDisplay::FAST_REFRESH);
} else {
renderer.displayBuffer(HalDisplay::HALF_REFRESH);
@@ -1970,7 +1981,10 @@ void EpubReaderActivity::renderContents(std::unique_ptr<Page> page, const int or
LOG_INF("ERS", "Skipping grayscale/BW-restore for this page (insufficient heap for BW snapshot)");
}
if (page->hasImages() && getEffectiveImageRendering() != CrossPointSettings::IMAGES_SUPPRESS) {
// Only schedule the half-refresh if real images were decoded on this page.
// Placeholder-only pages don't deposit grayscale data that needs settling.
if (page->hasImages() && !pageHasPlaceholders &&
getEffectiveImageRendering() != CrossPointSettings::IMAGES_SUPPRESS) {
pendingHalfRefreshAfterImagePage = true;
}
@@ -109,6 +109,11 @@ class EpubReaderActivity final : public Activity {
unsigned long lastPageTurnTime = 0UL;
unsigned long pageTurnDuration = 0UL;
bool pendingHalfRefreshAfterImagePage = false;
// When true, large images on the current page are decoded instead of shown as placeholders.
// Reset to false on every page turn so the next image page starts with a placeholder again.
bool forceLoadLargeImages = false;
// Set after each render: true if the current page contains at least one placeholder image.
bool pageHasPlaceholders = false;
// Temporary AA suspension when BW snapshot allocation fails under memory pressure.
// Automatically lifted once heap recovers above hysteresis thresholds.
bool antiAliasingSuspendedLowMemory = false;