模拟器新增 RemoDispBus 推流服务端,修复远端取图

This commit is contained in:
2026-09-10 16:28:39 +08:00
parent f209776356
commit 8ee71203f6
7 changed files with 653 additions and 4 deletions
+70
View File
@@ -69,3 +69,73 @@ void *sim_port_get_display(void)
{
return (void *)lv_display_get_default();
}
/*
* 函数功能:读取当前屏幕内容并转换为 1bpp 单色位图(MSB-first)
* 入口参数:buf - 输出缓冲(调用方分配,≥ 宽*高/8 字节)
* buf_size - buf 容量(字节)
* 返回值:0 - 成功,-1 - 失败
* 限定条件:sim_port_init() 已成功;须在 SDL 所属线程(主循环线程)调用
* 函数说明:1. lv_sdl_window_get_renderer 取 SDL 渲染器
* 2. SDL_RenderReadPixels 读回屏幕实际呈现的 ARGB8888 像素
* 3. 按红通道阈值 128 判白(=1/墨)/黑(=0),逐行打包为 1bpp MSB-first
* 窗口模式为 I1+PARTIAL,LVGL 显示缓冲系分块且经 I1→ARGB8888
* 转换,直接读 get_buf_active 不可靠;读回屏幕呈现像素最稳,
* 且完全避开快照离屏重渲染(SDL 驱动下会卡派发循环)
*/
int sim_port_get_screen_mono(uint8_t *buf, uint32_t buf_size)
{
if (buf == NULL) {
return -1;
}
lv_display_t *disp = lv_display_get_default();
if (disp == NULL) {
return -1;
}
int32_t w = lv_display_get_horizontal_resolution(disp);
int32_t h = lv_display_get_vertical_resolution(disp);
if (w <= 0 || h <= 0) {
return -1;
}
uint32_t stride = (uint32_t)(w + 7) / 8u;
uint32_t need = stride * (uint32_t)h;
if (buf_size < need) {
return -1;
}
SDL_Renderer *renderer = (SDL_Renderer *)lv_sdl_window_get_renderer(disp);
if (renderer == NULL) {
return -1;
}
/* 读回屏幕实际呈现的像素(ARGB8888,4 字节/像素) */
uint32_t pitch = (uint32_t)w * 4u;
uint8_t *px = (uint8_t *)SDL_malloc((size_t)w * (size_t)h * 4u);
if (px == NULL) {
return -1;
}
int rc = SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_ARGB8888, px, (int)pitch);
if (rc != 0) {
SDL_free(px);
return -1;
}
/* 先清零(黑像素=0),ARGB8888 内存序 [B,G,R,A],红通道在偏移 2 */
lv_memset(buf, 0, need);
for (int32_t y = 0; y < h; y++) {
const uint8_t *row = px + (size_t)y * (size_t)pitch;
uint8_t *out = buf + (size_t)y * (size_t)stride;
for (int32_t x = 0; x < w; x++) {
if (row[(size_t)x * 4u + 2u] >= 128u) {
out[(uint32_t)x >> 3] |= (uint8_t)(0x80u >> (x & 7));
}
}
}
SDL_free(px);
return 0;
}