perf: shrink HomeActivity cover cache from 48KB framebuffer to 16KB region (#2035)

On-device repro showed the cover snapshot pinning ~52KB of contiguous
heap (cloning the full 48KB framebuffer with malloc overhead). MaxAlloc
on Home was 61KB; nothing was leaving headroom for HTTPS, which needs
30-50KB contiguous for the mbedTLS handshake.

Add region-aware framebuffer helpers to GfxRenderer that translate a
logical rect through rotateCoordinates and copy only the byte range that
contains the rotated rect. HomeActivity records the tile rect it passes
to drawRecentBookCover and caches only that subregion.

Measured on device (X3, Portrait):

  Idle on Home    | Free 102K -> 139K  | MaxAlloc 61K -> 115K
  Mid-EPUB-read   | Free  81K -> 134K  | MaxAlloc 70K -> 115K
  Cover cache     |        ~52K -> ~16K (per allocation)

Works in all four orientations because the bounds helper samples the
four logical corners through the existing rotation, so the cached byte
range always covers the pixels the theme could have drawn into.

Savings will vary with theme, but should be significant across all.
This commit is contained in:
Jeremy Klein
2026-05-18 22:41:02 -04:00
committed by GitHub
parent a525606d7f
commit a14c8e762d
4 changed files with 128 additions and 23 deletions
+12
View File
@@ -185,4 +185,16 @@ class GfxRenderer {
uint16_t getDisplayWidth() const { return panelWidth; }
uint16_t getDisplayHeight() const { return panelHeight; }
uint16_t getDisplayWidthBytes() const { return panelWidthBytes; }
// Region cache: take a logical (orientation-aware) rect, hit the framebuffer
// bytes that the rect can have touched, and pump them in or out of a caller-
// supplied buffer. Used by HomeActivity to snapshot just the cover tile
// (~16 KB in Portrait) instead of cloning the entire 48 KB framebuffer.
//
// getRegionByteSize: required buffer length for the rect at current orientation.
// copyRegionToBuffer / copyBufferToRegion: false if `bufSize` is smaller than that.
size_t getRegionByteSize(int logicalX, int logicalY, int logicalW, int logicalH) const;
bool copyRegionToBuffer(int logicalX, int logicalY, int logicalW, int logicalH, uint8_t* buf, size_t bufSize) const;
bool copyBufferToRegion(int logicalX, int logicalY, int logicalW, int logicalH, const uint8_t* buf,
size_t bufSize) const;
};