Forráskód Böngészése

update: sdl2, 更新sdl2事件泵更新由tp定时器自动维护,并将事件队列提升到64.

zengeshuai 2 hónapja
szülő
commit
522c0dc862

+ 39 - 2
bsp/pc/port/driver/luat_tp_pc.c

@@ -3,6 +3,8 @@
 #include "luat_tp.h"
 #include "luat_mem.h"
 #include "luat_mcu.h"
+#include "luat_rtos.h"
+#include "luat_sdl2.h"
 
 #include "uv.h"
 
@@ -11,6 +13,8 @@
 #define LUAT_LOG_TAG "tp_pc"
 #include "luat_log.h"
 
+#define TP_PC_FLUSH_INTERVAL_MS 30
+
 // 前置声明
 static int luat_tp_pc_init(luat_tp_config_t* conf);
 static int luat_tp_pc_read(luat_tp_config_t* conf, uint8_t* data);
@@ -36,14 +40,42 @@ typedef struct tp_pc_state
 
     // 队列机制 - 新增
     uint8_t event_queue_size; // 事件队列大小
-    luat_tp_data_t event_queue[8]; // 事件队列,最多保存8个事件
+    luat_tp_data_t event_queue[64]; // 事件队列,最多保存64个事件
     uint8_t queue_head; // 队列头
     uint8_t queue_tail; // 队列尾
     uint8_t queue_enabled; // 是否启用队列机制
+    luat_rtos_timer_t flush_timer; // SDL 事件泵刷新定时器,PC 平台专属
 } tp_pc_state_t;
 
 static tp_pc_state_t s_tp_state;
 
+static LUAT_RT_RET_TYPE tp_flush_timer_cb(LUAT_RT_CB_PARAM) {
+    // 定时调用 SDL2 flush 保持事件泵活跃,即使界面没有新的脏区
+    luat_sdl2_pump_events();
+}
+
+// 启动 SDL 刷新定时器,保证窗口事件泵持续运行
+static void start_tp_flush_timer(void) {
+    if (s_tp_state.flush_timer) {
+        return;
+    }
+    if (luat_rtos_timer_create(&s_tp_state.flush_timer) == 0) {
+        luat_rtos_timer_start(s_tp_state.flush_timer, TP_PC_FLUSH_INTERVAL_MS, 1, tp_flush_timer_cb, NULL);
+    } else {
+        LLOGW("pc tp unable to create refresh timer");
+    }
+}
+
+// 停止并释放 SDL 刷新定时器,避免重复创建
+static void stop_tp_flush_timer(void) {
+    if (!s_tp_state.flush_timer) {
+        return;
+    }
+    luat_rtos_timer_stop(s_tp_state.flush_timer);
+    luat_rtos_timer_delete(s_tp_state.flush_timer);
+    s_tp_state.flush_timer = NULL;
+}
+
 // 队列管理函数 - 兼容原有框架
 static int enqueue_event(luat_tp_data_t* event) {
     if (!event || !s_tp_state.queue_enabled) return -1;
@@ -279,6 +311,9 @@ static int luat_tp_pc_init(luat_tp_config_t* conf) {
     SDL_AddEventWatch(tp_sdl_watch, conf);
     LLOGI("pc tp init ok, w=%d h=%d tp_num=%d, queue_enabled=%d, queue_size=%d",
            conf->w, conf->h, conf->tp_num, s_tp_state.queue_enabled, s_tp_state.event_queue_size);
+
+    // 启动 SDL 刷新定时器,保证窗口事件泵持续运行
+    start_tp_flush_timer();
     return 0;
 }
 
@@ -356,7 +391,9 @@ static void luat_tp_pc_deinit(luat_tp_config_t* conf) {
             s_tp_state.queue_enabled = 0;
             uv_mutex_unlock(&s_tp_state.lock);
         }
-
+        // 停止并释放 SDL 刷新定时器,避免重复创建
+        stop_tp_flush_timer();
+    
         LLOGI("pc tp deinit complete");
     }
 }

+ 9 - 3
components/ui/sdl2/luat_sdl2.c

@@ -11,14 +11,16 @@ static SDL_Renderer *renderer = NULL;
 static SDL_Texture *framebuffer = NULL;
 static luat_sdl2_conf_t sdl_conf;
 
-static void luat_sdl2_pump_events(void) {
+// 定时调用此函数以保持 SDL2 事件泵活跃,避免窗口无响应
+void luat_sdl2_pump_events(void) {
     SDL_Event e;
+    // 循环处理所有等待的事件
     while (SDL_PollEvent(&e)) {
         if (e.type == SDL_QUIT) {
-            // Graceful exit on window close
+            // 当用户关闭窗口时,优雅退出程序
             exit(0);
         }
-        // Other events are ignored; important is to pump to keep window responsive
+        // 其他事件不做处理,关键作用是让事件泵持续运行,防止界面假死
     }
 }
 
@@ -71,11 +73,15 @@ void luat_sdl2_draw(int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint32_t* da
     SDL_UpdateTexture(framebuffer, &r, data, r.w * 2);
 }
 
+// 刷新渲染器,将framebuffer渲染到窗口,并立即处理SDL事件
 void luat_sdl2_flush(void) {
     if (renderer && framebuffer)
     {
+        // 将framebuffer的内容拷贝到渲染目标(窗口),准备呈现
         SDL_RenderCopy(renderer, framebuffer, NULL, NULL);
+        // 实际执行呈现
         SDL_RenderPresent(renderer);
     }
+    // 画面刷新后立刻处理(pump)SDL事件,保持窗口及触摸输入活跃
     luat_sdl2_pump_events();
 }

+ 1 - 0
components/ui/sdl2/luat_sdl2.h

@@ -16,6 +16,7 @@ int luat_sdl2_deinit(luat_sdl2_conf_t *conf);
 
 void luat_sdl2_draw(int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint32_t* data);
 void luat_sdl2_flush(void);
+void luat_sdl2_pump_events(void);
 
 #endif