mirror of
https://github.com/lvgl/lvgl.git
synced 2026-08-17 09:42:19 +08:00
feat(wayland): support falling back between multiple backends (#10430)
This commit is contained in:
@@ -2723,63 +2723,38 @@ config LV_WAYLAND_DIRECT_EXIT
|
||||
help
|
||||
LVGL is deinitialized before the application exits.
|
||||
|
||||
config LV_WAYLAND_AUTO_BACKEND
|
||||
bool "Auto-select the Wayland backend (legacy)"
|
||||
default y
|
||||
help
|
||||
Legacy behavior, slated for removal: the backend defaults to SHM and any
|
||||
LV_WAYLAND_USE_* set directly in lv_conf.h is honored. Disable this and pick
|
||||
a backend explicitly in the "Rendering backend" choice.
|
||||
|
||||
choice
|
||||
prompt "Rendering backend"
|
||||
default LV_WAYLAND_BACKEND_SHM
|
||||
depends on !LV_WAYLAND_AUTO_BACKEND
|
||||
help
|
||||
Select the rendering backend used by the Wayland driver.
|
||||
|
||||
config LV_WAYLAND_BACKEND_SHM
|
||||
bool "SHM (Shared Memory)"
|
||||
select LV_WAYLAND_USE_SHM
|
||||
help
|
||||
Default backend, using wl_shm for double-buffered direct rendering.
|
||||
Compatible with all Wayland compositors; no special hardware required.
|
||||
|
||||
config LV_WAYLAND_BACKEND_EGL
|
||||
bool "EGL (OpenGL ES, hardware-accelerated)"
|
||||
select LV_WAYLAND_USE_EGL
|
||||
select LV_USE_OPENGLES
|
||||
help
|
||||
Hardware-accelerated rendering via OpenGL ES 2.0 and EGL, compatible
|
||||
with LVGL 3D/glTF rendering. Requires OpenGL ES 2.0 on the target
|
||||
hardware and linking with wayland-egl (-lwayland-egl).
|
||||
|
||||
config LV_WAYLAND_BACKEND_G2D
|
||||
bool "G2D (NXP i.MX hardware accelerator)"
|
||||
select LV_WAYLAND_USE_G2D
|
||||
select LV_USE_DRAW_G2D
|
||||
help
|
||||
Hardware-accelerated 2D rendering via NXP's G2D engine.
|
||||
Supports NXP i.MX6/i.MX8 platforms with G2D library installed.
|
||||
endchoice
|
||||
|
||||
config LV_WAYLAND_BACKEND
|
||||
int
|
||||
default 0 if LV_WAYLAND_BACKEND_SHM
|
||||
default 1 if LV_WAYLAND_BACKEND_EGL
|
||||
default 2 if LV_WAYLAND_BACKEND_G2D
|
||||
|
||||
config LV_WAYLAND_USE_SHM
|
||||
bool
|
||||
bool "SHM (Shared Memory) Backend"
|
||||
default y
|
||||
depends on !LV_USE_DRAW_OPENGLES && !LV_USE_DRAW_NANOVG
|
||||
help
|
||||
Default backend, using wl_shm for double-buffered direct rendering.
|
||||
Compatible with all Wayland compositors; no special hardware required.
|
||||
Unavailable with the OpenGL ES and NanoVG renderers, which can only
|
||||
render into a GPU surface.
|
||||
|
||||
config LV_WAYLAND_USE_EGL
|
||||
bool
|
||||
bool "EGL (OpenGL ES, hardware-accelerated) Backend"
|
||||
default y if LV_USE_DRAW_OPENGLES || LV_USE_DRAW_NANOVG
|
||||
select LV_USE_EGL
|
||||
select LV_USE_OPENGLES
|
||||
select LV_WAYLAND_USE_DMABUF if !LV_USE_DRAW_OPENGLES && !LV_USE_DRAW_NANOVG
|
||||
help
|
||||
Hardware-accelerated rendering via OpenGL ES 2.0 and EGL, compatible
|
||||
with LVGL 3D/glTF rendering. Requires OpenGL ES 2.0 on the target
|
||||
hardware and linking with wayland-egl (-lwayland-egl).
|
||||
The only backend available with the OpenGL ES and NanoVG renderers.
|
||||
|
||||
config LV_WAYLAND_USE_G2D
|
||||
bool
|
||||
bool "G2D (NXP i.MX hardware accelerator)"
|
||||
depends on !LV_USE_DRAW_OPENGLES && !LV_USE_DRAW_NANOVG
|
||||
select LV_USE_DRAW_G2D
|
||||
select LV_WAYLAND_USE_DMABUF
|
||||
help
|
||||
Hardware-accelerated 2D rendering via NXP's G2D engine.
|
||||
Supports NXP i.MX6/i.MX8 platforms with G2D library installed.
|
||||
Unavailable with the OpenGL ES and NanoVG renderers, which can only
|
||||
render into a GPU surface.
|
||||
|
||||
config LV_WAYLAND_USE_DMABUF
|
||||
bool
|
||||
|
||||
@@ -138,9 +138,10 @@ Set it to one of the predefined GPU/revision combinations:
|
||||
|
||||
#### Drivers
|
||||
|
||||
Each backend-selecting driver (SDL, Wayland and DRM) now exposes an explicit `LV_<DRIVER>_BACKEND` choice instead of inferring the backend automatically.
|
||||
No driver infers its rendering backend from the enabled draw units any more. SDL and DRM now expose an explicit `LV_<DRIVER>_BACKEND` choice; Wayland instead lets you
|
||||
enable each of its backends individually and resolves between them at runtime. See below.
|
||||
|
||||
The `LV_<DRIVER>_AUTO_BACKEND` flags (enabled by default) exist purely to ease migration: they let LVGL reproduce the old auto-detected backend so existing projects
|
||||
Their `LV_<DRIVER>_AUTO_BACKEND` flags (enabled by default) exist purely to ease migration: they let LVGL reproduce the old auto-detected backend so existing projects
|
||||
don't silently switch to a different backend on update simply because they never set one explicitly. Leaving an `_AUTO_BACKEND` flag enabled triggers a build-time warning.
|
||||
These flags are not meant to be relied on going forward and will be removed for v10, every project should set its backend explicitly with `LV_<DRIVER>_BACKEND` and then
|
||||
disable the corresponding `_AUTO_BACKEND` flag to silence the warning.
|
||||
@@ -172,14 +173,29 @@ Set `LV_LINUX_DRM_AUTO_BACKEND` to 0 and select a backend explicitly with `LV_LI
|
||||
|
||||
`LV_USE_LINUX_DRM_GBM_BUFFERS` is no longer a user-facing setting. It is now set internally and automatically enabled whenever the `EGL` or `GBM` backend is selected; it should no longer be set directly in `lv_conf.h`.
|
||||
|
||||
- **Wayland** — while `LV_WAYLAND_AUTO_BACKEND` is enabled, the backend is inferred the legacy way: EGL when `LV_USE_OPENGLES` is enabled, otherwise G2D when `LV_USE_DRAW_G2D` is enabled, otherwise SHM.
|
||||
Set `LV_WAYLAND_AUTO_BACKEND` to 0 and select a backend explicitly with `LV_WAYLAND_BACKEND`:
|
||||
- **Wayland** — the backend is no longer inferred, and no longer has to be a single one.
|
||||
|
||||
| Value | Backend |
|
||||
|---|---|
|
||||
| `LV_WAYLAND_BACKEND_SHM` | SHM (Shared Memory) |
|
||||
| `LV_WAYLAND_BACKEND_EGL` | EGL (OpenGL ES, hardware-accelerated; enable: `LV_USE_OPENGLES`) |
|
||||
| `LV_WAYLAND_BACKEND_G2D` | G2D (NXP i.MX hardware accelerator; enable: `LV_USE_DRAW_G2D`) |
|
||||
Previously `LV_WAYLAND_USE_SHM`, `LV_WAYLAND_USE_EGL` and `LV_WAYLAND_USE_G2D` were derived internally and mutually exclusive: enabling `LV_USE_OPENGLES` gave you EGL,
|
||||
otherwise enabling `LV_USE_G2D` gave you G2D, otherwise you got SHM. Setting them in `lv_conf.h` had no effect.
|
||||
|
||||
They are now ordinary options that you set yourself, and **more than one may be enabled at a time**:
|
||||
|
||||
| Symbol | Backend | Default |
|
||||
|---|---|---|
|
||||
| `LV_WAYLAND_USE_SHM` | SHM (Shared Memory) | on, except with a GPU draw unit |
|
||||
| `LV_WAYLAND_USE_EGL` | EGL (OpenGL ES, hardware-accelerated; enable: `LV_USE_OPENGLES`) | off; under Kconfig, on with a GPU draw unit |
|
||||
| `LV_WAYLAND_USE_G2D` | G2D (NXP i.MX hardware accelerator; enable: `LV_USE_DRAW_G2D`) | off |
|
||||
|
||||
To reproduce exactly what you had before, enable the one backend the old rules would have picked for your config. `LV_USE_G2D` no longer plays a part in the choice:
|
||||
it is a deprecated no-op (see [No-op options kept for compatibility](#no-op-options-kept-for-compatibility)) and the G2D backend is now tied to `LV_USE_DRAW_G2D`.
|
||||
|
||||
| You had | Backend you got | Add |
|
||||
|---|---|---|
|
||||
| `LV_USE_OPENGLES` = 1 | EGL | `LV_WAYLAND_USE_EGL` = 1 (keep `LV_USE_OPENGLES`) |
|
||||
| `LV_USE_G2D` = 1 | G2D | `LV_WAYLAND_USE_G2D` = 1 and `LV_USE_DRAW_G2D` = 1 |
|
||||
| neither | SHM | nothing — `LV_WAYLAND_USE_SHM` is on by default |
|
||||
|
||||
See the [Wayland driver docs](/integration/embedded_linux/drivers/wayland#runtime-backend-selection) for more information.
|
||||
|
||||
- **X11** — render mode (unrelated to backend selection) is now a single value mapped onto the standard `LV_DISPLAY_RENDER_MODE_*` constants:
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -111,11 +111,6 @@
|
||||
#define LV_SDL_MOUSEWHEEL_MODE_ENCODER 0
|
||||
#define LV_SDL_MOUSEWHEEL_MODE_CROWN 1
|
||||
|
||||
/* Rendering backend */
|
||||
#define LV_WAYLAND_BACKEND_SHM 0
|
||||
#define LV_WAYLAND_BACKEND_EGL 1
|
||||
#define LV_WAYLAND_BACKEND_G2D 2
|
||||
|
||||
/* Log behavior on LV_CHECK_ARG failure */
|
||||
#define LV_CHECK_ARG_LOG_MODE_NONE 0
|
||||
#define LV_CHECK_ARG_LOG_MODE_MINIMAL 1
|
||||
@@ -3544,23 +3539,31 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LV_WAYLAND_AUTO_BACKEND
|
||||
#ifndef LV_WAYLAND_USE_SHM
|
||||
#ifdef LV_KCONFIG_PRESENT
|
||||
#ifdef CONFIG_LV_WAYLAND_AUTO_BACKEND
|
||||
#define LV_WAYLAND_AUTO_BACKEND CONFIG_LV_WAYLAND_AUTO_BACKEND
|
||||
#ifdef CONFIG_LV_WAYLAND_USE_SHM
|
||||
#define LV_WAYLAND_USE_SHM CONFIG_LV_WAYLAND_USE_SHM
|
||||
#else
|
||||
#define LV_WAYLAND_AUTO_BACKEND 0
|
||||
#define LV_WAYLAND_USE_SHM 0
|
||||
#endif
|
||||
#else
|
||||
#define LV_WAYLAND_AUTO_BACKEND LV_USE_WAYLAND
|
||||
#define LV_WAYLAND_USE_SHM !LV_USE_DRAW_OPENGLES && !LV_USE_DRAW_NANOVG && LV_USE_WAYLAND
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LV_WAYLAND_BACKEND
|
||||
#ifdef CONFIG_LV_WAYLAND_BACKEND
|
||||
#define LV_WAYLAND_BACKEND CONFIG_LV_WAYLAND_BACKEND
|
||||
#ifndef LV_WAYLAND_USE_EGL
|
||||
#ifdef CONFIG_LV_WAYLAND_USE_EGL
|
||||
#define LV_WAYLAND_USE_EGL CONFIG_LV_WAYLAND_USE_EGL
|
||||
#else
|
||||
#define LV_WAYLAND_BACKEND LV_WAYLAND_BACKEND_SHM
|
||||
#define LV_WAYLAND_USE_EGL 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LV_WAYLAND_USE_G2D
|
||||
#ifdef CONFIG_LV_WAYLAND_USE_G2D
|
||||
#define LV_WAYLAND_USE_G2D CONFIG_LV_WAYLAND_USE_G2D
|
||||
#else
|
||||
#define LV_WAYLAND_USE_G2D 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -4756,28 +4759,14 @@
|
||||
#endif
|
||||
#endif /*LV_USE_SDL && LV_SDL_AUTO_BACKEND*/
|
||||
|
||||
/* Wayland never inferred its backend from LV_USE_OPENGLES; the legacy interface
|
||||
* was setting LV_WAYLAND_USE_* directly. While LV_WAYLAND_AUTO_BACKEND is set we
|
||||
* honor any such define, default to SHM, and keep the three mutually exclusive.
|
||||
* The #warning fires only if a legacy LV_WAYLAND_USE_* was set by hand. */
|
||||
#if LV_USE_WAYLAND && LV_WAYLAND_AUTO_BACKEND
|
||||
#if defined(LV_WAYLAND_USE_EGL) || defined(LV_WAYLAND_USE_G2D) || defined(LV_WAYLAND_USE_SHM)
|
||||
#warning Setting LV_WAYLAND_USE_* directly is deprecated and will be removed in a future release. Set LV_WAYLAND_AUTO_BACKEND to 0 and select a backend with LV_WAYLAND_BACKEND.
|
||||
#endif
|
||||
#ifndef LV_WAYLAND_USE_EGL
|
||||
#define LV_WAYLAND_USE_EGL 0
|
||||
#endif
|
||||
#ifndef LV_WAYLAND_USE_G2D
|
||||
#define LV_WAYLAND_USE_G2D 0
|
||||
#endif
|
||||
#ifndef LV_WAYLAND_USE_SHM
|
||||
#if LV_WAYLAND_USE_EGL || LV_WAYLAND_USE_G2D
|
||||
#define LV_WAYLAND_USE_SHM 0
|
||||
#else
|
||||
#define LV_WAYLAND_USE_SHM 1
|
||||
#endif
|
||||
#endif
|
||||
#endif /*LV_USE_WAYLAND && LV_WAYLAND_AUTO_BACKEND*/
|
||||
/* The Wayland backends used to be mutually exclusive: LV_WAYLAND_BACKEND picked
|
||||
* exactly one of them, and the deprecated LV_WAYLAND_AUTO_BACKEND kept the older
|
||||
* behavior of setting LV_WAYLAND_USE_* by hand. Several backends can now be
|
||||
* enabled at once and the driver probes them at runtime, so both symbols are
|
||||
* gone. Warn rather than let an old lv_conf.h silently fall back to SHM. */
|
||||
#if LV_USE_WAYLAND && defined(LV_WAYLAND_BACKEND)
|
||||
#warning LV_WAYLAND_BACKEND is deprecated and has no effect. Enable each backend you want with LV_WAYLAND_USE_SHM, LV_WAYLAND_USE_EGL and LV_WAYLAND_USE_G2D instead; the driver initializes the first one that works.
|
||||
#endif /*LV_USE_WAYLAND && defined(LV_WAYLAND_BACKEND) */
|
||||
|
||||
#if defined(LV_ASSERT_HANDLER_INCLUDE) && !LV_DISABLE_ASSERT_HANDLER_INCLUDE_WARNING
|
||||
#warning "LV_ASSERT_HANDLER_INCLUDE is deprecated and will be removed in a future release. Use LV_ASSERT_CUSTOM_INCLUDE and define LV_ASSERT_HANDLER inside. To suppress this warning, remove LV_ASSERT_HANDLER_INCLUDE or enable LV_DISABLE_ASSERT_HANDLER_INCLUDE_WARNING."
|
||||
@@ -4902,27 +4891,11 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LV_WAYLAND_USE_SHM
|
||||
#if ((LV_WAYLAND_BACKEND == LV_WAYLAND_BACKEND_SHM) && (LV_USE_WAYLAND))
|
||||
#define LV_WAYLAND_USE_SHM 1
|
||||
#ifndef LV_WAYLAND_USE_DMABUF
|
||||
#if (((LV_WAYLAND_USE_EGL && !LV_USE_DRAW_OPENGLES && !LV_USE_DRAW_NANOVG && LV_USE_WAYLAND) || (LV_WAYLAND_USE_G2D && !LV_USE_DRAW_OPENGLES && !LV_USE_DRAW_NANOVG && LV_USE_WAYLAND)) && (LV_USE_WAYLAND))
|
||||
#define LV_WAYLAND_USE_DMABUF 1
|
||||
#else
|
||||
#define LV_WAYLAND_USE_SHM 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LV_WAYLAND_USE_EGL
|
||||
#if ((LV_WAYLAND_BACKEND == LV_WAYLAND_BACKEND_EGL) && (LV_USE_WAYLAND))
|
||||
#define LV_WAYLAND_USE_EGL 1
|
||||
#else
|
||||
#define LV_WAYLAND_USE_EGL 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LV_WAYLAND_USE_G2D
|
||||
#if ((LV_WAYLAND_BACKEND == LV_WAYLAND_BACKEND_G2D) && (LV_USE_WAYLAND))
|
||||
#define LV_WAYLAND_USE_G2D 1
|
||||
#else
|
||||
#define LV_WAYLAND_USE_G2D 0
|
||||
#define LV_WAYLAND_USE_DMABUF 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -4934,14 +4907,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LV_WAYLAND_USE_DMABUF
|
||||
#if (((LV_WAYLAND_USE_EGL && !LV_USE_DRAW_OPENGLES && !LV_USE_DRAW_NANOVG && LV_USE_WAYLAND) || (LV_WAYLAND_USE_G2D && LV_USE_WAYLAND)) && (LV_USE_WAYLAND))
|
||||
#define LV_WAYLAND_USE_DMABUF 1
|
||||
#else
|
||||
#define LV_WAYLAND_USE_DMABUF 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Optional user headers (LV_*_USE_CUSTOM_INCLUDE) overriding config macros. */
|
||||
#if LV_OS_USE_CUSTOM_INCLUDE
|
||||
#include LV_OS_CUSTOM_INCLUDE
|
||||
@@ -5154,8 +5119,8 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN);
|
||||
#error "LV_USE_DRAW_DMA2D_INTERRUPT requires LV_USE_DRAW_DMA2D (Kconfig depends on)"
|
||||
#endif
|
||||
|
||||
#if (LV_WAYLAND_BACKEND == LV_WAYLAND_BACKEND_G2D) && !LV_USE_DRAW_G2D
|
||||
#error "LV_USE_DRAW_G2D must be enabled: Kconfig selects it from LV_WAYLAND_BACKEND == LV_WAYLAND_BACKEND_G2D"
|
||||
#if (LV_WAYLAND_USE_G2D && !LV_USE_DRAW_OPENGLES && !LV_USE_DRAW_NANOVG && LV_USE_WAYLAND) && !LV_USE_DRAW_G2D
|
||||
#error "LV_USE_DRAW_G2D must be enabled: Kconfig selects it from LV_WAYLAND_USE_G2D && !LV_USE_DRAW_OPENGLES && !LV_USE_DRAW_NANOVG && LV_USE_WAYLAND"
|
||||
#endif
|
||||
|
||||
#if LV_USE_G2D_ASSERT && !(LV_USE_DRAW_G2D && LV_USE_DRAW_G2D)
|
||||
@@ -5318,8 +5283,8 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN);
|
||||
#error "LV_USE_NUTTX_TRACE_FILE requires LV_USE_PROFILER_BUILTIN && LV_USE_NUTTX (Kconfig depends on)"
|
||||
#endif
|
||||
|
||||
#if (LV_USE_DRAW_NANOVG || LV_USE_DRAW_OPENGLES || LV_LINUX_DRM_BACKEND == LV_LINUX_DRM_BACKEND_EGL || (LV_USE_GLFW && !LV_USE_EGL) || LV_WAYLAND_BACKEND == LV_WAYLAND_BACKEND_EGL) && !LV_USE_OPENGLES
|
||||
#error "LV_USE_OPENGLES must be enabled: Kconfig selects it from LV_USE_DRAW_NANOVG || LV_USE_DRAW_OPENGLES || LV_LINUX_DRM_BACKEND == LV_LINUX_DRM_BACKEND_EGL || (LV_USE_GLFW && !LV_USE_EGL) || LV_WAYLAND_BACKEND == LV_WAYLAND_BACKEND_EGL"
|
||||
#if (LV_USE_DRAW_NANOVG || LV_USE_DRAW_OPENGLES || LV_LINUX_DRM_BACKEND == LV_LINUX_DRM_BACKEND_EGL || (LV_USE_GLFW && !LV_USE_EGL) || (LV_WAYLAND_USE_EGL && LV_USE_WAYLAND)) && !LV_USE_OPENGLES
|
||||
#error "LV_USE_OPENGLES must be enabled: Kconfig selects it from LV_USE_DRAW_NANOVG || LV_USE_DRAW_OPENGLES || LV_LINUX_DRM_BACKEND == LV_LINUX_DRM_BACKEND_EGL || (LV_USE_GLFW && !LV_USE_EGL) || (LV_WAYLAND_USE_EGL && LV_USE_WAYLAND)"
|
||||
#endif
|
||||
|
||||
#if LV_USE_OPENGLES_DEBUG && !(LV_USE_OPENGLES)
|
||||
@@ -5338,6 +5303,14 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN);
|
||||
#error "LV_UEFI_USE_MEMORY_SERVICES requires LV_USE_UEFI (Kconfig depends on)"
|
||||
#endif
|
||||
|
||||
#if LV_WAYLAND_USE_EGL && !(LV_USE_WAYLAND)
|
||||
#error "LV_WAYLAND_USE_EGL requires LV_USE_WAYLAND (Kconfig depends on)"
|
||||
#endif
|
||||
|
||||
#if LV_WAYLAND_USE_G2D && !(!LV_USE_DRAW_OPENGLES && !LV_USE_DRAW_NANOVG && LV_USE_WAYLAND)
|
||||
#error "LV_WAYLAND_USE_G2D requires !LV_USE_DRAW_OPENGLES && !LV_USE_DRAW_NANOVG && LV_USE_WAYLAND (Kconfig depends on)"
|
||||
#endif
|
||||
|
||||
#if LV_USE_WINDOWS && !(LV_USE_OS == LV_OS_WINDOWS)
|
||||
#error "LV_USE_WINDOWS requires LV_USE_OS == LV_OS_WINDOWS (Kconfig depends on)"
|
||||
#endif
|
||||
|
||||
+30
-10
@@ -1769,20 +1769,40 @@
|
||||
/** LVGL is deinitialized before the application exits. */
|
||||
#define LV_WAYLAND_DIRECT_EXIT 1
|
||||
|
||||
/** Legacy behavior, slated for removal: the backend defaults to SHM and any
|
||||
* LV_WAYLAND_USE_* set directly in lv_conf.h is honored. Disable this and pick
|
||||
* a backend explicitly in the "Rendering backend" choice.
|
||||
#if !LV_USE_DRAW_OPENGLES
|
||||
#if !LV_USE_DRAW_NANOVG
|
||||
/** Default backend, using wl_shm for double-buffered direct rendering.
|
||||
* Compatible with all Wayland compositors; no special hardware required.
|
||||
* Unavailable with the OpenGL ES and NanoVG renderers, which can only
|
||||
* render into a GPU surface.
|
||||
*/
|
||||
#define LV_WAYLAND_AUTO_BACKEND 1
|
||||
#define LV_WAYLAND_USE_SHM 1
|
||||
|
||||
/** Select the rendering backend used by the Wayland driver.
|
||||
* Possible values:
|
||||
* - LV_WAYLAND_BACKEND_SHM: SHM (Shared Memory)
|
||||
* - LV_WAYLAND_BACKEND_EGL: EGL (OpenGL ES, hardware-accelerated) (enable: LV_USE_OPENGLES)
|
||||
* - LV_WAYLAND_BACKEND_G2D: G2D (NXP i.MX hardware accelerator) (enable: LV_USE_DRAW_G2D)
|
||||
#endif /*!LV_USE_DRAW_NANOVG*/
|
||||
#endif /*!LV_USE_DRAW_OPENGLES*/
|
||||
|
||||
/** Hardware-accelerated rendering via OpenGL ES 2.0 and EGL, compatible
|
||||
* with LVGL 3D/glTF rendering. Requires OpenGL ES 2.0 on the target
|
||||
* hardware and linking with wayland-egl (-lwayland-egl).
|
||||
* The only backend available with the OpenGL ES and NanoVG renderers.
|
||||
*
|
||||
* Enable: LV_USE_OPENGLES
|
||||
*/
|
||||
#define LV_WAYLAND_BACKEND LV_WAYLAND_BACKEND_SHM
|
||||
#define LV_WAYLAND_USE_EGL 0
|
||||
|
||||
#if !LV_USE_DRAW_OPENGLES
|
||||
#if !LV_USE_DRAW_NANOVG
|
||||
/** Hardware-accelerated 2D rendering via NXP's G2D engine.
|
||||
* Supports NXP i.MX6/i.MX8 platforms with G2D library installed.
|
||||
* Unavailable with the OpenGL ES and NanoVG renderers, which can only
|
||||
* render into a GPU surface.
|
||||
*
|
||||
* Enable: LV_USE_DRAW_G2D
|
||||
*/
|
||||
#define LV_WAYLAND_USE_G2D 0
|
||||
|
||||
#endif /*!LV_USE_DRAW_NANOVG*/
|
||||
#endif /*!LV_USE_DRAW_OPENGLES*/
|
||||
#endif /*LV_USE_WAYLAND*/
|
||||
|
||||
#if LV_USE_OS == LV_OS_WINDOWS
|
||||
|
||||
@@ -267,28 +267,14 @@ INTERNAL_COMPATIBILITY_BLOCK = r"""
|
||||
#endif
|
||||
#endif /*LV_USE_SDL && LV_SDL_AUTO_BACKEND*/
|
||||
|
||||
/* Wayland never inferred its backend from LV_USE_OPENGLES; the legacy interface
|
||||
* was setting LV_WAYLAND_USE_* directly. While LV_WAYLAND_AUTO_BACKEND is set we
|
||||
* honor any such define, default to SHM, and keep the three mutually exclusive.
|
||||
* The #warning fires only if a legacy LV_WAYLAND_USE_* was set by hand. */
|
||||
#if LV_USE_WAYLAND && LV_WAYLAND_AUTO_BACKEND
|
||||
#if defined(LV_WAYLAND_USE_EGL) || defined(LV_WAYLAND_USE_G2D) || defined(LV_WAYLAND_USE_SHM)
|
||||
#warning Setting LV_WAYLAND_USE_* directly is deprecated and will be removed in a future release. Set LV_WAYLAND_AUTO_BACKEND to 0 and select a backend with LV_WAYLAND_BACKEND.
|
||||
#endif
|
||||
#ifndef LV_WAYLAND_USE_EGL
|
||||
#define LV_WAYLAND_USE_EGL 0
|
||||
#endif
|
||||
#ifndef LV_WAYLAND_USE_G2D
|
||||
#define LV_WAYLAND_USE_G2D 0
|
||||
#endif
|
||||
#ifndef LV_WAYLAND_USE_SHM
|
||||
#if LV_WAYLAND_USE_EGL || LV_WAYLAND_USE_G2D
|
||||
#define LV_WAYLAND_USE_SHM 0
|
||||
#else
|
||||
#define LV_WAYLAND_USE_SHM 1
|
||||
#endif
|
||||
#endif
|
||||
#endif /*LV_USE_WAYLAND && LV_WAYLAND_AUTO_BACKEND*/
|
||||
/* The Wayland backends used to be mutually exclusive: LV_WAYLAND_BACKEND picked
|
||||
* exactly one of them, and the deprecated LV_WAYLAND_AUTO_BACKEND kept the older
|
||||
* behavior of setting LV_WAYLAND_USE_* by hand. Several backends can now be
|
||||
* enabled at once and the driver probes them at runtime, so both symbols are
|
||||
* gone. Warn rather than let an old lv_conf.h silently fall back to SHM. */
|
||||
#if LV_USE_WAYLAND && defined(LV_WAYLAND_BACKEND)
|
||||
#warning LV_WAYLAND_BACKEND is deprecated and has no effect. Enable each backend you want with LV_WAYLAND_USE_SHM, LV_WAYLAND_USE_EGL and LV_WAYLAND_USE_G2D instead; the driver initializes the first one that works.
|
||||
#endif /*LV_USE_WAYLAND && defined(LV_WAYLAND_BACKEND) */
|
||||
|
||||
#if defined(LV_ASSERT_HANDLER_INCLUDE) && !LV_DISABLE_ASSERT_HANDLER_INCLUDE_WARNING
|
||||
#warning "LV_ASSERT_HANDLER_INCLUDE is deprecated and will be removed in a future release. Use LV_ASSERT_CUSTOM_INCLUDE and define LV_ASSERT_HANDLER inside. To suppress this warning, remove LV_ASSERT_HANDLER_INCLUDE or enable LV_DISABLE_ASSERT_HANDLER_INCLUDE_WARNING."
|
||||
|
||||
+24
-49
@@ -12,63 +12,38 @@ config LV_WAYLAND_DIRECT_EXIT
|
||||
help
|
||||
LVGL is deinitialized before the application exits.
|
||||
|
||||
config LV_WAYLAND_AUTO_BACKEND
|
||||
bool "Auto-select the Wayland backend (legacy)"
|
||||
default y
|
||||
help
|
||||
Legacy behavior, slated for removal: the backend defaults to SHM and any
|
||||
LV_WAYLAND_USE_* set directly in lv_conf.h is honored. Disable this and pick
|
||||
a backend explicitly in the "Rendering backend" choice.
|
||||
|
||||
choice
|
||||
prompt "Rendering backend"
|
||||
default LV_WAYLAND_BACKEND_SHM
|
||||
depends on !LV_WAYLAND_AUTO_BACKEND
|
||||
help
|
||||
Select the rendering backend used by the Wayland driver.
|
||||
|
||||
config LV_WAYLAND_BACKEND_SHM
|
||||
bool "SHM (Shared Memory)"
|
||||
select LV_WAYLAND_USE_SHM
|
||||
help
|
||||
Default backend, using wl_shm for double-buffered direct rendering.
|
||||
Compatible with all Wayland compositors; no special hardware required.
|
||||
|
||||
config LV_WAYLAND_BACKEND_EGL
|
||||
bool "EGL (OpenGL ES, hardware-accelerated)"
|
||||
select LV_WAYLAND_USE_EGL
|
||||
select LV_USE_OPENGLES
|
||||
help
|
||||
Hardware-accelerated rendering via OpenGL ES 2.0 and EGL, compatible
|
||||
with LVGL 3D/glTF rendering. Requires OpenGL ES 2.0 on the target
|
||||
hardware and linking with wayland-egl (-lwayland-egl).
|
||||
|
||||
config LV_WAYLAND_BACKEND_G2D
|
||||
bool "G2D (NXP i.MX hardware accelerator)"
|
||||
select LV_WAYLAND_USE_G2D
|
||||
select LV_USE_DRAW_G2D
|
||||
help
|
||||
Hardware-accelerated 2D rendering via NXP's G2D engine.
|
||||
Supports NXP i.MX6/i.MX8 platforms with G2D library installed.
|
||||
endchoice
|
||||
|
||||
config LV_WAYLAND_BACKEND
|
||||
int
|
||||
default 0 if LV_WAYLAND_BACKEND_SHM
|
||||
default 1 if LV_WAYLAND_BACKEND_EGL
|
||||
default 2 if LV_WAYLAND_BACKEND_G2D
|
||||
|
||||
config LV_WAYLAND_USE_SHM
|
||||
bool
|
||||
bool "SHM (Shared Memory) Backend"
|
||||
default y
|
||||
depends on !LV_USE_DRAW_OPENGLES && !LV_USE_DRAW_NANOVG
|
||||
help
|
||||
Default backend, using wl_shm for double-buffered direct rendering.
|
||||
Compatible with all Wayland compositors; no special hardware required.
|
||||
Unavailable with the OpenGL ES and NanoVG renderers, which can only
|
||||
render into a GPU surface.
|
||||
|
||||
config LV_WAYLAND_USE_EGL
|
||||
bool
|
||||
bool "EGL (OpenGL ES, hardware-accelerated) Backend"
|
||||
default y if LV_USE_DRAW_OPENGLES || LV_USE_DRAW_NANOVG
|
||||
select LV_USE_EGL
|
||||
select LV_USE_OPENGLES
|
||||
select LV_WAYLAND_USE_DMABUF if !LV_USE_DRAW_OPENGLES && !LV_USE_DRAW_NANOVG
|
||||
help
|
||||
Hardware-accelerated rendering via OpenGL ES 2.0 and EGL, compatible
|
||||
with LVGL 3D/glTF rendering. Requires OpenGL ES 2.0 on the target
|
||||
hardware and linking with wayland-egl (-lwayland-egl).
|
||||
The only backend available with the OpenGL ES and NanoVG renderers.
|
||||
|
||||
config LV_WAYLAND_USE_G2D
|
||||
bool
|
||||
bool "G2D (NXP i.MX hardware accelerator)"
|
||||
depends on !LV_USE_DRAW_OPENGLES && !LV_USE_DRAW_NANOVG
|
||||
select LV_USE_DRAW_G2D
|
||||
select LV_WAYLAND_USE_DMABUF
|
||||
help
|
||||
Hardware-accelerated 2D rendering via NXP's G2D engine.
|
||||
Supports NXP i.MX6/i.MX8 platforms with G2D library installed.
|
||||
Unavailable with the OpenGL ES and NanoVG renderers, which can only
|
||||
render into a GPU surface.
|
||||
|
||||
config LV_WAYLAND_USE_DMABUF
|
||||
bool
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include LV_STDDEF_INCLUDE
|
||||
#include LV_STDINT_INCLUDE
|
||||
#include LV_STDBOOL_INCLUDE
|
||||
#include "lv_wayland_private.h"
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
@@ -124,8 +125,7 @@ lv_result_t lv_wayland_init(void)
|
||||
LV_LOG_ERROR("failed to connect to Wayland server");
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
lv_wl_ctx.backend_data = wl_backend_ops.init();
|
||||
lv_wayland_backend_init_all();
|
||||
|
||||
/* Add registry listener and wait for registry reception */
|
||||
lv_wl_ctx.wl_registry = wl_display_get_registry(lv_wl_ctx.wl_display);
|
||||
@@ -160,7 +160,7 @@ void lv_wayland_deinit(void)
|
||||
lv_wayland_xdg_deinit();
|
||||
|
||||
if(is_wayland_initialized) {
|
||||
wl_backend_ops.deinit(lv_wl_ctx.backend_data);
|
||||
lv_wayland_backend_deinit_all();
|
||||
}
|
||||
|
||||
if(lv_wl_ctx.seat.wl_seat) {
|
||||
@@ -330,7 +330,7 @@ static void handle_global(void * data, struct wl_registry * registry, uint32_t n
|
||||
}
|
||||
}
|
||||
|
||||
wl_backend_ops.global_handler(lv_wl_ctx.backend_data, registry, name, interface, version);
|
||||
lv_wayland_backend_global_handler(registry, name, interface, version);
|
||||
}
|
||||
|
||||
static void handle_global_remove(void * data, struct wl_registry * registry, uint32_t name)
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
/**
|
||||
* @file lv_wayland_backend.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_wayland_backend_private.h"
|
||||
|
||||
#if LV_USE_WAYLAND
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
#if LV_WAYLAND_USE_EGL
|
||||
extern const lv_wayland_backend_ops_t wl_egl_ops;
|
||||
extern const lv_wayland_backend_display_ops_t wl_egl_display_ops;
|
||||
#endif /*LV_WAYLAND_USE_EGL*/
|
||||
|
||||
#if LV_WAYLAND_USE_G2D
|
||||
extern const lv_wayland_backend_ops_t wl_g2d_ops;
|
||||
extern const lv_wayland_backend_display_ops_t wl_g2d_display_ops;
|
||||
#endif /*LV_WAYLAND_USE_G2D*/
|
||||
|
||||
#if LV_WAYLAND_USE_SHM
|
||||
extern const lv_wayland_backend_ops_t wl_shm_ops;
|
||||
extern const lv_wayland_backend_display_ops_t wl_shm_display_ops;
|
||||
#endif /*LV_WAYLAND_USE_SHM*/
|
||||
|
||||
|
||||
#if !LV_WAYLAND_USE_EGL && !LV_WAYLAND_USE_G2D && !LV_WAYLAND_USE_SHM
|
||||
#error "At least one wayland backend must be selected. Note that with LV_USE_DRAW_OPENGLES or LV_USE_DRAW_NANOVG only LV_WAYLAND_USE_EGL is available."
|
||||
#endif
|
||||
|
||||
/* The SHM and G2D backends hand a CPU buffer to LVGL, which the OpenGL ES and
|
||||
* NanoVG draw units cannot render into: they would claim the draw tasks and
|
||||
* leave the buffer untouched. Kconfig keeps this out of reach, catch an
|
||||
* lv_conf.h that sets the flags by hand. */
|
||||
#if (LV_WAYLAND_USE_SHM || LV_WAYLAND_USE_G2D) && (LV_USE_DRAW_OPENGLES || LV_USE_DRAW_NANOVG)
|
||||
#error "LV_WAYLAND_USE_SHM and LV_WAYLAND_USE_G2D are not compatible with LV_USE_DRAW_OPENGLES or LV_USE_DRAW_NANOVG. Use LV_WAYLAND_USE_EGL instead."
|
||||
#endif
|
||||
|
||||
/* Ordered by preference: the first backend that can initialize a display wins. */
|
||||
static struct {
|
||||
const char * name;
|
||||
const lv_wayland_backend_ops_t * ops;
|
||||
const lv_wayland_backend_display_ops_t * display_ops;
|
||||
void * backend_data;
|
||||
bool available;
|
||||
} backends[] = {
|
||||
#if LV_WAYLAND_USE_EGL
|
||||
{"EGL", &wl_egl_ops, &wl_egl_display_ops, NULL, false},
|
||||
#endif /*LV_WAYLAND_USE_EGL*/
|
||||
#if LV_WAYLAND_USE_G2D
|
||||
{"G2D", &wl_g2d_ops, &wl_g2d_display_ops, NULL, false},
|
||||
#endif /*LV_WAYLAND_USE_G2D*/
|
||||
#if LV_WAYLAND_USE_SHM
|
||||
{"SHM", &wl_shm_ops, &wl_shm_display_ops, NULL, false},
|
||||
#endif /*LV_WAYLAND_USE_SHM*/
|
||||
};
|
||||
|
||||
static const size_t backend_count = (sizeof(backends) / sizeof(backends[0]));
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_wayland_backend_init_all(void)
|
||||
{
|
||||
for(size_t i = 0; i < backend_count; ++i) {
|
||||
LV_LOG_INFO("Initializing '%s' wayland backend", backends[i].name);
|
||||
|
||||
backends[i].backend_data = NULL;
|
||||
backends[i].available = (backends[i].ops->init(&backends[i].backend_data) == LV_RESULT_OK);
|
||||
|
||||
if(!backends[i].available) {
|
||||
LV_LOG_WARN("Failed to initialize the '%s' wayland backend, it will not be used", backends[i].name);
|
||||
backends[i].backend_data = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lv_wayland_backend_deinit_all(void)
|
||||
{
|
||||
for(size_t i = 0; i < backend_count; ++i) {
|
||||
if(!backends[i].available) {
|
||||
continue;
|
||||
}
|
||||
LV_LOG_INFO("Deinitializing '%s' wayland backend", backends[i].name);
|
||||
backends[i].ops->deinit(backends[i].backend_data);
|
||||
backends[i].backend_data = NULL;
|
||||
backends[i].available = false;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_wayland_backend_global_handler(struct wl_registry * registry, uint32_t name,
|
||||
const char * interface, uint32_t version)
|
||||
{
|
||||
LV_ASSERT(registry != NULL);
|
||||
LV_ASSERT(interface != NULL);
|
||||
for(size_t i = 0; i < backend_count; ++i) {
|
||||
if(!backends[i].available) {
|
||||
continue;
|
||||
}
|
||||
backends[i].ops->global_handler(backends[i].backend_data, registry, name, interface, version);
|
||||
}
|
||||
}
|
||||
|
||||
lv_result_t lv_wayland_backend_init_display(lv_wayland_backend_display_data_t * backend_ddata,
|
||||
lv_display_t * display,
|
||||
int32_t width,
|
||||
int32_t height)
|
||||
|
||||
{
|
||||
LV_ASSERT(backend_ddata != NULL);
|
||||
LV_ASSERT(display != NULL);
|
||||
|
||||
lv_memzero(backend_ddata, sizeof(*backend_ddata));
|
||||
|
||||
/* Every attempt gets the display in the same state: a backend configures it
|
||||
* before it knows whether it will succeed, so restore what a failed attempt
|
||||
* may have changed. */
|
||||
const lv_color_format_t cf = lv_display_get_color_format(display);
|
||||
|
||||
for(size_t i = 0; i < backend_count; ++i) {
|
||||
if(!backends[i].available) {
|
||||
continue;
|
||||
}
|
||||
|
||||
void * display_data = backends[i].display_ops->init_display(backends[i].backend_data, display, width, height);
|
||||
if(!display_data) {
|
||||
LV_LOG_WARN("Failed to initialize a display with the '%s' wayland backend", backends[i].name);
|
||||
/* A backend may publish its display data through
|
||||
* lv_wayland_set_backend_display_data() before bailing out; drop the
|
||||
* pointer it left behind, it is freed by now. */
|
||||
backend_ddata->display_data = NULL;
|
||||
lv_display_set_color_format(display, cf);
|
||||
continue;
|
||||
}
|
||||
backend_ddata->ops = backends[i].display_ops;
|
||||
backend_ddata->backend_data = backends[i].backend_data;
|
||||
backend_ddata->display_data = display_data;
|
||||
LV_LOG_INFO("Initialized display with '%s' wayland backend", backends[i].name);
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
void lv_wayland_backend_deinit_display(lv_wayland_backend_display_data_t * backend_ddata,
|
||||
lv_display_t * display)
|
||||
|
||||
{
|
||||
LV_ASSERT(backend_ddata != NULL);
|
||||
LV_ASSERT(display != NULL);
|
||||
|
||||
if(!backend_ddata->ops) {
|
||||
/* No backend ever took this display */
|
||||
return;
|
||||
}
|
||||
|
||||
backend_ddata->ops->deinit_display(backend_ddata->backend_data, display);
|
||||
lv_memzero(backend_ddata, sizeof(*backend_ddata));
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_WAYLAND*/
|
||||
@@ -101,7 +101,7 @@ typedef struct {
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void * wl_egl_init(void);
|
||||
static lv_result_t wl_egl_init(void ** backend_data);
|
||||
static void wl_egl_deinit(void * backend_ctx);
|
||||
static void * wl_egl_init_display(void * backend_ctx, lv_display_t * display, int32_t width, int32_t height);
|
||||
static void * wl_egl_resize_display(void * backend_ctx, lv_display_t * display);
|
||||
@@ -144,14 +144,22 @@ static void delete_buffer(lv_opengles_egl_t * egl_ctx, lv_wl_buffer_t * buffer);
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
|
||||
/* TODO: the opengl driver doesn't support multiple instances
|
||||
* so we can only handle one display per EGL instance
|
||||
* WIP: https://github.com/lvgl/lvgl/pull/9854 */
|
||||
static bool has_display;
|
||||
static const struct wl_callback_listener frame_listener = {
|
||||
.done = frame_done,
|
||||
};
|
||||
|
||||
const lv_wayland_backend_ops_t wl_backend_ops = {
|
||||
const lv_wayland_backend_ops_t wl_egl_ops = {
|
||||
.init = wl_egl_init,
|
||||
.deinit = wl_egl_deinit,
|
||||
.global_handler = wl_egl_global_handler,
|
||||
};
|
||||
|
||||
const lv_wayland_backend_display_ops_t wl_egl_display_ops = {
|
||||
.init_display = wl_egl_init_display,
|
||||
.deinit_display = wl_egl_deinit_display,
|
||||
.resize_display = wl_egl_resize_display,
|
||||
@@ -184,14 +192,17 @@ static void frame_done(void * data, struct wl_callback * callback, uint32_t time
|
||||
lv_display_flush_ready(display);
|
||||
}
|
||||
|
||||
static void * wl_egl_init(void)
|
||||
static lv_result_t wl_egl_init(void ** backend_data)
|
||||
{
|
||||
has_display = false;
|
||||
#if LV_WL_EGL_DMABUF_ENABLED
|
||||
lv_wayland_dmabuf_ctx_init(&ctx);
|
||||
return &ctx;
|
||||
*backend_data = &ctx;
|
||||
#else
|
||||
return NULL;
|
||||
/* Without the DMA-BUF fast-path the backend keeps no global state */
|
||||
*backend_data = NULL;
|
||||
#endif
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
static void wl_egl_deinit(void * backend_ctx)
|
||||
@@ -208,7 +219,7 @@ static lv_wl_egl_display_data_t * egl_create_display_data(lv_display_t * display
|
||||
{
|
||||
lv_wl_egl_display_data_t * ddata = lv_zalloc(sizeof(*ddata));
|
||||
if(!ddata) {
|
||||
LV_LOG_ERROR("Failed to allocate data for display");
|
||||
LV_LOG_WARN("Failed to allocate data for display");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -224,7 +235,7 @@ static lv_wl_egl_display_data_t * egl_create_display_data(lv_display_t * display
|
||||
lv_egl_interface_t egl_interface = wl_egl_get_interface(display);
|
||||
ddata->egl_ctx = lv_opengles_egl_context_create(&egl_interface);
|
||||
if(!ddata->egl_ctx) {
|
||||
LV_LOG_ERROR("Failed to create EGL context");
|
||||
LV_LOG_WARN("Failed to create EGL context");
|
||||
goto egl_ctx_err;
|
||||
}
|
||||
|
||||
@@ -244,7 +255,7 @@ static lv_wl_egl_display_data_t * egl_create_display_data(lv_display_t * display
|
||||
/*Initialize the draw buffers and texture*/
|
||||
lv_result_t res = lv_opengles_texture_reshape(&ddata->texture, display, width, height);
|
||||
if(res != LV_RESULT_OK) {
|
||||
LV_LOG_ERROR("Failed to create draw buffers");
|
||||
LV_LOG_WARN("Failed to create draw buffers");
|
||||
goto texture_err;
|
||||
}
|
||||
return ddata;
|
||||
@@ -360,7 +371,7 @@ static void egl_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t *
|
||||
* full-screen quad pass and no eglSwapBuffers copy. */
|
||||
lv_wl_buffer_t * buf = get_next_buffer(ddata);
|
||||
if(!buf) {
|
||||
LV_LOG_ERROR("Failed to acquire a wayland window body buffer");
|
||||
LV_LOG_WARN("Failed to acquire a wayland window body buffer");
|
||||
lv_display_flush_ready(disp);
|
||||
return;
|
||||
}
|
||||
@@ -434,9 +445,13 @@ static void egl_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t *
|
||||
static void * wl_egl_init_display(void * backend_ctx, lv_display_t * display, int32_t width, int32_t height)
|
||||
{
|
||||
LV_UNUSED(backend_ctx);
|
||||
if(has_display) {
|
||||
LV_LOG_INFO("The EGL backend can only handle one display at a time");
|
||||
return NULL;
|
||||
}
|
||||
lv_wl_egl_display_data_t * ddata = egl_create_display_data(display, width, height);
|
||||
if(!ddata) {
|
||||
LV_LOG_ERROR("Failed to create display data");
|
||||
LV_LOG_WARN("Failed to create display data");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -451,7 +466,7 @@ static void * wl_egl_init_display(void * backend_ctx, lv_display_t * display, in
|
||||
LV_ASSERT_MALLOC(buf1);
|
||||
LV_ASSERT_MALLOC(buf2);
|
||||
if(!buf1 || !buf2) {
|
||||
LV_LOG_ERROR("Failed to allocate display buffer");
|
||||
LV_LOG_WARN("Failed to allocate display buffer");
|
||||
lv_free(buf1);
|
||||
lv_free(buf2);
|
||||
egl_destroy_display_data(ddata);
|
||||
@@ -464,6 +479,7 @@ static void * wl_egl_init_display(void * backend_ctx, lv_display_t * display, in
|
||||
lv_display_set_buffers(display, buf1, buf2, buf_size, LV_DISPLAY_RENDER_MODE_DIRECT);
|
||||
lv_display_set_flush_cb(display, egl_flush_cb);
|
||||
lv_display_set_flush_wait_cb(display, flush_wait_cb);
|
||||
has_display = true;
|
||||
return ddata;
|
||||
}
|
||||
#endif /*LV_WL_EGL_DMABUF_ENABLED*/
|
||||
@@ -472,6 +488,7 @@ static void * wl_egl_init_display(void * backend_ctx, lv_display_t * display, in
|
||||
lv_display_set_flush_wait_cb(display, flush_wait_cb);
|
||||
lv_display_set_render_mode(display, LV_USE_DRAW_NANOVG ? LV_DISPLAY_RENDER_MODE_FULL : LV_DISPLAY_RENDER_MODE_DIRECT);
|
||||
|
||||
has_display = true;
|
||||
return ddata;
|
||||
}
|
||||
|
||||
@@ -547,6 +564,7 @@ static void wl_egl_deinit_display(void * backend_ctx, lv_display_t * display)
|
||||
#endif
|
||||
|
||||
egl_destroy_display_data(ddata);
|
||||
has_display = false;
|
||||
}
|
||||
|
||||
static void wl_egl_global_handler(void * backend_ctx, struct wl_registry * registry, uint32_t name,
|
||||
@@ -629,7 +647,7 @@ static void * wl_egl_create_window(void * driver_data, const lv_egl_native_windo
|
||||
lv_wl_egl_display_data_t * ddata = lv_wayland_get_backend_display_data(display);
|
||||
|
||||
if(!wl_surface) {
|
||||
LV_LOG_ERROR("Failed to get Wayland surface");
|
||||
LV_LOG_WARN("Failed to get Wayland surface");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -637,7 +655,7 @@ static void * wl_egl_create_window(void * driver_data, const lv_egl_native_windo
|
||||
lv_display_get_horizontal_resolution(display),
|
||||
lv_display_get_vertical_resolution(display));
|
||||
if(!ddata->egl_window) {
|
||||
LV_LOG_ERROR("Failed to create wl_egl_window");
|
||||
LV_LOG_WARN("Failed to create wl_egl_window");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -704,13 +722,13 @@ static bool egl_dmabuf_setup(lv_wl_egl_display_data_t * ddata, lv_display_t * di
|
||||
|
||||
ddata->drm_fd = open_drm_device();
|
||||
if(ddata->drm_fd < 0) {
|
||||
LV_LOG_ERROR("Failed to open DRM device");
|
||||
LV_LOG_WARN("Failed to open DRM device");
|
||||
return false;
|
||||
}
|
||||
|
||||
ddata->gbm_device = gbm_create_device(ddata->drm_fd);
|
||||
if(!ddata->gbm_device) {
|
||||
LV_LOG_ERROR("Failed to create GBM device");
|
||||
LV_LOG_WARN("Failed to create GBM device");
|
||||
close(ddata->drm_fd);
|
||||
ddata->drm_fd = -1;
|
||||
return false;
|
||||
@@ -740,7 +758,7 @@ static bool egl_dmabuf_setup(lv_wl_egl_display_data_t * ddata, lv_display_t * di
|
||||
}
|
||||
|
||||
if(!ok) {
|
||||
LV_LOG_ERROR("DMA-BUF creation failed");
|
||||
LV_LOG_WARN("DMA-BUF creation failed");
|
||||
egl_dmabuf_teardown(ddata);
|
||||
return false;
|
||||
}
|
||||
@@ -876,7 +894,7 @@ static void load_egl_extensions(void)
|
||||
eglGetProcAddress("glEGLImageTargetTexture2DOES");
|
||||
|
||||
if(!glEGLImageTargetTexture2DOES) {
|
||||
LV_LOG_ERROR("Failed to load glEGLImageTargetTexture2DOES extension");
|
||||
LV_LOG_WARN("Failed to load glEGLImageTargetTexture2DOES extension");
|
||||
}
|
||||
else {
|
||||
LV_LOG_INFO("Loaded glEGLImageTargetTexture2DOES extension");
|
||||
@@ -890,7 +908,7 @@ static int open_drm_device(void)
|
||||
|
||||
num_devices = drmGetDevices2(0, devices, 64);
|
||||
if(num_devices < 0) {
|
||||
LV_LOG_ERROR("drmGetDevices2 failed: %s", strerror(-num_devices));
|
||||
LV_LOG_WARN("drmGetDevices2 failed: %s", strerror(-num_devices));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -909,7 +927,7 @@ static int open_drm_device(void)
|
||||
|
||||
drmFreeDevices(devices, num_devices);
|
||||
if(fd < 0) {
|
||||
LV_LOG_ERROR("Failed to open DRM device");
|
||||
LV_LOG_WARN("Failed to open DRM device");
|
||||
}
|
||||
|
||||
return fd;
|
||||
@@ -927,7 +945,7 @@ static bool init_buffer(lv_wayland_dmabuf_ctx_t * dmabuf_ctx, lv_wl_buffer_t * b
|
||||
|
||||
buffer->bo = gbm_bo_create(ddata->gbm_device, width, height, gbm_cf, gbm_flags);
|
||||
if(!buffer->bo) {
|
||||
LV_LOG_ERROR("Failed to create GBM buffer object");
|
||||
LV_LOG_WARN("Failed to create GBM buffer object");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -935,7 +953,7 @@ static bool init_buffer(lv_wayland_dmabuf_ctx_t * dmabuf_ctx, lv_wl_buffer_t * b
|
||||
buffer->offset = gbm_bo_get_offset(buffer->bo, 0);
|
||||
buffer->dmabuf_fd = gbm_bo_get_fd(buffer->bo);
|
||||
if(buffer->dmabuf_fd < 0) {
|
||||
LV_LOG_ERROR("Failed to export GBM buffer object as a DMA-BUF fd");
|
||||
LV_LOG_WARN("Failed to export GBM buffer object as a DMA-BUF fd");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -953,7 +971,7 @@ static bool init_buffer(lv_wayland_dmabuf_ctx_t * dmabuf_ctx, lv_wl_buffer_t * b
|
||||
buffer->egl_image = eglCreateImageKHR(ddata->egl_ctx->egl_display, EGL_NO_CONTEXT,
|
||||
EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
|
||||
if(buffer->egl_image == EGL_NO_IMAGE_KHR) {
|
||||
LV_LOG_ERROR("Failed to create EGL image from DMA-BUF");
|
||||
LV_LOG_WARN("Failed to create EGL image from DMA-BUF");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ typedef struct {
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void * wl_g2d_init(void);
|
||||
static lv_result_t wl_g2d_init(void ** backend_data);
|
||||
static void wl_g2d_deinit(void * backend_ctx);
|
||||
static void wl_g2d_global_handler(void * backend_ctx, struct wl_registry * registry, uint32_t name,
|
||||
const char * interface, uint32_t version);
|
||||
@@ -121,10 +121,13 @@ static lv_wl_buffer_t * get_next_buffer(lv_wl_g2d_display_data_t * ddata);
|
||||
|
||||
static lv_wl_g2d_ctx_t ctx;
|
||||
|
||||
const lv_wayland_backend_ops_t wl_backend_ops = {
|
||||
const lv_wayland_backend_ops_t wl_g2d_ops = {
|
||||
.init = wl_g2d_init,
|
||||
.deinit = wl_g2d_deinit,
|
||||
.global_handler = wl_g2d_global_handler,
|
||||
};
|
||||
|
||||
const lv_wayland_backend_display_ops_t wl_g2d_display_ops = {
|
||||
.init_display = wl_g2d_init_display,
|
||||
.deinit_display = wl_g2d_deinit_display,
|
||||
.resize_display = wl_g2d_resize_display,
|
||||
@@ -175,10 +178,11 @@ static const struct wl_callback_listener frame_listener = {
|
||||
**********************/
|
||||
|
||||
|
||||
static void * wl_g2d_init(void)
|
||||
static lv_result_t wl_g2d_init(void ** backend_data)
|
||||
{
|
||||
lv_memset(&ctx, 0, sizeof(ctx));
|
||||
return &ctx;
|
||||
*backend_data = &ctx;
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
static void wl_g2d_deinit(void * backend_ctx)
|
||||
@@ -260,7 +264,8 @@ static void delete_buffer(lv_wl_buffer_t * buffer)
|
||||
static lv_wl_g2d_display_data_t * wl_g2d_create_display_data(lv_wl_g2d_ctx_t * ctx, lv_display_t * display,
|
||||
int32_t width, int32_t height)
|
||||
{
|
||||
lv_wl_g2d_display_data_t * ddata = lv_zalloc(sizeof(*ddata));
|
||||
if(!ctx->handler)
|
||||
lv_wl_g2d_display_data_t * ddata = lv_zalloc(sizeof(*ddata));
|
||||
LV_ASSERT_MALLOC(ddata);
|
||||
if(!ddata) {
|
||||
return NULL;
|
||||
@@ -325,11 +330,14 @@ static void wl_g2d_delete_display_data(lv_wl_g2d_display_data_t * ddata)
|
||||
|
||||
static void * wl_g2d_init_display(void * backend_ctx, lv_display_t * display, int32_t width, int32_t height)
|
||||
{
|
||||
|
||||
lv_wl_g2d_ctx_t * ctx = (lv_wl_g2d_ctx_t *)backend_ctx;
|
||||
if(!ctx->handler) {
|
||||
LV_LOG_WARN("dmabuf registry not bound. Can't initialize a display with the g2d backend");
|
||||
return NULL;
|
||||
}
|
||||
lv_wl_g2d_display_data_t * ddata = wl_g2d_create_display_data(ctx, display, width, height);
|
||||
if(!ddata) {
|
||||
LV_LOG_ERROR("Failed to create display data");
|
||||
LV_LOG_WARN("Failed to create display data");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ extern "C" {
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_wayland_private.h"
|
||||
#include "../../lvgl_public.h"
|
||||
|
||||
#if LV_USE_WAYLAND
|
||||
|
||||
@@ -30,33 +30,37 @@ extern "C" {
|
||||
|
||||
/**
|
||||
* @typedef lv_wayland_backend_init_t
|
||||
* @brief Initialize the backend context
|
||||
* @brief Initialize the backend data
|
||||
*
|
||||
* This function is called once when the Wayland driver is initialized to create
|
||||
* the global backend context. The returned pointer will be passed as backend_ctx
|
||||
* to all other backend operations.
|
||||
* the global backend data. The context written to backend_data is passed back
|
||||
* to every other operation of the backend. It may be left NULL by a backend that
|
||||
* keeps no global state.
|
||||
*
|
||||
* @return Pointer to backend-specific context data, or NULL on failure
|
||||
* @param[out] backend_data Receives a pointer to backend-specific context data
|
||||
* @return LV_RESULT_OK if the backend is usable, otherwise LV_RESULT_INVALID.
|
||||
* A backend that fails here is skipped entirely: no further operation is
|
||||
* called on it, not even deinit()
|
||||
*
|
||||
* @note This is called before any displays are created
|
||||
* @see lv_wayland_backend_deinit_t
|
||||
*/
|
||||
typedef void * (*lv_wayland_backend_init_t)(void);
|
||||
typedef lv_result_t (*lv_wayland_backend_init_t)(void ** backend_data);
|
||||
|
||||
/**
|
||||
* @typedef lv_wayland_backend_deinit_t
|
||||
* @brief Deinitialize the backend context
|
||||
* @brief Deinitialize the backend data
|
||||
*
|
||||
* This function is called when the Wayland driver is deinitialized. It must
|
||||
* clean up all resources allocated in the init function and free the backend
|
||||
* context.
|
||||
*
|
||||
* @param[in] backend_ctx Pointer to the backend context returned by init
|
||||
* @param[in] backend_data Pointer to the backend data returned by init
|
||||
*
|
||||
* @note This is called after all displays have been destroyed
|
||||
* @see lv_wayland_backend_init_t
|
||||
*/
|
||||
typedef void (*lv_wayland_backend_deinit_t)(void * backend_ctx);
|
||||
typedef void (*lv_wayland_backend_deinit_t)(void * backend_data);
|
||||
|
||||
/**
|
||||
* @typedef lv_wayland_backend_init_display_t
|
||||
@@ -65,7 +69,7 @@ typedef void (*lv_wayland_backend_deinit_t)(void * backend_ctx);
|
||||
* This function is called when creating a new LVGL display on Wayland. It should
|
||||
* allocate and initialize per-display resources needed for rendering.
|
||||
*
|
||||
* @param[in] backend_ctx Pointer to the backend context
|
||||
* @param[in] backend_data Pointer to the backend data
|
||||
* @param[in] display Pointer to the LVGL display object
|
||||
* @param[in] width Initial width of the display in pixels
|
||||
* @param[in] height Initial height of the display in pixels
|
||||
@@ -76,7 +80,7 @@ typedef void (*lv_wayland_backend_deinit_t)(void * backend_ctx);
|
||||
* @note It is expected that each display gets its own data structure in order for a backend
|
||||
* to support multiple displays
|
||||
*/
|
||||
typedef void * (*lv_wayland_backend_init_display_t)(void * backend_ctx, lv_display_t * display, int32_t width,
|
||||
typedef void * (*lv_wayland_backend_init_display_t)(void * backend_data, lv_display_t * display, int32_t width,
|
||||
int32_t height);
|
||||
|
||||
/**
|
||||
@@ -86,7 +90,7 @@ typedef void * (*lv_wayland_backend_init_display_t)(void * backend_ctx, lv_displ
|
||||
* This function is called when a display needs to be resized or when its rotation
|
||||
* is modified. The backend should update its rendering resources accordingly.
|
||||
*
|
||||
* @param[in] backend_ctx Pointer to the backend context
|
||||
* @param[in] backend_data Pointer to the backend data
|
||||
* @param[in] display Pointer to the LVGL display object being resized
|
||||
* @return Pointer to updated display-specific data, or NULL on failure
|
||||
*
|
||||
@@ -95,7 +99,7 @@ typedef void * (*lv_wayland_backend_init_display_t)(void * backend_ctx, lv_displ
|
||||
* retrieved using lv_wayland_get_backend_display_data()
|
||||
* @warning The display data is overwritten with the return value of this function
|
||||
*/
|
||||
typedef void * (*lv_wayland_backend_resize_display_t)(void * backend_ctx, lv_display_t * display);
|
||||
typedef void * (*lv_wayland_backend_resize_display_t)(void * backend_data, lv_display_t * display);
|
||||
|
||||
/**
|
||||
* @typedef lv_wayland_backend_destroy_display_t
|
||||
@@ -105,12 +109,12 @@ typedef void * (*lv_wayland_backend_resize_display_t)(void * backend_ctx, lv_dis
|
||||
* all per-display resources and free the display data that was allocated in
|
||||
* init_display.
|
||||
*
|
||||
* @param[in] backend_ctx Pointer to the backend context
|
||||
* @param[in] backend_data Pointer to the backend data
|
||||
* @param[in] display Pointer to the LVGL display object being destroyed
|
||||
*
|
||||
* @note The display data associated with this display must be freed
|
||||
*/
|
||||
typedef void (*lv_wayland_backend_destroy_display_t)(void * backend_ctx, lv_display_t * display);
|
||||
typedef void (*lv_wayland_backend_destroy_display_t)(void * backend_data, lv_display_t * display);
|
||||
|
||||
/**
|
||||
* @typedef lv_wayland_backend_global_handler_t
|
||||
@@ -120,7 +124,7 @@ typedef void (*lv_wayland_backend_destroy_display_t)(void * backend_ctx, lv_disp
|
||||
* compositor. The backend can use this to bind to Wayland protocols it requires
|
||||
* (e.g., wl_shm, EGL extensions, DMA-BUF protocols, etc.).
|
||||
*
|
||||
* @param[in] backend_ctx Pointer to the backend context
|
||||
* @param[in] backend_data Pointer to the backend data
|
||||
* @param[in] registry Wayland registry object
|
||||
* @param[in] name Numeric name of the global object
|
||||
* @param[in] interface String name of the interface (e.g., "wl_shm")
|
||||
@@ -129,34 +133,94 @@ typedef void (*lv_wayland_backend_destroy_display_t)(void * backend_ctx, lv_disp
|
||||
* @note This is called during Wayland connection setup
|
||||
* @note The backend should use wl_registry_bind() to bind to needed protocols
|
||||
*/
|
||||
typedef void (*lv_wayland_backend_global_handler_t)(void * backend_ctx, struct wl_registry * registry, uint32_t name,
|
||||
typedef void (*lv_wayland_backend_global_handler_t)(void * backend_data, struct wl_registry * registry, uint32_t name,
|
||||
const char * interface, uint32_t version);
|
||||
|
||||
/**
|
||||
* @struct lv_wayland_backend_ops_t
|
||||
* @brief Wayland backend operations structure
|
||||
*
|
||||
* This structure defines the complete set of operations that a Wayland backend
|
||||
* This structure defines the general set of operations that a Wayland backend
|
||||
* must implement. All function pointers must be non-NULL.
|
||||
*
|
||||
* @par Lifecycle Order:
|
||||
* 1. init() - Initialize backend context
|
||||
* 1. init() - Initialize backend data
|
||||
* 2. global_handler() - Called for each Wayland global (may be called multiple times)
|
||||
* 3. init_display() - Create display (may be called multiple times for multiple displays)
|
||||
* 4. resize_display() - Resize display (called as needed)
|
||||
* 5. deinit_display() - Destroy display (called once per display)
|
||||
* 6. deinit() - Clean up backend context
|
||||
* 3. deinit() - Clean up backend data
|
||||
*/
|
||||
typedef struct {
|
||||
lv_wayland_backend_init_t init; /**< Initialize backend context */
|
||||
lv_wayland_backend_init_t init; /**< Initialize backend data */
|
||||
lv_wayland_backend_global_handler_t global_handler; /**< Handle Wayland global objects */
|
||||
lv_wayland_backend_deinit_t deinit; /**< Deinitialize backend data */
|
||||
} lv_wayland_backend_ops_t;
|
||||
|
||||
/**
|
||||
* @struct lv_wayland_backend_display_ops_t
|
||||
* @brief Wayland backend display operations structure
|
||||
*
|
||||
* This structure defines the display specific set of operations that a Wayland backend
|
||||
* must implement. All function pointers must be non-NULL.
|
||||
*
|
||||
* @par Lifecycle Order:
|
||||
* 1. init_display() - Create display (may be called multiple times for multiple displays)
|
||||
* 2. resize_display() - Resize display (called as needed)
|
||||
* 3. deinit_display() - Destroy display (called once per display)
|
||||
*/
|
||||
typedef struct {
|
||||
lv_wayland_backend_init_display_t init_display; /**< Initialize a new display */
|
||||
lv_wayland_backend_resize_display_t resize_display; /**< Resize or reconfigure display */
|
||||
lv_wayland_backend_destroy_display_t deinit_display; /**< Destroy a display */
|
||||
lv_wayland_backend_deinit_t deinit; /**< Deinitialize backend context */
|
||||
} lv_wayland_backend_ops_t;
|
||||
} lv_wayland_backend_display_ops_t;
|
||||
|
||||
extern const lv_wayland_backend_ops_t wl_backend_ops;
|
||||
|
||||
typedef struct {
|
||||
const lv_wayland_backend_display_ops_t * ops; /**< Backend display specific operations */
|
||||
void * backend_data; /**< General backend data */
|
||||
void * display_data; /**< Specific display backend data */
|
||||
} lv_wayland_backend_display_data_t;
|
||||
|
||||
/** @brief Initializes every compiled-in backend
|
||||
*
|
||||
* A backend whose init() fails is marked unavailable and skipped by all the
|
||||
* functions below.
|
||||
*/
|
||||
void lv_wayland_backend_init_all(void);
|
||||
|
||||
/** @brief Deinitializes every available backend
|
||||
*/
|
||||
void lv_wayland_backend_deinit_all(void);
|
||||
|
||||
/** @brief Dispatches a global handler call to all available backends
|
||||
*
|
||||
* @param[in] registry Wayland registry object
|
||||
* @param[in] name Numeric name of the global object
|
||||
* @param[in] interface String name of the interface
|
||||
* @param[in] version Version number of the interface
|
||||
*/
|
||||
void lv_wayland_backend_global_handler(struct wl_registry * registry, uint32_t name,
|
||||
const char * interface, uint32_t version);
|
||||
|
||||
/** @brief Loops through all available backends to find one capable of initializing a display
|
||||
*
|
||||
* The function loops through all available backends until one can initialize a display
|
||||
*
|
||||
* @param[out] backend_ddata Backend display data
|
||||
* @param[in] display The display to initialize for
|
||||
* @param[in] width the display width
|
||||
* @param[in] height the display height
|
||||
* @return LV_RESULT_OK if the display was initialized else LV_RESULT_INVALID
|
||||
*/
|
||||
lv_result_t lv_wayland_backend_init_display(lv_wayland_backend_display_data_t * backend_ddata,
|
||||
lv_display_t * display,
|
||||
int32_t width,
|
||||
int32_t height);
|
||||
|
||||
/** @brief Deinitializes a display
|
||||
*
|
||||
* @param[in] backend_ddata Backend display data of the display
|
||||
* @param[in] display The display to deinitialize
|
||||
*/
|
||||
void lv_wayland_backend_deinit_display(lv_wayland_backend_display_data_t * backend_ddata, lv_display_t * display);
|
||||
|
||||
/** @brief Get the backend-specific display data
|
||||
*
|
||||
|
||||
@@ -54,7 +54,7 @@ typedef struct {
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void * shm_init(void);
|
||||
static lv_result_t shm_init(void ** backend_data);
|
||||
static void shm_deinit(void *);
|
||||
static void * shm_init_display(void * backend_ctx, lv_display_t * display, int32_t width, int32_t height);
|
||||
static void * shm_resize_display(void * backend_ctx, lv_display_t * display);
|
||||
@@ -86,10 +86,13 @@ static const struct wl_buffer_listener buffer_listener = {
|
||||
.release = buffer_release
|
||||
};
|
||||
|
||||
const lv_wayland_backend_ops_t wl_backend_ops = {
|
||||
const lv_wayland_backend_ops_t wl_shm_ops = {
|
||||
.init = shm_init,
|
||||
.deinit = shm_deinit,
|
||||
.global_handler = shm_global_handler,
|
||||
};
|
||||
|
||||
const lv_wayland_backend_display_ops_t wl_shm_display_ops = {
|
||||
.init_display = shm_init_display,
|
||||
.deinit_display = shm_deinit_display,
|
||||
.resize_display = shm_resize_display,
|
||||
@@ -145,15 +148,19 @@ static int32_t lv_cf_to_shm_cf(lv_color_format_t cf)
|
||||
}
|
||||
}
|
||||
|
||||
static void * shm_init(void)
|
||||
static lv_result_t shm_init(void ** backend_data)
|
||||
{
|
||||
lv_memzero(&shm_ctx, sizeof(shm_ctx));
|
||||
return &shm_ctx;
|
||||
*backend_data = &shm_ctx;
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
static void shm_deinit(void * backend_ctx)
|
||||
{
|
||||
lv_wl_shm_ctx_t * ctx = backend_ctx;
|
||||
if(!ctx) {
|
||||
return;
|
||||
}
|
||||
if(ctx->shm) {
|
||||
wl_shm_destroy(ctx->shm);
|
||||
ctx->shm = NULL;
|
||||
@@ -459,4 +466,4 @@ static void shm_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t *
|
||||
ddata->curr_wl_buffer_idx = (ddata->curr_wl_buffer_idx + 1) % LV_WL_SHM_BUF_COUNT;
|
||||
}
|
||||
|
||||
#endif /*LV_WAYLAND_USE_SHM*/
|
||||
#endif /*LV_USE_WAYLAND*/
|
||||
|
||||
@@ -19,6 +19,7 @@ extern "C" {
|
||||
#if LV_USE_WAYLAND
|
||||
|
||||
|
||||
#include "lv_wayland_backend_private.h"
|
||||
#include <sys/poll.h>
|
||||
#include <wayland-client-protocol.h>
|
||||
#include <wayland_xdg_shell.h>
|
||||
@@ -127,12 +128,12 @@ typedef struct {
|
||||
|
||||
|
||||
typedef struct _lv_wl_window_t {
|
||||
void * backend_display_data;
|
||||
lv_display_t * lv_disp;
|
||||
lv_indev_t * lv_indev_pointer;
|
||||
lv_indev_t * lv_indev_pointeraxis;
|
||||
lv_indev_t * lv_indev_touch;
|
||||
lv_indev_t * lv_indev_keyboard;
|
||||
lv_wayland_backend_display_data_t backend_ddata;
|
||||
lv_wayland_display_close_cb_t close_cb;
|
||||
lv_wl_window_xdg_t xdg;
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
#if LV_USE_WAYLAND
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -84,7 +83,16 @@ lv_display_t * lv_wayland_window_create(uint32_t hor_res, uint32_t ver_res, char
|
||||
lv_display_set_driver_data(window->lv_disp, window);
|
||||
|
||||
/* Initialize display driver */
|
||||
window->backend_display_data = wl_backend_ops.init_display(lv_wl_ctx.backend_data, window->lv_disp, hor_res, ver_res);
|
||||
lv_result_t res = lv_wayland_backend_init_display(&window->backend_ddata,
|
||||
window->lv_disp, hor_res,
|
||||
ver_res);
|
||||
if(res != LV_RESULT_OK) {
|
||||
LV_LOG_ERROR("Failed to create display");
|
||||
goto init_display_err;
|
||||
}
|
||||
|
||||
/*Assert here so that we can freely use these operations afterwards*/
|
||||
LV_ASSERT_NULL(window->backend_ddata.ops);
|
||||
|
||||
lv_wayland_xdg_configure_surface(window);
|
||||
|
||||
@@ -123,7 +131,8 @@ lv_display_t * lv_wayland_window_create(uint32_t hor_res, uint32_t ver_res, char
|
||||
LV_LOG_ERROR("failed to register keyboard indev");
|
||||
}
|
||||
return window->lv_disp;
|
||||
|
||||
init_display_err:
|
||||
lv_wayland_xdg_delete_window(&window->xdg);
|
||||
create_window_err:
|
||||
wl_surface_destroy(window->body);
|
||||
create_surface_err:
|
||||
@@ -140,7 +149,7 @@ void * lv_wayland_get_backend_display_data(lv_display_t * display)
|
||||
LV_ASSERT_NULL(display);
|
||||
lv_wl_window_t * window = lv_display_get_driver_data(display);
|
||||
LV_ASSERT_NULL(window);
|
||||
return window->backend_display_data;
|
||||
return window->backend_ddata.display_data;
|
||||
}
|
||||
|
||||
void lv_wayland_set_backend_display_data(lv_display_t * display, void * data)
|
||||
@@ -148,7 +157,7 @@ void lv_wayland_set_backend_display_data(lv_display_t * display, void * data)
|
||||
LV_ASSERT_NULL(display);
|
||||
lv_wl_window_t * window = lv_display_get_driver_data(display);
|
||||
LV_ASSERT_NULL(window);
|
||||
window->backend_display_data = data;
|
||||
window->backend_ddata.display_data = data;
|
||||
}
|
||||
|
||||
struct wl_surface * lv_wayland_get_window_surface(lv_display_t * display)
|
||||
@@ -298,9 +307,7 @@ static void delete_event(lv_event_t * e)
|
||||
|
||||
/* Make sure buffer is correctly released*/
|
||||
wl_display_roundtrip(lv_wl_ctx.wl_display);
|
||||
|
||||
wl_backend_ops.deinit_display(window->backend_display_data, window->lv_disp);
|
||||
window->backend_display_data = NULL;
|
||||
lv_wayland_backend_deinit_display(&window->backend_ddata, window->lv_disp);
|
||||
|
||||
if(LV_WAYLAND_DIRECT_EXIT) {
|
||||
lv_display_set_driver_data(window->lv_disp, NULL);
|
||||
@@ -337,7 +344,15 @@ static void res_changed_event(lv_event_t * e)
|
||||
{
|
||||
lv_display_t * display = (lv_display_t *) lv_event_get_target(e);
|
||||
lv_wl_window_t * window = lv_display_get_driver_data(display);
|
||||
window->backend_display_data = wl_backend_ops.resize_display(lv_wl_ctx.backend_data, display);
|
||||
|
||||
void * display_data = window->backend_ddata.ops->resize_display(window->backend_ddata.backend_data, display);
|
||||
if(!display_data) {
|
||||
/* The backend kept the display data of the previous resolution alive */
|
||||
LV_LOG_ERROR("Failed to resize the display, keeping the previous configuration");
|
||||
return;
|
||||
}
|
||||
|
||||
window->backend_ddata.display_data = display_data;
|
||||
}
|
||||
|
||||
#endif /* LV_USE_WAYLAND */
|
||||
|
||||
@@ -3,5 +3,7 @@
|
||||
CONFIG_LV_USE_DRAW_OPENGLES=y
|
||||
|
||||
CONFIG_LV_LINUX_DRM_BACKEND_EGL=y
|
||||
CONFIG_LV_WAYLAND_BACKEND_EGL=y
|
||||
CONFIG_LV_SDL_BACKEND_EGL=y
|
||||
|
||||
CONFIG_LV_WAYLAND_USE_EGL=y
|
||||
CONFIG_LV_WAYLAND_USE_SHM=y
|
||||
|
||||
@@ -7,8 +7,7 @@ CONFIG_LV_USE_LINUX_DRM=y
|
||||
CONFIG_LV_LINUX_DRM_BACKEND_FBDEV=y
|
||||
|
||||
CONFIG_LV_USE_WAYLAND=y
|
||||
# CONFIG_LV_WAYLAND_AUTO_BACKEND is not set
|
||||
CONFIG_LV_WAYLAND_BACKEND_SHM=y
|
||||
CONFIG_LV_WAYLAND_USE_SHM=y
|
||||
|
||||
# X11 has no backend choice, it is software only
|
||||
CONFIG_LV_USE_X11=y
|
||||
|
||||
Reference in New Issue
Block a user