Files
crosspoint-reader-mod/chat-summaries/2026-02-19_sleep-double-fast-refresh-summary.md
cottongin dfbc931c14 mod: Phase 1 - bring forward mod-exclusive files with ActivityManager migration
Brings ~55 mod-exclusive files to the upstream-based mod/master-resync branch:

Activities (migrated to new ActivityManager pattern):
- Clock/Time: SetTimeActivity, SetTimezoneOffsetActivity, NtpSyncActivity
- Dictionary: DictionaryDefinitionActivity, DictionarySuggestionsActivity,
  DictionaryWordSelectActivity, LookedUpWordsActivity
- Bookmark: EpubReaderBookmarkSelectionActivity
- Book management: BookManageMenuActivity, EndOfBookMenuActivity
- OPDS: OpdsServerListActivity, OpdsSettingsActivity
- Utility: DirectoryPickerActivity, NumericStepperActivity

Utilities (unchanged):
- BookManager, BookSettings, BookmarkStore, BootNtpSync
- Dictionary, LookupHistory, TimeSync, OpdsServerStore

Libraries: PlaceholderCover, TableData, ChapterXPathIndexer
Scripts: inject_mod_version, generate_book_icon, preview_placeholder_cover
Docs: KOReader sync XPath mapping

Migration changes:
- ActivityWithSubactivity -> Activity base class
- Callback constructors -> finish()/setResult() pattern
- enterNewActivity() -> startActivityForResult()
- Activity::RenderLock&& -> RenderLock&&

These files won't compile yet - they reference mod settings and I18n
strings that will be added in subsequent phases.

Made-with: Cursor
2026-03-07 15:10:00 -05:00

2.1 KiB

Sleep Cover: Double FAST_REFRESH for Dithered Letterbox

Date: 2026-02-19

Task

Apply the "double FAST_REFRESH" technique (proven for inline EPUB images via PR #556) to sleep cover rendering when dithered letterboxing is enabled. This replaces the corruption-prone HALF_REFRESH with two FAST_REFRESH passes through a white intermediate state.

Also reverted the hash-based block dithering workaround back to standard Bayer dithering for all gray ranges, confirming the root cause was HALF_REFRESH rather than the dithering pattern.

Changes Made

src/activities/boot_sleep/SleepActivity.cpp

  • Added USE_SLEEP_DOUBLE_FAST_REFRESH define (set to 1): compile-time toggle for easy A/B testing.
  • Removed bayerCrossesBwBoundary() and hashBlockDither(): These were the HALF_REFRESH crosstalk workaround (2x2 hash blocks for gray 171-254). Removed entirely since double FAST_REFRESH addresses the root cause.
  • Simplified drawLetterboxFill(): Dithered mode now always uses quantizeBayerDither() for all gray ranges -- same algorithm used for non-boundary grays. No more hash/Bayer branching.
  • Modified renderBitmapSleepScreen() BW pass: When dithered letterbox is active and USE_SLEEP_DOUBLE_FAST_REFRESH is enabled:
    1. Clear screen to white + FAST_REFRESH (establishes clean baseline)
    2. Render letterbox fill + cover + FAST_REFRESH (shows actual content)
  • Letterbox fill included in all greyscale passes: Initially skipped to avoid scan coupling, but re-enabled after testing confirmed the double FAST_REFRESH baseline prevents corruption. This ensures the letterbox color matches the cover edge after the greyscale LUT is applied.
  • Standard HALF_REFRESH path preserved for letterbox=none, letterbox=solid, or when define is disabled.

Build

Successfully compiled with pio run (0 errors, 0 warnings).

Testing

Confirmed working on-device -- dithered letterbox renders cleanly without corruption, and letterbox color matches the cover edge including after greyscale layer application.

Commit

0fda903 on branch mod/sleep-screen-tweaks-on-1.1.0-rc-double-fast