From d85a39e78cc5a066967b95d521a4cb31664658d9 Mon Sep 17 00:00:00 2001 From: "Dany.L" <24490390+danyyliu@users.noreply.github.com> Date: Sat, 8 Jun 2024 04:54:52 +0800 Subject: [PATCH] feat(opengles): add basic driver for opengles (#6254) Co-authored-by: Dany Liu Co-authored-by: Gabor Kiss-Vamosi --- Kconfig | 9 + docs/integration/driver/index.rst | 1 + docs/integration/driver/opengles.rst | 65 ++++ lv_conf_template.h | 6 + scripts/install-prerequisites.bat | 2 +- scripts/install-prerequisites.sh | 1 + src/drivers/glfw/lv_glfw_mouse.c | 87 +++++ src/drivers/glfw/lv_glfw_mouse.h | 43 +++ src/drivers/glfw/lv_glfw_mouse_private.c | 89 +++++ src/drivers/glfw/lv_glfw_mouse_private.h | 52 +++ src/drivers/glfw/lv_glfw_window.c | 379 +++++++++++++++++++ src/drivers/glfw/lv_glfw_window.h | 46 +++ src/drivers/glfw/lv_opengles_debug.c | 57 +++ src/drivers/glfw/lv_opengles_debug.h | 38 ++ src/drivers/glfw/lv_opengles_driver.c | 447 +++++++++++++++++++++++ src/drivers/glfw/lv_opengles_driver.h | 27 ++ src/drivers/lv_drivers.h | 3 + src/lv_conf_internal.h | 22 ++ tests/CMakeLists.txt | 19 + tests/src/lv_test_conf_full.h | 4 + 20 files changed, 1396 insertions(+), 1 deletion(-) create mode 100644 docs/integration/driver/opengles.rst create mode 100644 src/drivers/glfw/lv_glfw_mouse.c create mode 100644 src/drivers/glfw/lv_glfw_mouse.h create mode 100644 src/drivers/glfw/lv_glfw_mouse_private.c create mode 100644 src/drivers/glfw/lv_glfw_mouse_private.h create mode 100644 src/drivers/glfw/lv_glfw_window.c create mode 100644 src/drivers/glfw/lv_glfw_window.h create mode 100644 src/drivers/glfw/lv_opengles_debug.c create mode 100644 src/drivers/glfw/lv_opengles_debug.h create mode 100644 src/drivers/glfw/lv_opengles_driver.c create mode 100644 src/drivers/glfw/lv_opengles_driver.h diff --git a/Kconfig b/Kconfig index f31462593..0bc4952e0 100644 --- a/Kconfig +++ b/Kconfig @@ -1646,6 +1646,15 @@ menu "LVGL configuration" config LV_USE_WINDOWS bool "Use LVGL Windows backend" default n + + config LV_USE_OPENGLES + bool "Use GLFW and OpenGL to open window on PC and handle mouse and keyboard" + default n + + config LV_USE_OPENGLES_DEBUG + bool "Enable debug mode for OpenGL" + depends on LV_USE_OPENGLES + default n endmenu menu "Examples" diff --git a/docs/integration/driver/index.rst b/docs/integration/driver/index.rst index 089307b40..ea9788091 100644 --- a/docs/integration/driver/index.rst +++ b/docs/integration/driver/index.rst @@ -10,3 +10,4 @@ Drivers libinput X11 windows + opengles diff --git a/docs/integration/driver/opengles.rst b/docs/integration/driver/opengles.rst new file mode 100644 index 000000000..254e31dd7 --- /dev/null +++ b/docs/integration/driver/opengles.rst @@ -0,0 +1,65 @@ +=============================== +OpenGL ES Display/Inputs driver +=============================== + +Overview +-------- + +| The **OpenGL ES** display/input `driver `__ offers support for simulating the LVGL display and keyboard/mouse inputs in an desktop window created via GLFW. +| It is an alternative to **Wayland**, **XCB**, **SDL** or **Qt**. + +The main purpose for this driver is for testing/debugging the LVGL application in an **OpenGL** simulation window. + +Prerequisites +------------- + +The OpenGL driver uses GLEW GLFW to access the OpenGL window manager. + +1. Install GLEW and GLFW: ``sudo apt-get install libglew-dev libglfw3-dev`` + +Configure OpenGL driver +----------------------- + +1. Required linked libraries: -lGL -lGLEW -lglfw +2. Enable the OpenGL driver support in lv_conf.h, by cmake compiler define or by KConfig + .. code:: c + + #define LV_USE_OPENGLES 1 + +Usage +----- + +.. code:: c + + #include "lvgl/lvgl.h" + #include "lvgl/examples/lv_examples.h" + #include "lvgl/demos/lv_demos.h" + + int main() + { + lv_init(); + + lv_display_t * disp = lv_glfw_window_create(480, 272); + + lv_indev_t * mouse = lv_glfw_mouse_create(); + lv_indev_set_group(mouse, lv_group_get_default()); + lv_indev_set_display(mouse, disp); + + lv_display_set_default(disp); + + LV_IMAGE_DECLARE(mouse_cursor_icon); /*Declare the image file.*/ + lv_obj_t * cursor_obj; + cursor_obj = lv_image_create(lv_screen_active()); /*Create an image object for the cursor */ + lv_image_set_src(cursor_obj, &mouse_cursor_icon); /*Set the image source*/ + lv_indev_set_cursor(mouse, cursor_obj); /*Connect the image object to the driver*/ + + lv_demo_widgets(); + + while (1) + { + uint32_t time_till_next = lv_timer_handler(); + lv_delay_ms(time_till_next); + } + + return 0; + } diff --git a/lv_conf_template.h b/lv_conf_template.h index e5b8ae3ec..ebafee7d1 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -978,6 +978,12 @@ /* LVGL Windows backend */ #define LV_USE_WINDOWS 0 +/* Use OpenGL to open window on PC and handle mouse and keyboard */ +#define LV_USE_OPENGLES 0 +#if LV_USE_OPENGLES + #define LV_USE_OPENGLES_DEBUG 1 /* Enable or disable debug for opengles */ +#endif + /*================== * EXAMPLES *==================*/ diff --git a/scripts/install-prerequisites.bat b/scripts/install-prerequisites.bat index 0611f9509..f37b11273 100644 --- a/scripts/install-prerequisites.bat +++ b/scripts/install-prerequisites.bat @@ -1,4 +1,4 @@ -vcpkg install vcpkg-tool-ninja libpng freetype +vcpkg install vcpkg-tool-ninja libpng freetype opengl glfw3 glew if %errorlevel% neq 0 exit /b %errorlevel% pip install pypng lz4 if %errorlevel% neq 0 exit /b %errorlevel% diff --git a/scripts/install-prerequisites.sh b/scripts/install-prerequisites.sh index ecd797acd..d63f6ba5e 100755 --- a/scripts/install-prerequisites.sh +++ b/scripts/install-prerequisites.sh @@ -9,6 +9,7 @@ sudo dpkg --add-architecture i386 sudo apt update sudo apt install gcc gcc-multilib g++-multilib ninja-build \ libpng-dev libjpeg-turbo8-dev libfreetype6-dev \ +libglew-dev libglfw3-dev \ libpng-dev:i386 libjpeg-dev:i386 libfreetype6-dev:i386 \ ruby-full gcovr cmake python3 pngquant libinput-dev libxkbcommon-dev libdrm-dev pkg-config pip3 install pypng lz4 diff --git a/src/drivers/glfw/lv_glfw_mouse.c b/src/drivers/glfw/lv_glfw_mouse.c new file mode 100644 index 000000000..d4078b5fa --- /dev/null +++ b/src/drivers/glfw/lv_glfw_mouse.c @@ -0,0 +1,87 @@ +/** + * @file lv_glfw_mouse.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_glfw_mouse.h" +#include "lv_glfw_mouse_private.h" +#if LV_USE_OPENGLES + +#include +#include +#include "../../core/lv_group.h" +#include "../../stdlib/lv_string.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void opengles_mouse_read(lv_indev_t * indev, lv_indev_data_t * data); +static void release_indev_cb(lv_event_t * e); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_indev_t * lv_glfw_mouse_create(void) +{ + lv_glfw_mouse_t * dsc = lv_malloc_zeroed(sizeof(lv_glfw_mouse_t)); + LV_ASSERT_MALLOC(dsc); + if(dsc == NULL) return NULL; + + lv_indev_t * indev = lv_indev_create(); + LV_ASSERT_MALLOC(indev); + if(indev == NULL) { + lv_free(dsc); + return NULL; + } + + lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(indev, opengles_mouse_read); + lv_indev_set_driver_data(indev, dsc); + + lv_indev_set_mode(indev, LV_INDEV_MODE_EVENT); + lv_indev_add_event_cb(indev, release_indev_cb, LV_EVENT_DELETE, indev); + + return indev; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void opengles_mouse_read(lv_indev_t * indev, lv_indev_data_t * data) +{ + lv_glfw_mouse_t * dsc = lv_indev_get_driver_data(indev); + + /*Store the collected data*/ + data->point.x = dsc->last_x; + data->point.y = dsc->last_y; + data->state = dsc->left_button_down ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; + data->enc_diff = dsc->diff; + dsc->diff = 0; +} + +static void release_indev_cb(lv_event_t * e) +{ + lv_indev_t * indev = (lv_indev_t *) lv_event_get_user_data(e); + lv_glfw_mouse_t * dsc = lv_indev_get_driver_data(indev); + if(dsc) { + lv_indev_set_driver_data(indev, NULL); + lv_indev_set_read_cb(indev, NULL); + lv_free(dsc); + LV_LOG_INFO("done"); + } +} + +#endif /* LV_USE_OPENGLES */ diff --git a/src/drivers/glfw/lv_glfw_mouse.h b/src/drivers/glfw/lv_glfw_mouse.h new file mode 100644 index 000000000..979fee964 --- /dev/null +++ b/src/drivers/glfw/lv_glfw_mouse.h @@ -0,0 +1,43 @@ +/** + * @file lv_glfw_mouse.h + * + */ + +#ifndef LV_GLFW_MOUSE_H +#define LV_GLFW_MOUSE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_glfw_window.h" +#if LV_USE_OPENGLES + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_indev_t * lv_glfw_mouse_create(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_OPENGLES*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_GLFW_MOUSE_H */ diff --git a/src/drivers/glfw/lv_glfw_mouse_private.c b/src/drivers/glfw/lv_glfw_mouse_private.c new file mode 100644 index 000000000..b8cbe95eb --- /dev/null +++ b/src/drivers/glfw/lv_glfw_mouse_private.c @@ -0,0 +1,89 @@ +/** + * @file lv_glfw_mouse_private.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "../../display/lv_display.h" +#include "../../indev/lv_indev.h" + +#include "lv_glfw_mouse_private.h" +#if LV_USE_OPENGLES + +#include +#include +#include "../../core/lv_group.h" +#include "../../stdlib/lv_string.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_glfw_mouse_move_handler(lv_display_t * disp, int x, int y) +{ + if(disp == NULL) { + return; + } + + /*Find a suitable indev*/ + lv_indev_t * indev = lv_indev_get_next(NULL); + while(indev) { + if(lv_indev_get_display(indev) == disp && lv_indev_get_type(indev) == LV_INDEV_TYPE_POINTER) { + break; + } + indev = lv_indev_get_next(indev); + } + + if(indev == NULL) return; + lv_glfw_mouse_t * indev_dev = lv_indev_get_driver_data(indev); + if(indev_dev == NULL) return; + + indev_dev->last_x = x; + indev_dev->last_y = y; + + lv_indev_read(indev); +} + +void lv_glfw_mouse_btn_handler(lv_display_t * disp, int btn_down) +{ + if(disp == NULL) { + return; + } + + /*Find a suitable indev*/ + lv_indev_t * indev = lv_indev_get_next(NULL); + while(indev) { + if(lv_indev_get_display(indev) == disp && lv_indev_get_type(indev) == LV_INDEV_TYPE_POINTER) { + break; + } + indev = lv_indev_get_next(indev); + } + + if(indev == NULL) return; + lv_glfw_mouse_t * indev_dev = lv_indev_get_driver_data(indev); + if(indev_dev == NULL) return; + + indev_dev->left_button_down = btn_down; + + lv_indev_read(indev); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /* LV_USE_OPENGLES */ diff --git a/src/drivers/glfw/lv_glfw_mouse_private.h b/src/drivers/glfw/lv_glfw_mouse_private.h new file mode 100644 index 000000000..b34e155a9 --- /dev/null +++ b/src/drivers/glfw/lv_glfw_mouse_private.h @@ -0,0 +1,52 @@ +/** + * @file lv_glfw_mouse_private.h + * + */ + +#ifndef LV_GLFW_MOUSE_PRIVATE_H +#define LV_GLFW_MOUSE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#if LV_USE_OPENGLES + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + int16_t last_x; + int16_t last_y; + bool left_button_down; + int32_t diff; +} lv_glfw_mouse_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_glfw_mouse_move_handler(lv_display_t * disp, int x, int y); + +void lv_glfw_mouse_btn_handler(lv_display_t * disp, int btn_down); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_OPENGLES*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_GLFW_MOUSE_PRIVATE_H */ diff --git a/src/drivers/glfw/lv_glfw_window.c b/src/drivers/glfw/lv_glfw_window.c new file mode 100644 index 000000000..b09f569ee --- /dev/null +++ b/src/drivers/glfw/lv_glfw_window.c @@ -0,0 +1,379 @@ +/** + * @file lv_glfw_window.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_glfw_window.h" +#include "lv_glfw_mouse_private.h" +#if LV_USE_OPENGLES +#include +#include +#include +#include +#include "../../core/lv_refr.h" +#include "../../stdlib/lv_string.h" +#include "../../core/lv_global.h" +#include "../../display/lv_display_private.h" +#include "../../lv_init.h" + +#include +#include + +#include "lv_opengles_driver.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef struct { + GLFWwindow * window; + + uint8_t * fb1; + uint8_t * fb2; + uint8_t * fb_act; + uint8_t * buf1; + uint8_t * buf2; + uint8_t * rotated_buf; + size_t rotated_buf_size; + + uint8_t zoom; + uint8_t ignore_size_chg; +} lv_glfw_window_t; + +/********************** + * STATIC PROTOTYPES + **********************/ +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p); +static int window_create(lv_display_t * disp); +static void window_update(lv_display_t * disp); +static void texture_resize(lv_display_t * disp); +static void window_update_handler(lv_timer_t * t); +static void window_event_handler(lv_timer_t * t); +static void release_disp_cb(lv_event_t * e); +static void res_chg_event_cb(lv_event_t * e); +static uint32_t lv_glfw_tick_count_callback(void); + +/*********************** + * GLOBAL PROTOTYPES + ***********************/ +static bool inited = false; +bool deiniting = false; + +/********************** + * STATIC VARIABLES + **********************/ +static lv_timer_t * update_handler_timer; +static lv_timer_t * event_handler_timer; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_display_t * lv_glfw_window_create(int32_t hor_res, int32_t ver_res) +{ + if(!inited) { + update_handler_timer = lv_timer_create(window_update_handler, 5, NULL); + event_handler_timer = lv_timer_create(window_event_handler, 5, NULL); + + lv_tick_set_cb(lv_glfw_tick_count_callback); + + inited = true; + } + + lv_glfw_window_t * dsc = lv_malloc_zeroed(sizeof(lv_glfw_window_t)); + LV_ASSERT_MALLOC(dsc); + if(dsc == NULL) return NULL; + + lv_display_t * disp = lv_display_create(hor_res, ver_res); + if(disp == NULL) { + lv_free(dsc); + return NULL; + } + + lv_display_add_event_cb(disp, release_disp_cb, LV_EVENT_DELETE, disp); + + lv_display_set_driver_data(disp, dsc); + + int ret = window_create(disp); + if(ret != 0) { + lv_display_send_event(disp, LV_EVENT_DELETE, NULL); + return NULL; + } + + lv_display_set_flush_cb(disp, flush_cb); + uint32_t stride = lv_draw_buf_width_to_stride(lv_display_get_horizontal_resolution(disp), + lv_display_get_color_format(disp)); + lv_display_set_buffers(disp, dsc->fb1, dsc->fb2, stride * disp->ver_res, + LV_DISPLAY_RENDER_MODE_DIRECT); + lv_display_add_event_cb(disp, res_chg_event_cb, LV_EVENT_RESOLUTION_CHANGED, NULL); + + lv_opengles_init(dsc->fb1, hor_res, ver_res); + + return disp; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_glfw_window_quit(lv_display_t * disp) +{ + lv_glfw_window_t * dsc = lv_display_get_driver_data(disp); + if(inited) { + lv_timer_delete(update_handler_timer); + update_handler_timer = NULL; + + glfwDestroyWindow(dsc->window); + glfwTerminate(); + + inited = false; + } +} + +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) +{ + LV_UNUSED(area); + LV_UNUSED(px_map); + if(lv_display_flush_is_last(disp)) { + window_update(disp); + } + + /*IMPORTANT! It must be called to tell the system the flush is ready*/ + lv_display_flush_ready(disp); +} + +/** + * Handler for glfw events + */ +static void window_event_handler(lv_timer_t * t) +{ + LV_UNUSED(t); + if(deiniting == false) { + return; + } + + lv_display_t * disp = lv_display_get_default(); + if(disp == NULL) { + return; + } + lv_glfw_window_t * dsc = lv_display_get_driver_data(disp); + if(dsc == NULL) { + return; + } + + glfwSetWindowShouldClose(dsc->window, GLFW_TRUE); + lv_display_send_event(disp, LV_EVENT_DELETE, NULL); +} + +/** + * Handler to update texture + */ +static void window_update_handler(lv_timer_t * t) +{ + LV_UNUSED(t); + lv_display_t * disp = lv_display_get_default(); + if(disp == NULL) { + return; + } + lv_glfw_window_t * dsc = lv_display_get_driver_data(disp); + if(dsc == NULL) { + return; + } + + if(!glfwWindowShouldClose(dsc->window)) { + lv_opengles_update(dsc->fb1, disp->hor_res, disp->ver_res); + + /* Swap front and back buffers */ + glfwSwapBuffers(dsc->window); + + glfwPollEvents(); + } +} + +static void glfw_error_cb(int error, const char * description) +{ + fprintf(stderr, "GLFW Error %d: %s\n", error, description); +} + +static void window_close_callback(GLFWwindow * window) +{ + LV_UNUSED(window); + deiniting = true; +} + +static void key_callback(GLFWwindow * window, int key, int scancode, int action, int mods) +{ + LV_UNUSED(window); + LV_UNUSED(scancode); + LV_UNUSED(mods); + if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { + deiniting = true; + } +} + +static void mouse_button_callback(GLFWwindow * window, int button, int action, int mods) +{ + LV_UNUSED(window); + LV_UNUSED(mods); + if(button == GLFW_MOUSE_BUTTON_LEFT) { + lv_display_t * disp = lv_display_get_default(); + if(action == GLFW_PRESS) { + lv_glfw_mouse_btn_handler(disp, 1); + } + else if(action == GLFW_RELEASE) { + lv_glfw_mouse_btn_handler(disp, 0); + } + } +} + +static void mouse_move_cllback(GLFWwindow * window, double xpos, double ypos) +{ + LV_UNUSED(window); + lv_display_t * disp = lv_display_get_default(); + lv_glfw_mouse_move_handler(disp, (int)xpos, (int)ypos); +} + +static void framebuffer_size_callback(GLFWwindow * window, int width, int height) +{ + LV_UNUSED(window); + glViewport(0, 0, width, height); + lv_display_t * disp = lv_display_get_default(); + if(disp == NULL) { + return; + } + lv_glfw_window_t * dsc = lv_display_get_driver_data(disp); + dsc->ignore_size_chg = 1; + lv_display_set_resolution(disp, width / dsc->zoom, height / dsc->zoom); + dsc->ignore_size_chg = 0; + lv_refr_now(disp); +} + +static void texture_resize(lv_display_t * disp) +{ + int32_t hor_res = lv_display_get_horizontal_resolution(disp); + int32_t ver_res = lv_display_get_vertical_resolution(disp); + uint32_t stride = lv_draw_buf_width_to_stride(hor_res, lv_display_get_color_format(disp)); + lv_glfw_window_t * dsc = lv_display_get_driver_data(disp); + + dsc->fb1 = realloc(dsc->fb1, stride * ver_res); + lv_memzero(dsc->fb1, stride * ver_res); + + lv_display_set_buffers(disp, dsc->fb1, dsc->fb2, stride * ver_res, LV_DISPLAY_RENDER_MODE_DIRECT); +} + +static int window_create(lv_display_t * disp) +{ + lv_glfw_window_t * dsc = lv_display_get_driver_data(disp); + dsc->zoom = 1; + + glfwSetErrorCallback(glfw_error_cb); + if(!glfwInit()) { + LV_LOG_ERROR("glfwInit fail.\n"); + return 1; + } + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); + + int32_t hor_res = disp->hor_res; + int32_t ver_res = disp->ver_res; + + /* Create window with graphics context */ + dsc->window = glfwCreateWindow(hor_res * dsc->zoom, ver_res * dsc->zoom, "LVGL Simulator", NULL, NULL); + if(dsc->window == NULL) { + LV_LOG_ERROR("glfwCreateWindow fail.\n"); + return 2; + } + + glfwMakeContextCurrent(dsc->window); + if(glewInit() != GLEW_OK) { + LV_LOG_ERROR("glewInit fail.\n"); + return 3; + } + + LV_LOG_INFO("GL version: %s\n", glGetString(GL_VERSION)); + LV_LOG_INFO("GLSL version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); + + glfwSwapInterval(1); + + glfwSetFramebufferSizeCallback(dsc->window, framebuffer_size_callback); + + glfwSetMouseButtonCallback(dsc->window, mouse_button_callback); + glfwSetCursorPosCallback(dsc->window, mouse_move_cllback); + + glfwSetKeyCallback(dsc->window, key_callback); + + glfwSetWindowCloseCallback(dsc->window, window_close_callback); + + texture_resize(disp); + + uint32_t px_size = lv_color_format_get_size(lv_display_get_color_format(disp)); + lv_memset(dsc->fb1, 0xff, hor_res * ver_res * px_size); + + return 0; +} + +static void window_update(lv_display_t * disp) +{ + lv_glfw_window_t * dsc = lv_display_get_driver_data(disp); + if(dsc->fb_act) { + LV_LOG_INFO("current pixel: %d\n", ((uint16_t *)(dsc->fb_act))[0]); + } + if(dsc->fb1) { + LV_LOG_INFO("fb1 pixel: %d\n", ((uint16_t *)(dsc->fb1))[0]); + } +} + +static void res_chg_event_cb(lv_event_t * e) +{ + lv_display_t * disp = lv_event_get_current_target(e); + texture_resize(disp); +} + +static void release_disp_cb(lv_event_t * e) +{ + lv_display_t * disp = (lv_display_t *) lv_event_get_user_data(e); + lv_glfw_window_t * dsc = lv_display_get_driver_data(disp); + + lv_glfw_window_quit(disp); + + if(dsc->fb1) { + free(dsc->fb1); + dsc->fb1 = NULL; + } + if(dsc->fb2) { + free(dsc->fb2); + dsc->fb2 = NULL; + } + if(dsc->buf1) { + free(dsc->buf1); + dsc->buf1 = NULL; + } + if(dsc->buf2) { + free(dsc->buf2); + dsc->buf2 = NULL; + } + + lv_deinit(); + lv_free(dsc); + + exit(0); +} + +static uint32_t lv_glfw_tick_count_callback(void) +{ + int milliseconds = (int)(glfwGetTime() * 1000); + return milliseconds; +} + +#endif /*LV_USE_OPENGLES*/ diff --git a/src/drivers/glfw/lv_glfw_window.h b/src/drivers/glfw/lv_glfw_window.h new file mode 100644 index 000000000..000d1d618 --- /dev/null +++ b/src/drivers/glfw/lv_glfw_window.h @@ -0,0 +1,46 @@ +/** + * @file lv_glfw_window.h + * + */ + +#ifndef LV_GLFW_WINDOW_H +#define LV_GLFW_WINDOW_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../display/lv_display.h" +#include "../../indev/lv_indev.h" + +#if LV_USE_OPENGLES + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_display_t * lv_glfw_window_create(int32_t hor_res, int32_t ver_res); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_OPENGLES */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_GLFW_WINDOW_H */ diff --git a/src/drivers/glfw/lv_opengles_debug.c b/src/drivers/glfw/lv_opengles_debug.c new file mode 100644 index 000000000..3e52e3125 --- /dev/null +++ b/src/drivers/glfw/lv_opengles_debug.c @@ -0,0 +1,57 @@ +/** + * @file lv_opengles_debug.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "../../display/lv_display.h" +#include "lv_opengles_debug.h" + +#if LV_USE_OPENGLES + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/*********************** + * GLOBAL PROTOTYPES + ***********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void GLClearError() +{ + while(glGetError() != GL_NO_ERROR); +} + +bool GLLogCall(const char * function, const char * file, int line) +{ + GLenum error; + while((error = glGetError()) != GL_NO_ERROR) { + LV_LOG_ERROR("[OpenGL Error] (%d) %s %s:%d\n", error, function, file, line); + return false; + } + return true; +} + +#endif /* LV_USE_OPENGLES */ diff --git a/src/drivers/glfw/lv_opengles_debug.h b/src/drivers/glfw/lv_opengles_debug.h new file mode 100644 index 000000000..2d1fa31ac --- /dev/null +++ b/src/drivers/glfw/lv_opengles_debug.h @@ -0,0 +1,38 @@ +/** + * @file lv_opengles_debug.h + * + */ + +#ifndef LV_OPENGLES_DEBUG_H +#define LV_OPENGLES_DEBUG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#if LV_USE_OPENGLES + +#include +#include + +void GLClearError(void); + +bool GLLogCall(const char * function, const char * file, int line); + +#if LV_USE_OPENGLES_DEBUG +#define GL_CALL(x) GLClearError();\ + x;\ + GLLogCall(#x, __FILE__, __LINE__) +#else +#define GL_CALL(x) x +#endif + +#endif /* LV_USE_OPENGLES */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_OPENGLES_DEBUG_H */ diff --git a/src/drivers/glfw/lv_opengles_driver.c b/src/drivers/glfw/lv_opengles_driver.c new file mode 100644 index 000000000..cb8901070 --- /dev/null +++ b/src/drivers/glfw/lv_opengles_driver.c @@ -0,0 +1,447 @@ +/** + * @file lv_opengles_driver.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "../../display/lv_display.h" + +#if LV_USE_OPENGLES + +#include +#include +#include +#include +#include "lv_opengles_debug.h" +#include "lv_opengles_driver.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void lv_opengles_vertex_buffer_init(const void * data, unsigned int size); +static void lv_opengles_vertex_buffer_deinit(void); +static void lv_opengles_vertex_buffer_bind(void); +static void lv_opengles_vertex_buffer_unbind(void); +static void lv_opengles_vertex_array_init(void); +static void lv_opengles_vertex_array_deinit(void); +static void lv_opengles_vertex_array_bind(void); +static void lv_opengles_vertex_array_unbind(void); +static void lv_opengles_vertex_array_add_buffer(void); +static void lv_opengles_index_buffer_init(const unsigned int * data, unsigned int count); +static void lv_opengles_index_buffer_deinit(void); +static unsigned int lv_opengles_index_buffer_get_count(void); +static void lv_opengles_index_buffer_bind(void); +static void lv_opengles_index_buffer_unbind(void); +static void lv_opengles_render_clear(void); +static unsigned int lv_opengles_shader_compile(unsigned int type, const char * source); +static unsigned int lv_opengles_shader_create(const char * vertexShader, const char * fragmentShader); +static void lv_opengles_shader_init(void); +static void lv_opengles_shader_deinit(void); +static void lv_opengles_shader_bind(void); +static void lv_opengles_shader_unbind(void); +static int lv_opengles_shader_get_uniform_location(const char * name); +static void lv_opengles_shader_set_uniform1i(const char * name, int value); +static void lv_opengles_shader_set_uniform4f(const char * name, float v0, float v1, float v2, float v3); +static void lv_opengles_render_draw(void); +static void lv_opengles_texture_init(void * buffer, int width, int height); +static void lv_opengles_texture_deinit(void); +static void lv_opengles_texture_bind(unsigned int slot); +static void lv_opengles_texture_update(void * buffer, int width, int height); + +/*********************** + * GLOBAL PROTOTYPES + ***********************/ + +/********************** + * STATIC VARIABLES + **********************/ +static unsigned int vertex_buffer_id = 0; + +static unsigned int vertex_array_id = 0; + +static unsigned int index_buffer_id = 0; +static unsigned int index_buffer_count = 0; + +static unsigned int texture_id = 0; + +static unsigned int shader_id; + +static const char * shader_names[] = { "u_Color", "u_Texture", "u_ColorDepth" }; +static int shader_location[] = { 0, 0, 0 }; + +static const char * vertex_shader = + "#version 300 es\n" + "\n" + "in vec4 position;\n" + "in vec2 texCoord;\n" + "\n" + "out vec2 v_TexCoord;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = position;\n" + " v_TexCoord = texCoord;\n" + "};\n"; + +static const char * fragment_shader = + "#version 300 es\n" + "\n" + "precision mediump float;\n" + "\n" + "layout(location = 0) out vec4 color;\n" + "\n" + "in vec2 v_TexCoord;\n" + "\n" + "uniform vec4 u_Color;\n" + "uniform sampler2D u_Texture;\n" + "uniform int u_ColorDepth;\n" + "\n" + "void main()\n" + "{\n" + " vec4 texColor = texture(u_Texture, v_TexCoord);\n" + " if (u_ColorDepth == 8) {\n" + " float gray = texColor.r;\n" + " color = vec4(gray, gray, gray, 1.0);\n" + " } else {\n" + " color = texColor;\n" + " }\n" + "};\n"; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_opengles_init(uint8_t * frame_buffer, int32_t hor, int32_t ver) +{ + float positions[] = { + -1.0f, 1.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 1.0f + }; + + unsigned int indices[] = { + 0, 1, 2, + 2, 3, 0 + }; + + lv_opengles_vertex_buffer_init(positions, 4 * 4 * sizeof(float)); + + lv_opengles_vertex_array_init(); + lv_opengles_vertex_array_add_buffer(); + + lv_opengles_index_buffer_init(indices, 6); + + lv_opengles_shader_init(); + lv_opengles_shader_bind(); + lv_opengles_shader_set_uniform1i("u_ColorDepth", LV_COLOR_DEPTH); + lv_opengles_shader_set_uniform4f("u_Color", 0.8f, 0.3f, 0.8f, 1.0f); + + int slot = 0; + lv_opengles_texture_init(frame_buffer, hor, ver); + lv_opengles_texture_bind(slot); + + lv_opengles_shader_set_uniform1i("u_Texture", slot); + + /* unbound everything */ + lv_opengles_vertex_array_unbind(); + lv_opengles_vertex_buffer_unbind(); + lv_opengles_index_buffer_unbind(); + lv_opengles_shader_unbind(); +} + +void lv_opengles_deinit(void) +{ + lv_opengles_texture_deinit(); + lv_opengles_shader_deinit(); + lv_opengles_index_buffer_deinit(); + lv_opengles_vertex_buffer_deinit(); + lv_opengles_vertex_array_deinit(); +} + +void lv_opengles_update(uint8_t * frame_buffer, int32_t hor, int32_t ver) +{ + lv_opengles_render_clear(); + lv_opengles_texture_update(frame_buffer, hor, ver); + + lv_opengles_shader_bind(); + lv_opengles_shader_set_uniform1i("u_ColorDepth", LV_COLOR_DEPTH); + lv_opengles_shader_set_uniform4f("u_Color", 0.0f, 0.3f, 0.8f, 1.0f); + lv_opengles_render_draw(); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_opengles_vertex_buffer_init(const void * data, unsigned int size) +{ + GL_CALL(glGenBuffers(1, &vertex_buffer_id)); + GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id)); + GL_CALL(glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW)); +} + +static void lv_opengles_vertex_buffer_deinit() +{ + GL_CALL(glDeleteBuffers(1, &vertex_buffer_id)); +} + +static void lv_opengles_vertex_buffer_bind() +{ + GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id)); +} + +static void lv_opengles_vertex_buffer_unbind() +{ + GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, 0)); +} + +static void lv_opengles_vertex_array_init() +{ + GL_CALL(glGenVertexArrays(1, &vertex_array_id)); +} + +static void lv_opengles_vertex_array_deinit() +{ + GL_CALL(glDeleteVertexArrays(1, &vertex_array_id)); +} + +static void lv_opengles_vertex_array_bind() +{ + GL_CALL(glBindVertexArray(vertex_array_id)); +} + +static void lv_opengles_vertex_array_unbind() +{ + GL_CALL(glBindVertexArray(0)); +} + +static void lv_opengles_vertex_array_add_buffer() +{ + lv_opengles_vertex_buffer_bind(); + intptr_t offset = 0; + + for(unsigned int i = 0; i < 2; i++) { + lv_opengles_vertex_array_bind(); + GL_CALL(glEnableVertexAttribArray(i)); + GL_CALL(glVertexAttribPointer(i, 2, GL_FLOAT, GL_FALSE, 16, (const void *)offset)); + offset += 2 * 4; + } +} + +static void lv_opengles_index_buffer_init(const unsigned int * data, unsigned int count) +{ + index_buffer_count = count; + GL_CALL(glGenBuffers(1, &index_buffer_id)); + + GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_id)); + + GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(GLuint), data, GL_STATIC_DRAW)); +} + +static void lv_opengles_index_buffer_deinit() +{ + GL_CALL(glDeleteBuffers(1, &index_buffer_id)); +} + +static unsigned int lv_opengles_index_buffer_get_count() +{ + return index_buffer_count; +} + +static void lv_opengles_index_buffer_bind() +{ + GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_id)); +} + +static void lv_opengles_index_buffer_unbind() +{ + GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); +} + +static void lv_opengles_render_clear() +{ + GL_CALL(glClear(GL_COLOR_BUFFER_BIT)); +} + +static unsigned int lv_opengles_shader_compile(unsigned int type, const char * source) +{ + GL_CALL(unsigned int id = glCreateShader(type)); + const char * src = source; + GL_CALL(glShaderSource(id, 1, &src, NULL)); + GL_CALL(glCompileShader(id)); + + int result; + GL_CALL(glGetShaderiv(id, GL_COMPILE_STATUS, &result)); + if(result == GL_FALSE) { + int length; + GL_CALL(glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length)); + char * message = lv_malloc_zeroed(length * sizeof(char)); + GL_CALL(glGetShaderInfoLog(id, length, &length, message)); + LV_LOG_ERROR("Failed to compile %s shader!\n", type == GL_VERTEX_SHADER ? "vertex" : "fragment"); + LV_LOG_ERROR("%s\n", message); + GL_CALL(glDeleteShader(id)); + return 0; + } + + return id; +} + +static unsigned int lv_opengles_shader_create(const char * vertexShader, const char * fragmentShader) +{ + GL_CALL(unsigned int program = glCreateProgram()); + unsigned int vs = lv_opengles_shader_compile(GL_VERTEX_SHADER, vertexShader); + unsigned int fs = lv_opengles_shader_compile(GL_FRAGMENT_SHADER, fragmentShader); + + GL_CALL(glAttachShader(program, vs)); + GL_CALL(glAttachShader(program, fs)); + GL_CALL(glLinkProgram(program)); + GL_CALL(glValidateProgram(program)); + + GL_CALL(glDeleteShader(vs)); + GL_CALL(glDeleteShader(fs)); + + return program; +} + +static void lv_opengles_shader_init() +{ + shader_id = lv_opengles_shader_create(vertex_shader, fragment_shader); +} + +static void lv_opengles_shader_deinit() +{ + GL_CALL(glDeleteProgram(shader_id)); +} + +static void lv_opengles_shader_bind() +{ + GL_CALL(glUseProgram(shader_id)); +} + +static void lv_opengles_shader_unbind() +{ + GL_CALL(glUseProgram(0)); +} + +static int lv_opengles_shader_get_uniform_location(const char * name) +{ + int id = -1; + for(size_t i = 0; i < sizeof(shader_location) / sizeof(int); i++) { + if(strcmp(shader_names[i], name) == 0) { + id = i; + } + } + if(id == -1) { + return -1; + } + + if(shader_location[id] != 0) { + return shader_location[id]; + } + + GL_CALL(int location = glGetUniformLocation(shader_id, name)); + if(location == -1) + LV_LOG_WARN("Warning: uniform '%s' doesn't exist!\n", name); + + shader_location[id] = location; + return location; +} + +static void lv_opengles_shader_set_uniform1i(const char * name, int value) +{ + GL_CALL(glUniform1i(lv_opengles_shader_get_uniform_location(name), value)); +} + +static void lv_opengles_shader_set_uniform4f(const char * name, float v0, float v1, float v2, float v3) +{ + GL_CALL(glUniform4f(lv_opengles_shader_get_uniform_location(name), v0, v1, v2, v3)); +} + +static void lv_opengles_render_draw() +{ + lv_opengles_shader_bind(); + lv_opengles_vertex_array_bind(); + lv_opengles_index_buffer_bind(); + unsigned int count = lv_opengles_index_buffer_get_count(); + GL_CALL(glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, NULL)); +} + +static void lv_opengles_texture_init(void * buffer, int width, int height) +{ + if(buffer == NULL) { + return; + } + + GL_CALL(glGenTextures(1, &texture_id)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, texture_id)); + + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + + GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + + /*Color depth: 8 (A8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/ +#if LV_COLOR_DEPTH == 8 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, buffer)); +#elif LV_COLOR_DEPTH == 16 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, width, height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, buffer)); +#elif LV_COLOR_DEPTH == 24 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, buffer)); +#elif LV_COLOR_DEPTH == 32 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer)); +#else +#error("Unsupported color format") +#endif + + GL_CALL(glBindTexture(GL_TEXTURE_2D, 0)); +} + +static void lv_opengles_texture_deinit() +{ + GL_CALL(glDeleteTextures(1, &texture_id)); + texture_id = 0; +} + +static void lv_opengles_texture_bind(unsigned int slot) +{ + GL_CALL(glActiveTexture(GL_TEXTURE0 + slot)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, texture_id)); +} + +static void lv_opengles_texture_update(void * buffer, int width, int height) +{ + GL_CALL(glBindTexture(GL_TEXTURE_2D, texture_id)); + + GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + /*Color depth: 8 (A8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/ +#if LV_COLOR_DEPTH == 8 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, buffer)); +#elif LV_COLOR_DEPTH == 16 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, width, height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, buffer)); +#elif LV_COLOR_DEPTH == 24 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, buffer)); +#elif LV_COLOR_DEPTH == 32 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer)); +#else +#error("Unsupported color format") +#endif +} + +#endif /* LV_USE_OPENGLES */ diff --git a/src/drivers/glfw/lv_opengles_driver.h b/src/drivers/glfw/lv_opengles_driver.h new file mode 100644 index 000000000..c6fe31228 --- /dev/null +++ b/src/drivers/glfw/lv_opengles_driver.h @@ -0,0 +1,27 @@ +/** + * @file lv_opengles_driver.h + * + */ + +#ifndef LV_OPENGLES_DRIVER_H +#define LV_OPENGLES_DRIVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if LV_USE_OPENGLES + +void lv_opengles_init(uint8_t * frame_buffer, int32_t hor, int32_t ver); + +void lv_opengles_update(uint8_t * frame_buffer, int32_t hor, int32_t ver); + +void lv_opengles_deinit(void); + +#endif /* LV_USE_OPENGLES */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_OPENGLES_DRIVER_H */ diff --git a/src/drivers/lv_drivers.h b/src/drivers/lv_drivers.h index f07e000d5..f7f2e2ac1 100644 --- a/src/drivers/lv_drivers.h +++ b/src/drivers/lv_drivers.h @@ -37,6 +37,9 @@ extern "C" { #include "windows/lv_windows_input.h" #include "windows/lv_windows_display.h" +#include "glfw/lv_glfw_window.h" +#include "glfw/lv_glfw_mouse.h" + /********************* * DEFINES *********************/ diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index 134c48e7f..5040fabb6 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -3191,6 +3191,28 @@ #endif #endif +/* Use OpenGL to open window on PC and handle mouse and keyboard */ +#ifndef LV_USE_OPENGLES + #ifdef CONFIG_LV_USE_OPENGLES + #define LV_USE_OPENGLES CONFIG_LV_USE_OPENGLES + #else + #define LV_USE_OPENGLES 0 + #endif +#endif +#if LV_USE_OPENGLES + #ifndef LV_USE_OPENGLES_DEBUG + #ifdef _LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_OPENGLES_DEBUG + #define LV_USE_OPENGLES_DEBUG CONFIG_LV_USE_OPENGLES_DEBUG + #else + #define LV_USE_OPENGLES_DEBUG 0 + #endif + #else + #define LV_USE_OPENGLES_DEBUG 1 /* Enable or disable debug for opengles */ + #endif + #endif +#endif + /*================== * EXAMPLES *==================*/ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index bc5d3084d..89cf4c3a2 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -336,6 +336,18 @@ if ($ENV{NON_AMD64_BUILD}) include_directories(${LIBINPUT_INCLUDE_DIRS}) endif() +# OpenGL ES is required for its driver +if (NOT $ENV{NON_AMD64_BUILD}) + find_package(OpenGL REQUIRED) + find_package(GLEW REQUIRED) + find_package(glfw3 REQUIRED) + + # Include directories + include_directories(${OPENGL_INCLUDE_DIR}) + include_directories(${GLEW_INCLUDE_DIRS}) + include_directories(${GLFW_INCLUDE_DIRS}) +endif() + if (NOT LIBINPUT_FOUND) message("libinput not found, defaulting to 0") add_definitions(-DLV_USE_LIBINPUT=0) @@ -423,6 +435,13 @@ foreach( test_case_fname ${TEST_CASE_FILES} ) m pthread ${TEST_LIBS}) + + if (NOT $ENV{NON_AMD64_BUILD}) + target_link_libraries(${test_name} PRIVATE + ${OPENGL_LIBRARIES} ${GLEW_LIBRARIES} glfw) + endif() + + target_include_directories(${test_name} PUBLIC ${TEST_INCLUDE_DIRS}) target_compile_options(${test_name} PUBLIC ${LVGL_TESTFILE_COMPILE_OPTIONS}) diff --git a/tests/src/lv_test_conf_full.h b/tests/src/lv_test_conf_full.h index 0b995dba1..8be882645 100644 --- a/tests/src/lv_test_conf_full.h +++ b/tests/src/lv_test_conf_full.h @@ -134,6 +134,10 @@ #define LV_LIBINPUT_XKB 1 #endif +#if !defined(NON_AMD64_BUILD) && !defined(_MSC_VER) && !defined(_WIN32) + #define LV_USE_OPENGLES 1 +#endif + #define LV_USE_FREETYPE 1 #define LV_FREETYPE_USE_LVGL_PORT 0 #define LV_FREETYPE_CACHE_FT_GLYPH_CNT 10