fix: BookInfo performance — Y-culling, newline normalization, cover clamping
Addressed critical render performance issues identified via device debug log: - Add Y-culling in render() to skip off-screen draw calls (was causing 337K LOG_ERR calls per frame, 7-13s render times) - Normalize description whitespace (strip embedded \n/\r/\t) to prevent "No glyph for codepoint 10" errors - Clamp cover bitmap maxHeight to prevent drawing beyond screen edge - Pre-compute layout in onEnter() with InfoField struct (wrappedText called once, not per frame) - Add cover image display via generateThumbBmp + drawBitmap1Bit Made-with: Cursor
This commit is contained in:
38
chat-summaries/2026-03-09_00-44-summary.md
Normal file
38
chat-summaries/2026-03-09_00-44-summary.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# BookInfoActivity: Performance Fix and Cover Image
|
||||
|
||||
## Task
|
||||
Fix BookInfoActivity sluggishness (slow open, unresponsive scrolling) and add book cover display.
|
||||
|
||||
## Root Cause (from device debug log)
|
||||
1. **No Y-culling in render()**: All text lines drawn even when off-screen. Content extending ~1162px on 800px screen caused hundreds of thousands of `LOG_ERR("Outside range")` calls per frame, each doing serial I/O. Render times: 7-13 seconds per frame.
|
||||
2. **Description text contained literal newlines**: `stripHtml()` and `trim()` in ContentOpfParser don't replace interior `\n` characters. These got passed to `drawText()`, triggering "No glyph for codepoint 10" errors.
|
||||
3. **`wrappedText()` recomputed every frame**: Original render called it for every field on every scroll -- now pre-computed once.
|
||||
4. **No cover image**: Activity never loaded or displayed any cover.
|
||||
|
||||
## Changes Made
|
||||
|
||||
### Committed first: PR #1342 port (commit 4cf395a)
|
||||
- Staged and committed all prior working state before making further changes
|
||||
|
||||
### BookInfoActivity refactor (2 files)
|
||||
|
||||
**`src/activities/home/BookInfoActivity.h`**:
|
||||
- Replaced individual metadata string members with `InfoField` struct + `std::vector<InfoField> fields`
|
||||
- Added `coverBmpPath`, `coverDisplayHeight`, `coverDisplayWidth` members
|
||||
- Added `buildLayout()` method for pre-computation
|
||||
|
||||
**`src/activities/home/BookInfoActivity.cpp`**:
|
||||
- **Y-culling**: `render()` skips draw calls for items entirely above or below the visible screen area (`y + height > 0 && y < pageH`); breaks out of field loop when `y >= pageH`
|
||||
- **Newline normalization**: Added `normalizeWhitespace()` helper that collapses `\n`, `\r`, `\t` sequences into single spaces; applied to description text before word-wrapping
|
||||
- **Cover height clamping**: `drawBitmap1Bit` maxHeight capped to `std::min(coverDisplayHeight, pageH - y)` to prevent drawing beyond screen
|
||||
- **Pre-computed layout**: All `wrappedText()` calls moved to `onEnter()` via `buildLayout()`; `render()` only iterates pre-computed lines
|
||||
- Cover thumbnail generated via `epub.generateThumbBmp()` / `xtc.generateThumbBmp()`; fallback to `PlaceholderCoverGenerator`
|
||||
- Cover rendered centered at top using `renderer.drawBitmap1Bit()`
|
||||
|
||||
## Build Verification
|
||||
- `pio run` SUCCESS (19s incremental, RAM 30.3%, Flash 95.7%)
|
||||
|
||||
## Follow-up Items
|
||||
- Hardware test: verify render times dropped from 7-13s to <100ms with Y-culling
|
||||
- Hardware test: verify cover image renders correctly
|
||||
- Hardware test: verify scroll responsiveness on device
|
||||
Reference in New Issue
Block a user