Browse Source

[simulator][lvgl]同步lvgl win32 driver
https://github.com/lvgl/lv_drivers/commit/b69dca2ade845532a971bc935b7127cbda19ec9b
https://github.com/lvgl/lv_drivers/commit/0b01584e299e9a7bb880678c33d4da6fe472fc9e

https://github.com/lvgl/lv_drivers/pull/212
https://github.com/lvgl/lv_drivers/pull/216

Meco Man 2 years ago
parent
commit
3f0934feb7
1 changed files with 213 additions and 166 deletions
  1. 213 166
      bsp/simulator/applications/lvgl/win32drv.c

+ 213 - 166
bsp/simulator/applications/lvgl/win32drv.c

@@ -12,7 +12,7 @@
 #if USE_WIN32DRV
 
 #include <windowsx.h>
-
+#include <process.h>
 #include <stdbool.h>
 #include <stdint.h>
 
@@ -38,6 +38,16 @@
  *      TYPEDEFS
  **********************/
 
+typedef struct _WINDOW_THREAD_PARAMETER
+{
+    HANDLE window_mutex;
+    HINSTANCE instance_handle;
+    HICON icon_handle;
+    lv_coord_t hor_res;
+    lv_coord_t ver_res;
+    int show_window_mode;
+} WINDOW_THREAD_PARAMETER, * PWINDOW_THREAD_PARAMETER;
+
 /**********************
  *  STATIC PROTOTYPES
  **********************/
@@ -132,9 +142,8 @@ static void lv_win32_display_driver_flush_callback(
     const lv_area_t* area,
     lv_color_t* color_p);
 
