feat(opengles): add basic driver for opengles (#6254)
Co-authored-by: Dany Liu <dany.yang.liu@email.com> Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com>
This commit is contained in:
9
Kconfig
9
Kconfig
@@ -1646,6 +1646,15 @@ menu "LVGL configuration"
|
|||||||
config LV_USE_WINDOWS
|
config LV_USE_WINDOWS
|
||||||
bool "Use LVGL Windows backend"
|
bool "Use LVGL Windows backend"
|
||||||
default n
|
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
|
endmenu
|
||||||
|
|
||||||
menu "Examples"
|
menu "Examples"
|
||||||
|
|||||||
@@ -10,3 +10,4 @@ Drivers
|
|||||||
libinput
|
libinput
|
||||||
X11
|
X11
|
||||||
windows
|
windows
|
||||||
|
opengles
|
||||||
|
|||||||
65
docs/integration/driver/opengles.rst
Normal file
65
docs/integration/driver/opengles.rst
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
===============================
|
||||||
|
OpenGL ES Display/Inputs driver
|
||||||
|
===============================
|
||||||
|
|
||||||
|
Overview
|
||||||
|
--------
|
||||||
|
|
||||||
|
| The **OpenGL ES** display/input `driver <https://github.com/lvgl/lvgl/src/drivers/opengles>`__ 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;
|
||||||
|
}
|
||||||
@@ -978,6 +978,12 @@
|
|||||||
/* LVGL Windows backend */
|
/* LVGL Windows backend */
|
||||||
#define LV_USE_WINDOWS 0
|
#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
|
* EXAMPLES
|
||||||
*==================*/
|
*==================*/
|
||||||
|
|||||||
@@ -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%
|
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||||
pip install pypng lz4
|
pip install pypng lz4
|
||||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ sudo dpkg --add-architecture i386
|
|||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install gcc gcc-multilib g++-multilib ninja-build \
|
sudo apt install gcc gcc-multilib g++-multilib ninja-build \
|
||||||
libpng-dev libjpeg-turbo8-dev libfreetype6-dev \
|
libpng-dev libjpeg-turbo8-dev libfreetype6-dev \
|
||||||
|
libglew-dev libglfw3-dev \
|
||||||
libpng-dev:i386 libjpeg-dev:i386 libfreetype6-dev:i386 \
|
libpng-dev:i386 libjpeg-dev:i386 libfreetype6-dev:i386 \
|
||||||
ruby-full gcovr cmake python3 pngquant libinput-dev libxkbcommon-dev libdrm-dev pkg-config
|
ruby-full gcovr cmake python3 pngquant libinput-dev libxkbcommon-dev libdrm-dev pkg-config
|
||||||
pip3 install pypng lz4
|
pip3 install pypng lz4
|
||||||
|
|||||||
87
src/drivers/glfw/lv_glfw_mouse.c
Normal file
87
src/drivers/glfw/lv_glfw_mouse.c
Normal file
@@ -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 <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#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 */
|
||||||
43
src/drivers/glfw/lv_glfw_mouse.h
Normal file
43
src/drivers/glfw/lv_glfw_mouse.h
Normal file
@@ -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 */
|
||||||
89
src/drivers/glfw/lv_glfw_mouse_private.c
Normal file
89
src/drivers/glfw/lv_glfw_mouse_private.c
Normal file
@@ -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 <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#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 */
|
||||||
52
src/drivers/glfw/lv_glfw_mouse_private.h
Normal file
52
src/drivers/glfw/lv_glfw_mouse_private.h
Normal file
@@ -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 */
|
||||||
379
src/drivers/glfw/lv_glfw_window.c
Normal file
379
src/drivers/glfw/lv_glfw_window.c
Normal file
@@ -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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <memory.h>
|
||||||
|
#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 <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#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*/
|
||||||
46
src/drivers/glfw/lv_glfw_window.h
Normal file
46
src/drivers/glfw/lv_glfw_window.h
Normal file
@@ -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 */
|
||||||
57
src/drivers/glfw/lv_opengles_debug.c
Normal file
57
src/drivers/glfw/lv_opengles_debug.c
Normal file
@@ -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 */
|
||||||
38
src/drivers/glfw/lv_opengles_debug.h
Normal file
38
src/drivers/glfw/lv_opengles_debug.h
Normal file
@@ -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 <stdbool.h>
|
||||||
|
|
||||||
|
#if LV_USE_OPENGLES
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
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 */
|
||||||
447
src/drivers/glfw/lv_opengles_driver.c
Normal file
447
src/drivers/glfw/lv_opengles_driver.c
Normal file
@@ -0,0 +1,447 @@
|
|||||||
|
/**
|
||||||
|
* @file lv_opengles_driver.c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* INCLUDES
|
||||||
|
*********************/
|
||||||
|
#include "../../display/lv_display.h"
|
||||||
|
|
||||||
|
#if LV_USE_OPENGLES
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#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 */
|
||||||
27
src/drivers/glfw/lv_opengles_driver.h
Normal file
27
src/drivers/glfw/lv_opengles_driver.h
Normal file
@@ -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 */
|
||||||
@@ -37,6 +37,9 @@ extern "C" {
|
|||||||
#include "windows/lv_windows_input.h"
|
#include "windows/lv_windows_input.h"
|
||||||
#include "windows/lv_windows_display.h"
|
#include "windows/lv_windows_display.h"
|
||||||
|
|
||||||
|
#include "glfw/lv_glfw_window.h"
|
||||||
|
#include "glfw/lv_glfw_mouse.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
|
|||||||
@@ -3191,6 +3191,28 @@
|
|||||||
#endif
|
#endif
|
||||||
#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
|
* EXAMPLES
|
||||||
*==================*/
|
*==================*/
|
||||||
|
|||||||
@@ -336,6 +336,18 @@ if ($ENV{NON_AMD64_BUILD})
|
|||||||
include_directories(${LIBINPUT_INCLUDE_DIRS})
|
include_directories(${LIBINPUT_INCLUDE_DIRS})
|
||||||
endif()
|
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)
|
if (NOT LIBINPUT_FOUND)
|
||||||
message("libinput not found, defaulting to 0")
|
message("libinput not found, defaulting to 0")
|
||||||
add_definitions(-DLV_USE_LIBINPUT=0)
|
add_definitions(-DLV_USE_LIBINPUT=0)
|
||||||
@@ -423,6 +435,13 @@ foreach( test_case_fname ${TEST_CASE_FILES} )
|
|||||||
m
|
m
|
||||||
pthread
|
pthread
|
||||||
${TEST_LIBS})
|
${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_include_directories(${test_name} PUBLIC ${TEST_INCLUDE_DIRS})
|
||||||
target_compile_options(${test_name} PUBLIC ${LVGL_TESTFILE_COMPILE_OPTIONS})
|
target_compile_options(${test_name} PUBLIC ${LVGL_TESTFILE_COMPILE_OPTIONS})
|
||||||
|
|
||||||
|
|||||||
@@ -134,6 +134,10 @@
|
|||||||
#define LV_LIBINPUT_XKB 1
|
#define LV_LIBINPUT_XKB 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(NON_AMD64_BUILD) && !defined(_MSC_VER) && !defined(_WIN32)
|
||||||
|
#define LV_USE_OPENGLES 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#define LV_USE_FREETYPE 1
|
#define LV_USE_FREETYPE 1
|
||||||
#define LV_FREETYPE_USE_LVGL_PORT 0
|
#define LV_FREETYPE_USE_LVGL_PORT 0
|
||||||
#define LV_FREETYPE_CACHE_FT_GLYPH_CNT 10
|
#define LV_FREETYPE_CACHE_FT_GLYPH_CNT 10
|
||||||
|
|||||||
Reference in New Issue
Block a user