perf(reader): M30 删掉无人消费的下一页预取槽(refill 渲染减半、常驻 −0.69MB)+ 回书架置顶刚读完的书

This commit is contained in:
AskaEth committed 2026-11-10 13:22:35 +08:00
1 parent dc559aa1ac
commit a9638fa59c
5 files changed
+73 -34

No files matched your search

+29 -28
View File
@@ -29,9 +29,10 @@ static int g_reader_active;
static meow_widget *g_canvas;
static int g_pw, g_ph, g_top, g_mx, g_my;
static int g_fs, g_ls;
#define RD_PAGE_CACHE 2
#define RD_PAGE_SLOT_CUR 0
static uint16_t *g_page_buf[RD_PAGE_CACHE]; /* [0]=cur [1]=next(FreeType 页位图;B.1 降 3→2 槽,省 1 页 0.69MB) */
/* M30:只保留当前页位图。原先的 next 预取槽全工程无消费者(翻页走 rd_book_turn + 重渲染
* 当前页,不换槽),每页白渲染一页(真机 ~220ms)+ 常驻 480×720×2B = 0.69MB。 */
static uint16_t *g_page_buf; /* 当前页位图(FreeType/图片路径) */
static int g_page_valid; /* 1=位图内容即当前页(开书 refill 后 on_enter 复用,免二次渲染) */
static int g_has_font; /* 1=FreeType 路径;0=SDK 字库兜底 */
static int g_menu_open;
static int g_ui_open; /* 「界面」排版面板(B) */
@@ -791,9 +792,9 @@ static void reader_canvas_render(meow_widget *w, const meow_theme *th, void *ctx
chapter_name(); /* 每帧同步顶栏/页底章节名(就绪后取章名,否则文件名) */
if (g_book) {
int page = rd_book_current(g_book);
if ((g_has_font || rd_book_is_image(g_book)) && g_page_buf[RD_PAGE_SLOT_CUR]) {
if ((g_has_font || rd_book_is_image(g_book)) && g_page_buf) {
/* 翻页 blit:行拷贝当前页位图 → back_buf(局部脏区由 flush_region 上屏) */
blit_rows(g_page_buf[RD_PAGE_SLOT_CUR], 0, 0, g_ph);
blit_rows(g_page_buf, 0, 0, g_ph);
} else {
rd_book_render_text(g_book, page, reader_draw_line_atlas, NULL);
}
@@ -884,37 +885,35 @@ static void reader_redraw(void)
static void reader_free_page_bufs(void)
{
for (int i = 0; i < RD_PAGE_CACHE; i++) { free(g_page_buf[i]); g_page_buf[i] = NULL; }
free(g_page_buf); g_page_buf = NULL;
g_page_valid = 0;
if (g_anim_old) { free(g_anim_old); g_anim_old = NULL; }
}
/* 分配 FreeType 页位图槽(cur+next 两槽)。已备当前槽则幂等返回(开书/重入共用)。
/* 分配当前页位图。已备则幂等返回(开书/重入共用)。
* 动画快照 g_anim_old 不在此常驻:翻页时懒分配、动画完成即释放(见 turn_animated/anim_done)。
* 分配失败 → g_has_font=0,走字库兜底路径。 */
static void reader_alloc_page_bufs(void)
{
if (!(g_has_font || rd_book_is_image(g_book))) return;
if (g_page_buf[RD_PAGE_SLOT_CUR]) return; /* 已备当前槽(重入)→ 幂等 */
for (int i = 0; i < RD_PAGE_CACHE; i++)
g_page_buf[i] = (uint16_t *)malloc((size_t)g_pw * (size_t)g_ph * 2);
if (!g_page_buf[RD_PAGE_SLOT_CUR]) { reader_free_page_bufs(); g_has_font = 0; }
if (g_page_buf) return; /* 已备(重入)→ 幂等 */
g_page_buf = (uint16_t *)malloc((size_t)g_pw * (size_t)g_ph * 2);
g_page_valid = 0;
if (!g_page_buf) g_has_font = 0;
}
/* 渲染当前页 + 下一预取页到 2 槽缓存(B.1:降 3→2,去 prev 槽;动画档 无/滑动/淡入 R1 默认无)。 */
/* 渲染当前页到位图(M30:不再预渲染下一页——那一槽没有消费者)。 */
static int reader_refill_page(void)
{
if (!g_book) return -1;
if ((g_has_font || rd_book_is_image(g_book)) && g_page_buf[RD_PAGE_SLOT_CUR]) {
if ((g_has_font || rd_book_is_image(g_book)) && g_page_buf) {
uint16_t bg = rgb565(g_page_bg), fg = rgb565(g_page_fg);
int cur = rd_book_current(g_book);
int np = rd_book_pages(g_book);
int slots[RD_PAGE_CACHE] = { cur, cur + 1 };
for (int i = 0; i < RD_PAGE_CACHE; i++) {
int p = slots[i];
if (p >= 0 && p < np) rd_book_render(g_book, p, g_page_buf[i], g_pw * 2, bg, fg);
else for (int y = 0; y < g_ph; y++) /* 空白槽填背景 */
for (int x = 0; x < g_pw; x++) g_page_buf[i][(size_t)y * g_pw + x] = bg;
}
if (cur >= 0 && cur < np) rd_book_render(g_book, cur, g_page_buf, g_pw * 2, bg, fg);
else for (int y = 0; y < g_ph; y++) /* 无页可画:填背景 */
for (int x = 0; x < g_pw; x++) g_page_buf[(size_t)y * g_pw + x] = bg;
g_page_valid = 1;
return 0;
}
return 0; /* 兜底路径:render_text 直绘 */
@@ -924,7 +923,7 @@ static int reader_refill_page(void)
static void reader_anim_update(meow_anim *a, float v, void *ctx)
{
(void)a; (void)ctx;
if (!g_book || !g_anim_old || !g_page_buf[RD_PAGE_SLOT_CUR]) return;
if (!g_book || !g_anim_old || !g_page_buf) return;
int off = (int)(v * g_pw);
int y0 = rect_y0(), y1 = rect_y1();
meow_ui_fill_rect(0, y0, g_pw, y1 - y0, g_page_bg); /* 内容区清底色 */
@@ -932,7 +931,7 @@ static void reader_anim_update(meow_anim *a, float v, void *ctx)
if (g_anim_dir == 1) { old_x = -off; new_x = g_pw - off; } /* 下一页:旧左移/新右入 */
else { old_x = off; new_x = off - g_pw; } /* 上一页:旧右移/新左入 */
blit_rows(g_anim_old, old_x, y0, y1);
blit_rows(g_page_buf[RD_PAGE_SLOT_CUR], new_x, y0, y1);
blit_rows(g_page_buf, new_x, y0, y1);
meow_ui_flush_region(0, y0, g_pw, y1 - y0);
}
static void reader_anim_done(meow_anim *a, int canceled, void *ctx)
@@ -948,7 +947,7 @@ static void reader_turn_animated(int dir)
if (!g_book) return;
if (g_anim) { meow_anim_cancel(g_anim); g_anim = NULL; } /* 取消进行中动画,重开 */
/* 无页位图(atlas 兜底):瞬切 */
if (!(g_has_font || rd_book_is_image(g_book)) || !g_page_buf[RD_PAGE_SLOT_CUR]) {
if (!(g_has_font || rd_book_is_image(g_book)) || !g_page_buf) {
rd_book_turn(g_book, dir);
g_prog_dirty = 1;
reader_refill_page(); reader_redraw(); reader_reflow_persist();
@@ -956,7 +955,7 @@ static void reader_turn_animated(int dir)
}
if (!g_anim_old) g_anim_old = (uint16_t *)malloc((size_t)g_pw * g_ph * 2);
if (!g_anim_old) { rd_book_turn(g_book, dir); g_prog_dirty = 1; reader_refill_page(); reader_redraw(); return; }
memcpy(g_anim_old, g_page_buf[RD_PAGE_SLOT_CUR], (size_t)g_pw * g_ph * 2);
memcpy(g_anim_old, g_page_buf, (size_t)g_pw * g_ph * 2);
rd_book_turn(g_book, dir);
g_prog_dirty = 1;
reader_refill_page();
@@ -1005,7 +1004,7 @@ static void reader_scrub_preview(int page)
meow_ui_text_right(g_pw - 16, fy + 1, ft, 16, g_page_fg);
}
/* 右缘条区清残留(恢复页面内容)再画条 + 预览框;无页位图(字库兜底)则跳过恢复 */
if (g_page_buf[RD_PAGE_SLOT_CUR]) blit_sub(g_page_buf[RD_PAGE_SLOT_CUR], g_pw - 120, y0, 120, y1 - y0);
if (g_page_buf) blit_sub(g_page_buf, g_pw - 120, y0, 120, y1 - y0);
reader_draw_scrub(th);
if (g_show_footer) meow_ui_flush_region(0, g_ph - RD_FOOT_H, g_pw, RD_FOOT_H);
meow_ui_flush_region(g_pw - 120, y0, 120, y1 - y0);
@@ -1092,7 +1091,7 @@ int reader_open(const char *path)
if (g_has_font || rd_book_is_image(g_book)) {
reader_free_page_bufs(); /* 丢弃上一本书的页位图(重开/换书) */
reader_alloc_page_bufs(); /* 重建 cur+next 两槽;g_anim_old 翻页时懒分配 */
reader_alloc_page_bufs(); /* 重建当前页位图;g_anim_old 翻页时懒分配 */
}
/* 复位动画/刮擦/覆盖层状态(跨书) */
@@ -1150,7 +1149,9 @@ static void reader_on_enter(meow_view *v, void *ctx)
g_reader_active = 1;
if (g_book) {
reader_alloc_page_bufs(); /* 离开已释放页位图 → 重建;未释放则幂等返回 */
reader_refill_page();
/* 开书路径 reader_open 已渲染好当前页(g_page_valid=1)→ 这里不再重复渲染;
* 从其它页返回(leave 释放过位图)才 refill。 */
if (!g_page_valid) reader_refill_page();
chapter_name();
}
reader_redraw();
@@ -1159,7 +1160,7 @@ static void reader_on_leave(meow_view *v, void *ctx)
{
(void)v; (void)ctx;
reader_reflow_persist(); /* 离开保存进度 */
reader_free_page_bufs(); /* 离开阅读页释放页位图(cur+next 两槽+动画快照)→ on_enter 重建 */
reader_free_page_bufs(); /* 离开阅读页释放页位图(当前页 + 动画快照)→ on_enter 重建 */
g_reader_active = 0;
}
static void reader_on_destroy(meow_view *v, void *ctx)