-static void lv_win32_display_driver_rounder_callback(
-    lv_disp_drv_t* disp_drv,
-    lv_area_t* area);
+static void lv_win32_display_refresh_handler(
+    lv_timer_t* param);
 
 static void lv_win32_pointer_driver_read_callback(
     lv_indev_drv_t* indev_drv,
@@ -154,8 +163,8 @@ static LRESULT CALLBACK lv_win32_window_message_callback(
     WPARAM wParam,
     LPARAM lParam);
 
-static void lv_win32_message_handler(
-    lv_timer_t* param);
+static unsigned int __stdcall lv_win32_window_thread_entrypoint(
+    void* raw_parameter);
 
 /**********************
  *  GLOBAL VARIABLES
@@ -171,7 +180,6 @@ EXTERN_C lv_indev_t* lv_win32_encoder_device_object = NULL;
  *  STATIC VARIABLES
  **********************/
 
-static HINSTANCE g_instance_handle = NULL;
 static HWND g_window_handle = NULL;
 
 static HDC g_buffer_dc_handle = NULL;
@@ -179,6 +187,7 @@ static UINT32* g_pixel_buffer = NULL;
 static SIZE_T g_pixel_buffer_size = 0;
 
 static lv_disp_t* g_display = NULL;
+static bool volatile g_display_refreshing = false;
 
 static bool volatile g_mouse_pressed = false;
 static LPARAM volatile g_mouse_value = 0;
@@ -236,104 +245,42 @@ EXTERN_C bool lv_win32_init(
     lv_coord_t ver_res,
     HICON icon_handle)
 {
-    WNDCLASSEXW WindowClass;
-
-    WindowClass.cbSize = sizeof(WNDCLASSEX);
-
-    WindowClass.style = 0;
-    WindowClass.lpfnWndProc = lv_win32_window_message_callback;
-    WindowClass.cbClsExtra = 0;
-    WindowClass.cbWndExtra = 0;
-    WindowClass.hInstance = instance_handle;
-    WindowClass.hIcon = icon_handle;
-    WindowClass.hCursor = LoadCursorW(NULL, IDC_ARROW);
-    WindowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
-    WindowClass.lpszMenuName = NULL;
-    WindowClass.lpszClassName = L"lv_sim_visual_studio";
-    WindowClass.hIconSm = icon_handle;
-
-    if (!RegisterClassExW(&WindowClass))
-    {
-        return false;
-    }
-
-    g_instance_handle = instance_handle;
-
-    g_window_handle = CreateWindowExW(
-        WINDOW_EX_STYLE,
-        WindowClass.lpszClassName,
-        L"LVGL Simulator for Windows Desktop",
-        WINDOW_STYLE,
-        CW_USEDEFAULT,
-        0,
-        CW_USEDEFAULT,
-        0,
-        NULL,
-        NULL,
-        instance_handle,
-        NULL);
-
-    if (!g_window_handle)
-    {
-        return false;
-    }
-
-    g_dpi_value = lv_win32_get_dpi_for_window(g_window_handle);
-
-    RECT WindowSize;
-
-    WindowSize.left = 0;
-    WindowSize.right = MulDiv(
-        hor_res * WIN32DRV_MONITOR_ZOOM,
-        g_dpi_value,
-        USER_DEFAULT_SCREEN_DPI);
-    WindowSize.top = 0;
-    WindowSize.bottom = MulDiv(
-        ver_res * WIN32DRV_MONITOR_ZOOM,
-        g_dpi_value,
-        USER_DEFAULT_SCREEN_DPI);
-
-    AdjustWindowRectEx(
-        &WindowSize,
-        WINDOW_STYLE,
-        FALSE,
-        WINDOW_EX_STYLE);
-    OffsetRect(
-        &WindowSize,
-        -WindowSize.left,
-        -WindowSize.top);
-
-    SetWindowPos(
-        g_window_handle,
+    PWINDOW_THREAD_PARAMETER parameter =
+        (PWINDOW_THREAD_PARAMETER)malloc(sizeof(WINDOW_THREAD_PARAMETER));
+    parameter->window_mutex = CreateEventExW(NULL, NULL, 0, EVENT_ALL_ACCESS);
+    parameter->instance_handle = instance_handle;
+    parameter->icon_handle = icon_handle;
+    parameter->hor_res = hor_res;
+    parameter->ver_res = ver_res;
+    parameter->show_window_mode = show_window_mode;
+
+    _beginthreadex(
         NULL,
         0,
+        lv_win32_window_thread_entrypoint,
+        parameter,
         0,
-        WindowSize.right,
-        WindowSize.bottom,
-        SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE);
-
-    lv_win32_register_touch_window(g_window_handle, 0);
-
-    lv_timer_create(lv_win32_message_handler, 0, NULL);
-
-    lv_win32_enable_child_window_dpi_message(g_window_handle);
-
-    HDC hNewBufferDC = lv_win32_create_frame_buffer(
-        g_window_handle,
-        hor_res,
-        ver_res,
-        &g_pixel_buffer,
-        &g_pixel_buffer_size);
+        NULL);
 
-    DeleteDC(g_buffer_dc_handle);
-    g_buffer_dc_handle = hNewBufferDC;
+    WaitForSingleObjectEx(parameter->window_mutex, INFINITE, FALSE);
 
     static lv_disp_draw_buf_t display_buffer;
+#if (LV_COLOR_DEPTH == 32) || \
+    (LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP == 0) || \
+    (LV_COLOR_DEPTH == 8) || \
+    (LV_COLOR_DEPTH == 1)
+    lv_disp_draw_buf_init(
+        &display_buffer,
+        (lv_color_t*)g_pixel_buffer,
+        NULL,
+        hor_res * ver_res);
+#else
     lv_disp_draw_buf_init(
         &display_buffer,
         (lv_color_t*)malloc(hor_res * ver_res * sizeof(lv_color_t)),
         NULL,
         hor_res * ver_res);
+#endif
 
     static lv_disp_drv_t display_driver;
     lv_disp_drv_init(&display_driver);
@@ -341,8 +288,11 @@ EXTERN_C bool lv_win32_init(
     display_driver.ver_res = ver_res;
     display_driver.flush_cb = lv_win32_display_driver_flush_callback;
     display_driver.draw_buf = &display_buffer;
-    display_driver.rounder_cb = lv_win32_display_driver_rounder_callback;
+    display_driver.direct_mode = 1;
     g_display = lv_disp_drv_register(&display_driver);
+    lv_timer_del(g_display->refr_timer);
+    g_display->refr_timer = NULL;
+    lv_timer_create(lv_win32_display_refresh_handler, 0, NULL);
 
     static lv_indev_drv_t pointer_driver;
     lv_indev_drv_init(&pointer_driver);
@@ -362,9 +312,6 @@ EXTERN_C bool lv_win32_init(
     encoder_driver.read_cb = lv_win32_encoder_driver_read_callback;
     lv_win32_encoder_device_object = lv_indev_drv_register(&encoder_driver);
 
-    ShowWindow(g_window_handle, show_window_mode);
-    UpdateWindow(g_window_handle);
-
     return true;
 }
 
@@ -674,79 +621,52 @@ static void lv_win32_display_driver_flush_callback(
     const lv_area_t* area,
     lv_color_t* color_p)
 {
+    if (lv_disp_flush_is_last(disp_drv))
+    {
 #if (LV_COLOR_DEPTH == 32) || \
     (LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP == 0) || \
     (LV_COLOR_DEPTH == 8) || \
     (LV_COLOR_DEPTH == 1)
-    UNREFERENCED_PARAMETER(area);
-    memcpy(g_pixel_buffer, color_p, g_pixel_buffer_size);
+        UNREFERENCED_PARAMETER(color_p);
 #elif (LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP != 0)
-    SIZE_T count = g_pixel_buffer_size / sizeof(UINT16);
-    PUINT16 source = (PUINT16)color_p;
-    PUINT16 destination = (PUINT16)g_pixel_buffer;
-    for (SIZE_T i = 0; i < count; ++i)
-    {
-        UINT16 current = *source;
-        *destination = (LOBYTE(current) << 8) | HIBYTE(current);
+        SIZE_T count = g_pixel_buffer_size / sizeof(UINT16);
+        PUINT16 source = (PUINT16)color_p;
+        PUINT16 destination = (PUINT16)g_pixel_buffer;
+        for (SIZE_T i = 0; i < count; ++i)
+        {
+            UINT16 current = *source;
+            *destination = (LOBYTE(current) << 8) | HIBYTE(current);
 
-        ++source;
-        ++destination;
-    }
+            ++source;
+            ++destination;
+        }
 #else
-    for (int y = area->y1; y <= area->y2; ++y)
-    {
-        for (int x = area->x1; x <= area->x2; ++x)
+        for (int y = area->y1; y <= area->y2; ++y)
         {
-            g_pixel_buffer[y * disp_drv->hor_res + x] = lv_color_to32(*color_p);
-            color_p++;
+            for (int x = area->x1; x <= area->x2; ++x)
+            {
+                g_pixel_buffer[y * disp_drv->hor_res + x] =
+                    lv_color_to32(*color_p);
+                color_p++;
+            }
         }
-    }
 #endif
 
-    HDC hWindowDC = GetDC(g_window_handle);
-    if (hWindowDC)
-    {
-        int PreviousMode = SetStretchBltMode(
-            hWindowDC,
-            HALFTONE);
-
-        StretchBlt(
-            hWindowDC,
-            0,
-            0,
-            MulDiv(
-                disp_drv->hor_res * WIN32DRV_MONITOR_ZOOM,
-                g_dpi_value,
-                USER_DEFAULT_SCREEN_DPI),
-            MulDiv(
-                disp_drv->ver_res * WIN32DRV_MONITOR_ZOOM,
-                g_dpi_value,
-                USER_DEFAULT_SCREEN_DPI),
-            g_buffer_dc_handle,
-            0,
-            0,
-            disp_drv->hor_res,
-            disp_drv->ver_res,
-            SRCCOPY);
-
-        SetStretchBltMode(
-            hWindowDC,
-            PreviousMode);
-
-        ReleaseDC(g_window_handle, hWindowDC);
+        InvalidateRect(g_window_handle, NULL, FALSE);
     }
 
     lv_disp_flush_ready(disp_drv);
 }
 
-static void lv_win32_display_driver_rounder_callback(
-    lv_disp_drv_t* disp_drv,
-    lv_area_t* area)
+static void lv_win32_display_refresh_handler(
+    lv_timer_t* param)
 {
-    area->x1 = 0;
-    area->x2 = disp_drv->hor_res - 1;
-    area->y1 = 0;
-    area->y2 = disp_drv->ver_res - 1;
+    UNREFERENCED_PARAMETER(param);
+
+    if (!g_display_refreshing)
+    {
+        _lv_disp_refr_timer(NULL);
+    }
 }
 
 static void lv_win32_pointer_driver_read_callback(
@@ -975,6 +895,43 @@ static LRESULT CALLBACK lv_win32_window_message_callback(
 
         break;
     }
+    case WM_PAINT:
+    {
+        g_display_refreshing = true;
+
+        PAINTSTRUCT ps;
+        HDC hdc = BeginPaint(hWnd, &ps);
+
+        if (g_display)
+        {
+            SetStretchBltMode(hdc, HALFTONE);
+
+            StretchBlt(
+                hdc,
+                ps.rcPaint.left,
+                ps.rcPaint.top,
+                ps.rcPaint.right - ps.rcPaint.left,
+                ps.rcPaint.bottom - ps.rcPaint.top,
+                g_buffer_dc_handle,
+                0,
+                0,
+                MulDiv(
+                    ps.rcPaint.right - ps.rcPaint.left,
+                    USER_DEFAULT_SCREEN_DPI,
+                    WIN32DRV_MONITOR_ZOOM * g_dpi_value),
+                MulDiv(
+                    ps.rcPaint.bottom - ps.rcPaint.top,
+                    USER_DEFAULT_SCREEN_DPI,
+                    WIN32DRV_MONITOR_ZOOM * g_dpi_value),
+                SRCCOPY);
+        }
+
+        EndPaint(hWnd, &ps);
+
+        g_display_refreshing = false;
+
+        break;
+    }
     case WM_DESTROY:
         PostQuitMessage(0);
         break;
@@ -985,23 +942,113 @@ static LRESULT CALLBACK lv_win32_window_message_callback(
     return 0;
 }
 
-static void lv_win32_message_handler(
-    lv_timer_t* param)
+static unsigned int __stdcall lv_win32_window_thread_entrypoint(
+    void* raw_parameter)
 {
-    UNREFERENCED_PARAMETER(param);
+    PWINDOW_THREAD_PARAMETER parameter =
+        (PWINDOW_THREAD_PARAMETER)raw_parameter;
+
+    WNDCLASSEXW window_class;
+    window_class.cbSize = sizeof(WNDCLASSEXW);
+    window_class.style = 0;
+    window_class.lpfnWndProc = lv_win32_window_message_callback;
+    window_class.cbClsExtra = 0;
+    window_class.cbWndExtra = 0;
+    window_class.hInstance = parameter->instance_handle;
+    window_class.hIcon = parameter->icon_handle;
+    window_class.hCursor = LoadCursorW(NULL, IDC_ARROW);
+    window_class.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+    window_class.lpszMenuName = NULL;
+    window_class.lpszClassName = L"lv_sim_visual_studio";
+    window_class.hIconSm = parameter->icon_handle;
+    if (!RegisterClassExW(&window_class))
+    {
+        return 0;
+    }
 
-    MSG Message;
-    BOOL Result = PeekMessageW(&Message, NULL, 0, 0, TRUE);
-    if (Result != 0 && Result != -1)
+    HWND window_handle = CreateWindowExW(
+        WINDOW_EX_STYLE,
+        window_class.lpszClassName,
+        L"LVGL Simulator for Windows Desktop",
+        WINDOW_STYLE,
+        CW_USEDEFAULT,
+        0,
+        CW_USEDEFAULT,
+        0,
+        NULL,
+        NULL,
+        parameter->instance_handle,
+        NULL);
+
+    if (!window_handle)
     {
-        TranslateMessage(&Message);
-        DispatchMessageW(&Message);
+        return 0;
+    }
 
-        if (Message.message == WM_QUIT)
-        {
-            lv_win32_quit_signal = true;
-        }
+    g_dpi_value = lv_win32_get_dpi_for_window(window_handle);
+
+    RECT window_size;
+
+    window_size.left = 0;
+    window_size.right = MulDiv(
+        parameter->hor_res * WIN32DRV_MONITOR_ZOOM,
+        g_dpi_value,
+        USER_DEFAULT_SCREEN_DPI);
+    window_size.top = 0;
+    window_size.bottom = MulDiv(
+        parameter->ver_res * WIN32DRV_MONITOR_ZOOM,
+        g_dpi_value,
+        USER_DEFAULT_SCREEN_DPI);
+
+    AdjustWindowRectEx(
+        &window_size,
+        WINDOW_STYLE,
+        FALSE,
+        WINDOW_EX_STYLE);
+    OffsetRect(
+        &window_size,
+        -window_size.left,
+        -window_size.top);
+
+    SetWindowPos(
+        window_handle,
+        NULL,
+        0,
+        0,
+        window_size.right,
+        window_size.bottom,
+        SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE);
+
+    lv_win32_register_touch_window(window_handle, 0);
+
+    lv_win32_enable_child_window_dpi_message(window_handle);
+
+    HDC hNewBufferDC = lv_win32_create_frame_buffer(
+        window_handle,
+        parameter->hor_res,
+        parameter->ver_res,
+        &g_pixel_buffer,
+        &g_pixel_buffer_size);
+
+    DeleteDC(g_buffer_dc_handle);
+    g_buffer_dc_handle = hNewBufferDC;
+
+    ShowWindow(window_handle, parameter->show_window_mode);
+    UpdateWindow(window_handle);
+    g_window_handle = window_handle;
+
+    SetEvent(parameter->window_mutex);
+
+    MSG message;
+    while (GetMessageW(&message, NULL, 0, 0))
+    {
+        TranslateMessage(&message);
+        DispatchMessageW(&message);
     }
+
+    lv_win32_quit_signal = true;
+
+    return 0;
 }
 
 #endif /*USE_WIN32DRV*/