lvgl 8.3.0和lv_drivers 8.3下编译支持wayland
本方法参考yocto中的lvgl,dialog-lvgl,lv-drivers这三个recipe,将lvgl输出到weston是种较为简单的利用硬件加速方案,这里就是由于在高分辨率下要进行旋转,导致纯软件效果不佳,所以需要利用上硬件加速。
1.获取源码
dialog-lvgl
https://git.ostc-eu.org/rzr/dialog-lvgl
lvgl
https://github.com/lvgl/lvgl
lv-drivers
https://github.com/lvgl/lv_drivers
相关源码可以从以上3个网址获取
2.编译环境
本编译环境使用带有weston的yocto工程生成的SDK包,环境变量相关设置通过source SDK包的配置环境文件来配置,不需要额外设置编译器以及环境变量。
需要确认环境中有以下几个库:
libwayland-cursor.so
libwayland-client.so
libxkbcommon.so //应该是XDG_SHELL相关的,这里用WL_SHELL,应该用不上
初始文件目录参考
cwf@cwf-virtual-machine:~/lvgl_wayland/lvgl_wayland_new$ tree -L 1
.
├── dialog-lvgl-main
├── lv_drivers-8.3.0
├── lvgl-8.3.0
└── README.md
整体流程
(1)lvgl用cmake编译出liblvgl.a
(2)lv_drivers用cmake编译出liblv_drivers.a
(3)dialog_lvgl用makefile链接相关库,编译出执行文件
3.lvgl 8.3.0 编译
输入以下命令
cd lvgl-8.3.0
cp lv_conf_template.h lv_conf.h
mkdir build
修改lv_conf.h
第一处:修改"#if 0"为"#if 1"
...
/* clang-format off */
#if 1 /*Set it to "1" to enable content*/
#ifndef LV_CONF_H
#define LV_CONF_H
...
第二处:修改LV_MEM_SIZE大小,由于wayland会分配等同于屏幕分辨率尺寸的buffer,所以要大于分辨率色深,大多少就根据控件决定,
我这里分辨率为19201200,内存也还充足,分配20U *1024U * 1024U
...
/*1: use custom malloc/free, 0: use the built-in `lv_mem_alloc()` and `lv_mem_free()`*/
#define LV_MEM_CUSTOM 0
#if LV_MEM_CUSTOM == 0
/*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/
#define LV_MEM_SIZE (20U *1024U * 1024U) /*[bytes]*/
/*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/
#define LV_MEM_ADR 0 /*0: unused*/
...
第三处: 修改色深
#define LV_COLOR_DEPTH 32
第四处(可选):添加 #define LV_INV_BUF_SIZE 1,不修改可能会出现动画播放有部分未显示,或有残留动画。由于wayland驱动在一帧中处理多个局部刷新时,当调用wl_surface_commit后,lv_drivers唯一的一个wl_buffer便会进入busy状态,将可能导致后续的局部刷新被lv_drivers忽视,但这部分对lvgl而言是已经更新了,对weston而言是未更新的。(后面删除掉buffer->busy这部分就可以不添加)
#define LV_INV_BUF_SIZE 1
第五处(可选):添加demo支持,这里添加LV_USE_DEMO_WIDGETS和LV_USE_DEMO_BENCHMARK
/*Show some widget. It might be required to increase `LV_MEM_SIZE` */
#define LV_USE_DEMO_WIDGETS 1
#if LV_USE_DEMO_WIDGETS
#define LV_DEMO_WIDGETS_SLIDESHOW 0
#endif
/*Demonstrate the usage of encoder and keyboard*/
#define LV_USE_DEMO_KEYPAD_AND_ENCODER 0
/*Benchmark your system*/
#define LV_USE_DEMO_BENCHMARK 1
#if LV_USE_DEMO_BENCHMARK
/*Use RGB565A8 images with 16 bit color depth instead of ARGB8565*/
#define LV_DEMO_BENCHMARK_RGB565A8 0
#endif
/*Stress test for LVGL*/
#define LV_USE_DEMO_STRESS 0
/*Music player demo*/
#define LV_USE_DEMO_MUSIC 0
#if LV_USE_DEMO_MUSIC
#define LV_DEMO_MUSIC_SQUARE 0
#define LV_DEMO_MUSIC_LANDSCAPE 0
#define LV_DEMO_MUSIC_ROUND 0
#define LV_DEMO_MUSIC_LARGE 0
#define LV_DEMO_MUSIC_AUTO_PLAY 0
#endif
修改env_support/custom.cmake(可选)
这里添加了liblvgl_demos.a的编译,方便后续编译demos
# Option to define LV_LVGL_H_INCLUDE_SIMPLE, default: ON
option(LV_LVGL_H_INCLUDE_SIMPLE
"Use #include \"lvgl.h\" instead of #include \"../../lvgl.h\"" ON)
# Option to define LV_CONF_INCLUDE_SIMPLE, default: ON
option(LV_CONF_INCLUDE_SIMPLE
"Simple include of \"lv_conf.h\" and \"lv_drv_conf.h\"" ON)
# Option to set LV_CONF_PATH, if set parent path LV_CONF_DIR is added to
# includes
option(LV_CONF_PATH "Path defined for lv_conf.h")
get_filename_component(LV_CONF_DIR ${LV_CONF_PATH} DIRECTORY)
# Option to build shared libraries (as opposed to static), default: OFF
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
file(GLOB_RECURSE SOURCES ${LVGL_ROOT_DIR}/src/*.c)
file(GLOB_RECURSE EXAMPLE_SOURCES ${LVGL_ROOT_DIR}/examples/*.c)
file(GLOB_RECURSE DEMO_SOURCES ${LVGL_ROOT_DIR}/demos/*.c)
if (BUILD_SHARED_LIBS)
add_library(lvgl SHARED ${SOURCES})
else()
add_library(lvgl STATIC ${SOURCES})
endif()
add_library(lvgl::lvgl ALIAS lvgl)
add_library(lvgl_examples STATIC ${EXAMPLE_SOURCES})
add_library(lvgl::examples ALIAS lvgl_examples)
add_library(lvgl_demos STATIC ${DEMO_SOURCES})
add_library(lvgl::demos ALIAS lvgl_demos)
target_compile_definitions(
lvgl PUBLIC $<$<BOOL:${LV_LVGL_H_INCLUDE_SIMPLE}>:LV_LVGL_H_INCLUDE_SIMPLE>
$<$<BOOL:${LV_CONF_INCLUDE_SIMPLE}>:LV_CONF_INCLUDE_SIMPLE>)
# Include root and optional parent path of LV_CONF_PATH
target_include_directories(lvgl SYSTEM PUBLIC ${LVGL_ROOT_DIR} ${LV_CONF_DIR})
# Include /examples folder
target_include_directories(lvgl_examples SYSTEM
PUBLIC ${LVGL_ROOT_DIR}/examples)
target_include_directories(lvgl_demos SYSTEM
PUBLIC ${LVGL_ROOT_DIR}/demos)
target_link_libraries(lvgl_examples PUBLIC lvgl)
target_link_libraries(lvgl_demos PUBLIC lvgl)
# Lbrary and headers can be installed to system using make install
file(GLOB LVGL_PUBLIC_HEADERS "${CMAKE_SOURCE_DIR}/lv_conf.h"
"${CMAKE_SOURCE_DIR}/lvgl.h")
if("${LIB_INSTALL_DIR}" STREQUAL "")
set(LIB_INSTALL_DIR "lib")
endif()
if("${INC_INSTALL_DIR}" STREQUAL "")
set(INC_INSTALL_DIR "include/lvgl")
endif()
install(
DIRECTORY "${CMAKE_SOURCE_DIR}/src"
DESTINATION "${CMAKE_INSTALL_PREFIX}/${INC_INSTALL_DIR}/"
FILES_MATCHING
PATTERN "*.h")
install(
DIRECTORY "${CMAKE_SOURCE_DIR}/demos"
DESTINATION "${CMAKE_INSTALL_PREFIX}/${INC_INSTALL_DIR}/"
FILES_MATCHING
PATTERN "*.h")
set_target_properties(
lvgl
PROPERTIES OUTPUT_NAME lvgl
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
PUBLIC_HEADER "${LVGL_PUBLIC_HEADERS}")
set_target_properties(
lvgl_demos
PROPERTIES OUTPUT_NAME lvgl_demos
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
PUBLIC_HEADER "${LVGL_PUBLIC_HEADERS}")
install(
TARGETS lvgl
ARCHIVE DESTINATION "${LIB_INSTALL_DIR}"
LIBRARY DESTINATION "${LIB_INSTALL_DIR}"
RUNTIME DESTINATION "${LIB_INSTALL_DIR}"
PUBLIC_HEADER DESTINATION "${INC_INSTALL_DIR}")
install(
TARGETS lvgl_demos
ARCHIVE DESTINATION "${LIB_INSTALL_DIR}"
LIBRARY DESTINATION "${LIB_INSTALL_DIR}"
RUNTIME DESTINATION "${LIB_INSTALL_DIR}"
PUBLIC_HEADER DESTINATION "${INC_INSTALL_DIR}")
编译lvgl 8.3.0
cd build
cmake .. -DLIB_INSTALL_DIR=/home/cwf/lvgl_wayland/lvgl_wayland_new/lib -DCMAKE_INSTALL_PREFIX=/home/cwf/lvgl_wayland/lvgl_wayland_new
make -j8
make install
LIB_INSTALL_DIR为lib安装目录
CMAKE_INSTALL_PREFIX为头文件安装目录
这两个目录最后编译dialog_lvgl会用上,可以按照自己的情况设置
4.lv_drivers 8.3 编译
输入以下命令
cd lv_drivers-8.3.0
cp lv_drv_conf_template.h lv_drv_conf.h
mkdir build
修改lv_drv_conf.h
第一处:修改"#if 0"为"#if 1"
...
/* clang-format off */
#if 1 /*Set it to "1" to enable the content*/
#ifndef LV_DRV_CONF_H
#define LV_DRV_CONF_H
...
第二处:修改#define USE_WAYLAND 1,以及#define LV_WAYLAND_CLIENT_SIDE_DECORATIONS 0, 并添加define LV_WAYLAND_TIMER_HANDLER
...
/*----------------------------------------
* Wayland drivers (monitor, mouse, keyboard, touchscreen)
*---------------------------------------*/
#ifndef USE_WAYLAND
# define USE_WAYLAND 1
#endif
#if USE_WAYLAND
# define LV_WAYLAND_TIMER_HANDLER
/* Support for client-side decorations */
# ifndef LV_WAYLAND_CLIENT_SIDE_DECORATIONS
# define LV_WAYLAND_CLIENT_SIDE_DECORATIONS 0
# endif
/* Support for (deprecated) wl-shell protocol */
# ifndef LV_WAYLAND_WL_SHELL
# define LV_WAYLAND_WL_SHELL 1
# endif
/* Support for xdg-shell protocol */
# ifndef LV_WAYLAND_XDG_SHELL
# define LV_WAYLAND_XDG_SHELL 0
# endif
#endif
...
修改wayland.c
将以下部分屏注释掉
else if (buffer->busy)
{
LV_LOG_WARN("skip flush since wayland backing buffer is busy");
printf("skip flush since wayland backing buffer is busy\n");
lv_disp_flush_ready(disp_drv);
return;
}
修改CMakeLists.txt
这里的修改主要是修改了头文件路径
cmake_minimum_required(VERSION 3.12.4)
project(lv_drivers HOMEPAGE_URL https://github.com/lvgl/lv_drivers/)
# Option to build as shared library (as opposed to static), default: OFF
option(BUILD_SHARED_LIBS "Build shared as library (as opposed to static)" OFF)
file(GLOB_RECURSE SOURCES ./*.c)
if (BUILD_SHARED_LIBS)
add_library(lv_drivers SHARED ${SOURCES})
else()
add_library(lv_drivers STATIC ${SOURCES})
endif()
add_library(lvgl_drivers ALIAS lv_drivers)
add_library(lvgl::drivers ALIAS lv_drivers)
target_include_directories(lv_drivers SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
include_directories(/home/cwf/lvgl_wayland/lvgl_wayland/include/lvgl)
include_directories(/home/cwf/lvgl_wayland/lvgl_wayland/include)
add_definitions(-DLV_CONF_INCLUDE_SIMPLE=1)
set(PKG_WAYLAND_LIBRARIES ${CXX})
find_package(PkgConfig)
pkg_check_modules(PKG_WAYLAND wayland-client wayland-cursor wayland-protocols xkbcommon)
target_link_libraries(lv_drivers PUBLIC lvgl ${PKG_WAYLAND_LIBRARIES})
if("${LIB_INSTALL_DIR}" STREQUAL "")
set(LIB_INSTALL_DIR "lib")
endif()
if("${INC_INSTALL_DIR}" STREQUAL "")
set(INC_INSTALL_DIR "include/lvgl/lv_drivers")
endif()
install(
DIRECTORY "${CMAKE_SOURCE_DIR}/"
DESTINATION "${CMAKE_INSTALL_PREFIX}/${INC_INSTALL_DIR}"
FILES_MATCHING
PATTERN "*.h"
PATTERN ".git*" EXCLUDE
PATTERN "CMakeFiles" EXCLUDE
PATTERN "docs" EXCLUDE
PATTERN "lib" EXCLUDE
PATTERN "build" EXCLUDE)
file(GLOB LV_DRIVERS_PUBLIC_HEADERS "${CMAKE_SOURCE_DIR}/lv_drv_conf.h")
set_target_properties(
lv_drivers
PROPERTIES OUTPUT_NAME lv_drivers
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
PUBLIC_HEADER "${LV_DRIVERS_PUBLIC_HEADERS}")
install(
TARGETS lv_drivers
ARCHIVE DESTINATION "${LIB_INSTALL_DIR}"
LIBRARY DESTINATION "${LIB_INSTALL_DIR}"
RUNTIME DESTINATION "${LIB_INSTALL_DIR}"
PUBLIC_HEADER DESTINATION "${INC_INSTALL_DIR}")
编译 lv_drivers 8.3.0
cmake .. -DLIB_INSTALL_DIR=/home/cwf/lvgl_wayland/lvgl_wayland_new/lib -DCMAKE_INSTALL_PREFIX=/home/cwf/lvgl_wayland/lvgl_wayland_new
make -j8
make install
5.编译dialog-lvgl
对于dialog-lvgl这个工程,可以用其他工程替换,这里基本就用到makefile里面的获取头文件,链接库,获取全部源文件并编译出可执行文件的功能,其他功能基本没用上。
src/drivers/wayland.c 修改
删除或注释掉原来的void hal_init(void),修改成以下内容
#define H_RES (1920)
#define V_RES (1200)
void hal_init(void)
{
static pthread_t hal_thread;
lv_disp_t * disp;
lv_wayland_init();
disp = lv_wayland_create_window(H_RES, V_RES, "Window Title", NULL);
// lv_wayland_window_set_fullscreen(disp, true);
pthread_create(&hal_thread, NULL, tick_thread, NULL);
}
src/os/linux/main.c 修改
一般方法
#include "lvgl/demos/lv_demos.h"
int main(int argc, char ** argv)
{
if((argc > 1) && strcmp(argv[1], "--help") == 0) {
usage(argc, argv);
return 0;
}
lv_init();
hal_init();
// ui_init(argc, argv);
// lv_demo_benchmark();
lv_demo_widgets();
pfd.fd = lv_wayland_get_fd();
pfd.events = POLLIN;
while(1) {
lv_timer_handler();
usleep(5 * 1000);
}
return 0;
}
poll方法
修改while(1)逻辑,按lv_drivers的wayland里的推荐,使用poll方法,同时使用上demo
#include <limits.h>
#include <errno.h>
#include <poll.h>
#include "lvgl/demos/lv_demos.h"
int main(int argc, char ** argv)
{
if((argc > 1) && strcmp(argv[1], "--help") == 0) {
usage(argc, argv);
return 0;
}
struct pollfd pfd;
uint32_t time_till_next;
int sleep;
lv_init();
hal_init();
// ui_init(argc, argv);
// lv_demo_benchmark();
lv_demo_widgets();
pfd.fd = lv_wayland_get_fd();
pfd.events = POLLIN;
// while(1) {
// lv_timer_handler();
// usleep(5 * 1000);
// }
while(1) {
/* Handle any Wayland/LVGL timers/events */
time_till_next = lv_wayland_timer_handler();
/* Run until the last window closes */
if (!lv_wayland_window_is_open(NULL)) {
break;
}
/* Wait for something interesting to happen */
if (time_till_next == LV_NO_TIMER_READY) {
sleep = -1;
} else if (time_till_next > INT_MAX) {
sleep = INT_MAX;
} else {
sleep = time_till_next;
}
while ((poll(&pfd, 1, sleep) < 0) && (errno == EINTR));
}
return 0;
}
makefile修改
...
lvgl?=lvgl
project?=dialog-${lvgl}
url?=https://git.ostc-eu.org/rzr/dialog-lvgl
cmake_options?=-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON
DESTDIR?=/home/cwf/lvgl_wayland/lvgl_wayland_new
exe?=${project}
#sysroot?=${CURDIR}/tmp/sysroot
sysroot?=/home/cwf/lvgl_wayland/lvgl_wayland_new
prefix?=/usr/local
#includedir?=${prefix}/include
includedir?=/include
base_bindir?=bin
base_libdir?=/lib
# bindir?=${prefix}/${base_bindir}
# libdir?=${prefix}/${base_libdir}
bindir?=${base_bindir}
libdir?=${base_libdir}
os?=linux
srcs+=$(wildcard src/os/${os}/*.c | sort)
srcs+=$(wildcard src/widgets/*.c | sort)
srcs+=src/drivers/${lvgl_driver}.c
objs?=${srcs:.c=.o}
CFLAGS+=-Isrc
CFLAGS+=-I${sysroot}${includedir}/
CFLAGS+=-I${sysroot}${includedir}/lvgl
CFLAGS+=-I${sysroot}${includedir}/lvgl/lv_drivers
LDLIBS+=-L${sysroot}${libdir}
LDLIBS+=-llv_drivers
LDLIBS+=-llvgl
LDLIBS+=-llvgl_demos
LDLIBS+=-lwayland-cursor
V?=1
width?=42
height=${width}
depth?=1
...
编译dialog-lvgl
make install lvgl_driver=wayland
在bin文件夹下便会生成dialog-lvgl