feat(OpenGL): add EGL support (#8677)

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: André Costa <andre_miguel_costa@hotmail.com>
This commit is contained in:
Liam Howatt
2025-09-04 18:07:18 -04:00
committed by GitHub
parent c9b9a5ccf4
commit 91c1e38104
37 changed files with 2475 additions and 851 deletions
@@ -1,3 +1,141 @@
.. _linux_drm:
===
DRM
===
===
Overview
--------
The **DRM** (Direct Rendering Manager) display driver provides support for rendering
LVGL directly to Linux framebuffer devices through the DRM/KMS subsystem.
It enables running LVGL without a windowing system such as X11 or Wayland,
making it suitable for embedded devices, single-board computers, and direct-to-display
applications.
The DRM driver interacts directly with the GPU or display controller through
``/dev/dri/cardX`` nodes.
Getting Started with DRM
------------------------
Prerequisites
~~~~~~~~~~~~~
The DRM driver requires:
- A Linux system with DRM/KMS support enabled in the kernel.
- Access to a DRM device node, typically ``/dev/dri/card0``.
- Proper permissions to access DRM devices (e.g. running as root or adding the user
to the ``video`` group).
On Debian/Ubuntu-based systems:
.. code-block:: shell
sudo apt-get install libdrm-dev
Configure DRM Driver
~~~~~~~~~~~~~~~~~~~~
1. Enable the DRM driver support in ``lv_conf.h``, by CMake compiler define, or by KConfig:
.. code-block:: c
#define LV_USE_LINUX_DRM 1
2. Link against ``libdrm`` when building.
.. _linux_drm_basic_usage:
Basic Usage
~~~~~~~~~~~
.. code-block:: c
#include "lvgl/lvgl.h"
#include "lvgl/demos/lv_demos.h"
#include "lvgl/drivers/drm/lv_linux_drm.h"
int main(void)
{
/* Initialize LVGL */
lv_init();
/* DRM device node */
const char *device = "/dev/dri/card0";
/* Create a DRM display */
lv_display_t *disp = lv_linux_drm_create();
/* Set DRM device file and connector */
/* The 2nd argument is the DRM device path */
/* The 3rd argument is the connector_id (-1 = auto-select first available) */
lv_linux_drm_set_file(disp, device, -1);
/* Create demo widgets */
lv_demo_widgets();
/* Handle LVGL tasks */
while (1) {
uint32_t time_until_next = lv_timer_handler();
if(time_until_next == LV_NO_TIMER_READY) {
time_until_next = LV_DEF_REFR_PERIOD;
}
lv_delay_ms(time_until_next);
}
return 0;
}
Notes
~~~~~
- ``connector_id`` specifies which display output (HDMI, eDP, DP, etc.) should be used.
If ``-1`` is passed, the DRM driver will try to automatically pick the first available connector.
- DRM requires proper modesetting. By default, LVGL will select a preferred display mode.
Using DRM with GBM
------------------
The DRM driver can optionally use **GBM** (Generic Buffer Management) for buffer allocation.
This allows the driver to use GPU-friendly buffer objects instead of simple dumb framebuffers.
1. Enable the following option in your ``lv_conf.h`` (or via Kconfig/CMake):
.. code-block:: c
#define LV_USE_LINUX_DRM_GBM_BUFFERS 1
2. Link against ``libgbm`` when building.
When this option is enabled:
- Buffers will be allocated using GBM.
- This can improve performance and compatibility on platforms where GBM is supported.
Using DRM with EGL
------------------
The DRM driver can also be combined with :ref:`egl_driver` for hardware-accelerated
rendering via EGL/GLES.
To enable this, set the following options in your ``lv_conf.h`` (or via Kconfig/CMake):
.. code-block:: c
#define LV_USE_LINUX_DRM 1
#define LV_USE_LINUX_DRM_GBM_BUFFERS 1
#define LV_LINUX_DRM_USE_EGL 1
#define LV_USE_OPENGLES 1
#define LV_USE_DRAW_OPENGLES 1 /* optional but recommended for performance */
When ``LV_LINUX_DRM_USE_EGL`` is enabled, the DRM driver will automatically initialize EGL.
No special setup is required beyond the basic DRM initialization shown in :ref:`linux_drm_basic_usage`.
For a detailed overview of EGL usage and configuration, see :ref:`egl_driver`.
@@ -0,0 +1,63 @@
.. _egl_driver:
===
EGL
===
Overview
--------
The **EGL** driver provides support for creating LVGL displays using the EGL (Embedded-System Graphics Library) API.
EGL is a lower-level API that is more closely tied to the underlying drivers of the platform.
The OpenGL support in LVGL is intended to be portable between different APIs. Currently, there is support for GLFW and EGL.
Using EGL requires some additional platform integration.
:cpp:func:`lv_opengles_egl_window_create` can be used to create a :cpp:type:`lv_opengles_window_t`
which can be used with the same generic LVGL OpenGL APIs as a GLFW window.
EGL with DRM
------------
EGL can be used together with the DRM driver for hardware-accelerated rendering.
When ``LV_LINUX_DRM_USE_EGL`` is enabled, the DRM driver will automatically set up EGL.
No additional initialization is required beyond the normal DRM setup.
See :ref:`linux_drm` for configuration and a basic usage example.
EGL without DRM (Experimental)
------------------------------
.. warning::
This feature is experimental and the API is private. Expect breaking changes.
If you want to use EGL without being tied to DRM, you can enable ``LV_USE_EGL`` using a compiler definition.
This API is currently private and experimental, and people should expect breaking changes.
.. code-block:: bash
# Enable standalone EGL (experimental)
-DLV_USE_EGL=1
This allows you to use EGL with your own context management or other platforms, but the API may change
without notice in future versions.
Render Direct to Window
-----------------------
.. warning::
This feature is incomplete and has bugs.
Performance can be improved if the LVGL OpenGL driver renders its cached textures directly to the window
(and :c:macro:`LV_USE_DRAW_OPENGLES` is enabled). This can be done by creating the display with
:cpp:func:`lv_opengles_window_display_create` instead of :cpp:func:`lv_opengles_texture_create` +
:cpp:func:`lv_opengles_texture_get_texture_id` + :cpp:func:`lv_opengles_window_add_texture`.
Performance should be better with GLFW than EGL. EGL currently has issues when used this way.
Improving Performance
---------------------
There is a renderer in LVGL which caches software-rendered areas as OpenGL textures.
See :ref:`opengl_texture_caching_renderer` to learn more about it.
@@ -1,4 +1,4 @@
.. _opengl_es_driver:
.. _glfw_driver:
====
GLFW
@@ -7,34 +7,34 @@ GLFW
Overview
--------
The **OpenGL ES** display/input
`driver <https://github.com/lvgl/lvgl/tree/master/src/drivers/glfw/lv_opengles_driver.c>`__
offers support for simulating the LVGL display and keyboard/mouse inputs in an desktop
window created via GLFW.
The **GLFW** display/input driver offers support for creating
LVGL displays and keyboard/mouse inputs that can be used in an OpenGL context.
It can be used like **Wayland**, **XCB**, **SDL** or **Qt** or it can be used for more embedded applications.
It is an alternative to **Wayland**, **XCB**, **SDL** or **Qt**.
The GLFW driver is a quick way to get started on PC-like platforms.
The main purpose for this driver is for testing/debugging the LVGL application in
an **OpenGL** simulation window.
Getting Started with GLFW
-------------------------
Prerequisites
-------------
~~~~~~~~~~~~~
The OpenGL driver uses GLEW GLFW to access the OpenGL window manager.
The GLFW 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
-----------------------
Configure GLFW 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-block:: c
#define LV_USE_OPENGLES 1
Basic Usage
-----------
~~~~~~~~~~~
.. code-block:: c
@@ -51,7 +51,7 @@ Basic Usage
lv_init();
/* create a window and initialize OpenGL */
lv_glfw_window_t * window = lv_glfw_window_create(WIDTH, HEIGHT, true);
lv_opengles_window_t * window = lv_opengles_glfw_window_create(WIDTH, HEIGHT, true);
/* create a display that flushes to a texture */
lv_display_t * texture = lv_opengles_texture_create(WIDTH, HEIGHT);
@@ -59,10 +59,10 @@ Basic Usage
/* add the texture to the window */
unsigned int texture_id = lv_opengles_texture_get_texture_id(texture);
lv_glfw_texture_t * window_texture = lv_glfw_window_add_texture(window, texture_id, WIDTH, HEIGHT);
lv_opengles_window_texture_t * window_texture = lv_opengles_window_add_texture(window, texture_id, WIDTH, HEIGHT);
/* get the mouse indev of the window texture */
lv_indev_t * mouse = lv_glfw_texture_get_mouse_indev(window_texture);
lv_indev_t * mouse = lv_opengles_window_texture_get_mouse_indev(window_texture);
/* add a cursor to the mouse indev */
LV_IMAGE_DECLARE(mouse_cursor_icon);
@@ -84,9 +84,9 @@ Basic Usage
}
Advanced Usage
--------------
~~~~~~~~~~~~~~
The OpenGL driver can draw textures from the user. A third-party library could be
The GLFW driver can draw textures from the user. A third-party library could be
used to add content to a texture and the driver will draw the texture in the window.
.. code-block:: c
@@ -106,7 +106,7 @@ used to add content to a texture and the driver will draw the texture in the win
/* create a window and initialize OpenGL */
/* multiple windows can be created */
lv_glfw_window_t * window = lv_glfw_window_create(WIDTH, HEIGHT, true);
lv_opengles_window_t * window = lv_opengles_glfw_window_create(WIDTH, HEIGHT, true);
/****************************
* OPTIONAL MAIN TEXTURE
@@ -118,10 +118,10 @@ used to add content to a texture and the driver will draw the texture in the win
/* add the main texture to the window */
unsigned int main_texture_id = lv_opengles_texture_get_texture_id(main_texture);
lv_glfw_texture_t * window_main_texture = lv_glfw_window_add_texture(window, main_texture_id, WIDTH, HEIGHT);
lv_opengles_window_texture_t * window_main_texture = lv_opengles_window_add_texture(window, main_texture_id, WIDTH, HEIGHT);
/* get the mouse indev of this main texture */
lv_indev_t * main_texture_mouse = lv_glfw_texture_get_mouse_indev(window_main_texture);
lv_indev_t * main_texture_mouse = lv_opengles_window_texture_get_mouse_indev(window_main_texture);
/* add a cursor to the mouse indev */
LV_IMAGE_DECLARE(mouse_cursor_icon);
@@ -143,7 +143,7 @@ used to add content to a texture and the driver will draw the texture in the win
/* add the sub texture to the window */
unsigned int sub_texture_id = lv_opengles_texture_get_texture_id(sub_texture);
lv_glfw_texture_t * window_sub_texture = lv_glfw_window_add_texture(window, sub_texture_id, sub_texture_w, sub_texture_h);
lv_opengles_window_texture_t * window_sub_texture = lv_opengles_window_add_texture(window, sub_texture_id, sub_texture_w, sub_texture_h);
/* create Widgets on the screen of the sub texture */
lv_display_set_default(sub_texture);
@@ -151,11 +151,11 @@ used to add content to a texture and the driver will draw the texture in the win
lv_display_set_default(main_texture);
/* position the sub texture within the window */
lv_glfw_texture_set_x(window_sub_texture, 250);
lv_glfw_texture_set_y(window_sub_texture, 150);
lv_opengles_window_texture_set_x(window_sub_texture, 250);
lv_opengles_window_texture_set_y(window_sub_texture, 150);
/* optionally change the opacity of the sub texture */
lv_glfw_texture_set_opa(window_sub_texture, LV_OPA_80);
lv_opengles_window_texture_set_opa(window_sub_texture, LV_OPA_80);
/*********************************************
* USE AN EXTERNAL OPENGL TEXTURE IN LVGL
@@ -186,12 +186,12 @@ used to add content to a texture and the driver will draw the texture in the win
glBindTexture(GL_TEXTURE_2D, 0);
/* add the external texture to the window */
lv_glfw_texture_t * window_external_texture = lv_glfw_window_add_texture(window, external_texture_id, img_cogwheel_argb.header.w, img_cogwheel_argb.header.h);
lv_opengles_window_texture_t * window_external_texture = lv_opengles_window_add_texture(window, external_texture_id, img_cogwheel_argb.header.w, img_cogwheel_argb.header.h);
/* set the position and opacity of the external texture within the window */
lv_glfw_texture_set_x(window_external_texture, 20);
lv_glfw_texture_set_y(window_external_texture, 20);
lv_glfw_texture_set_opa(window_external_texture, LV_OPA_70);
lv_opengles_window_texture_set_x(window_external_texture, 20);
lv_opengles_window_texture_set_y(window_external_texture, 20);
lv_opengles_window_texture_set_opa(window_external_texture, LV_OPA_70);
/*********************************************
* USE AN LVGL TEXTURE IN ANOTHER LIBRARY
@@ -203,28 +203,9 @@ used to add content to a texture and the driver will draw the texture in the win
third_party_lib_use_texture(sub_texture_id);
}
OpenGL Texture Caching Renderer
-------------------------------
Improving Performance
---------------------
There is a renderer in LVGL which caches software-rendered areas as OpenGL textures.
The textures are retrieved from the cache and reused when there is a match.
The performance will be drastically improved in most cases.
.. code-block:: c
#define LV_USE_DRAW_OPENGLES 1
Known Limitations
~~~~~~~~~~~~~~~~~
- Performance will be the same or slightly worse if the drawn areas are never found in the cache
due to Widgets with continuously varying colors or shapes. One example is a label whose color
is set to a random value every frame, as in the "Multiple labels" scene of the benchmark demo.
- Layers with transparent pixels and an overall layer transparency will not blend correctly.
The effect can be observed in the "Containers with opa_layer" scene of the benchmark demo
in the border corners.
- Layers with rotation are not currently supported. Images with rotation are fine.
.. Comment: The above blank line is necessary for Sphinx to not complain,
since it looks for the blank line after a bullet list.
See :ref:`opengl_texture_caching_renderer` to learn more about it.
@@ -9,7 +9,9 @@ Drivers
fbdev
drm
opengl
glfw
egl
wayland
X11
evdev
@@ -0,0 +1,101 @@
.. _opengl_driver:
==============
OpenGL Driver
==============
Overview
--------
The **OpenGL** display driver is a generic driver that creates textures for embedding
LVGL content in other applications. The goal is to create textures that people can
embed in other applications. The OpenGL context must be created by the user or they
can use GLFW or EGL as backends.
Getting Started with OpenGL
---------------------------
Prerequisites
~~~~~~~~~~~~~
An OpenGL context must be created before using the OpenGL driver. You can create this using:
- GLFW (see :ref:`GLFW driver <glfw_driver>`)
- EGL (see :ref:`EGL driver <egl_driver>`)
- Your own OpenGL context management
Configure OpenGL Driver
~~~~~~~~~~~~~~~~~~~~~~~
1. Enable the OpenGL driver support in lv_conf.h, by cmake compiler define or by KConfig
.. code-block:: c
#define LV_USE_OPENGLES 1
Basic Usage
~~~~~~~~~~~
.. code-block:: c
#include "lvgl/lvgl.h"
#define WIDTH 640
#define HEIGHT 480
int main()
{
/* initialize lvgl */
lv_init();
/* NOTE: OpenGL context must be created before this point */
/* create a display that flushes to a texture */
lv_display_t * texture = lv_opengles_texture_create(WIDTH, HEIGHT);
lv_display_set_default(texture);
/* get the texture ID for use in your application */
unsigned int texture_id = lv_opengles_texture_get_texture_id(texture);
/* create Widgets on the screen */
lv_demo_widgets();
while (1)
{
uint32_t time_until_next = lv_timer_handler();
if(time_until_next == LV_NO_TIMER_READY) time_until_next = LV_DEF_REFR_PERIOD;
lv_delay_ms(time_until_next);
/* use texture_id in your OpenGL rendering */
your_opengl_render_function(texture_id);
}
return 0;
}
.. _opengl_texture_caching_renderer:
OpenGL Texture Caching Renderer
-------------------------------
There is a renderer in LVGL which caches software-rendered areas as OpenGL textures.
The textures are retrieved from the cache and reused when there is a match.
The performance will be drastically improved in most cases.
.. code-block:: c
#define LV_USE_DRAW_OPENGLES 1
Known Limitations
~~~~~~~~~~~~~~~~~
- Performance will be the same or slightly worse if the drawn areas are never found in the cache
due to Widgets with continuously varying colors or shapes. One example is a label whose color
is set to a random value every frame, as in the "Multiple labels" scene of the benchmark demo.
- Layers with transparent pixels and an overall layer transparency will not blend correctly.
The effect can be observed in the "Containers with opa_layer" scene of the benchmark demo
in the border corners.
- Layers with rotation are not currently supported. Images with rotation are fine.
+3 -3
View File
@@ -207,7 +207,7 @@ Setup
3. **Setup OpenGL ES Driver**
Follow the OpenGL ES driver setup documentation (:ref:``opengl_es_driver``) to configure GLFW and OpenGL ES support for your platform.
Follow the OpenGL ES driver setup documentation (:ref:`opengl_driver`) to configure GLFW and OpenGL ES support for your platform.
4. **Basic Setup Example**
@@ -219,10 +219,10 @@ Setup
lv_init();
/* GLFW setup */
lv_glfw_window_t *window = lv_glfw_window_create(WINDOW_WIDTH, WINDOW_HEIGHT, true);
lv_opengles_window_t *window = lv_opengles_glfw_window_create(WINDOW_WIDTH, WINDOW_HEIGHT, true);
lv_display_t *display = lv_opengles_texture_create(WINDOW_WIDTH, WINDOW_HEIGHT);
unsigned int texture_id = lv_opengles_texture_get_texture_id(display);
lv_glfw_window_add_texture(window, texture_id, WINDOW_WIDTH, WINDOW_HEIGHT);
lv_opengles_window_add_texture(window, texture_id, WINDOW_WIDTH, WINDOW_HEIGHT);
/* Load and display glTF demo */
lv_demo_gltf("A:<path/to/gltf>");
+1 -1
View File
@@ -34,7 +34,7 @@ OpenGL is the first supported 3D graphics back-end. The following must be enable
- :c:macro:`LV_USE_OPENGLES`
- :c:macro:`LV_USE_DRAW_OPENGLES`
See :ref:`LVGL's OpenGLES driver docs <opengl_es_driver>` to create a window and a
See :ref:`LVGL's OpenGLES driver docs <opengl_driver>` to create a window and a
display texture.
The `lv_example_3dtexture <https://github.com/lvgl/lv_example_3dtexture>` repository is a
+1 -1
View File
@@ -1164,7 +1164,7 @@
* shared across sub-systems and libraries using the Linux DMA-BUF API.
* The GBM library aims to provide a platform independent memory management system
* it supports the major GPU vendors - This option requires linking with libgbm */
#define LV_LINUX_DRM_GBM_BUFFERS 0
#define LV_USE_LINUX_DRM_GBM_BUFFERS 0
#endif
+12 -2
View File
@@ -360,9 +360,13 @@
#define LV_USE_DRAW_DMA2D_INTERRUPT 0
#endif
/** Draw using cached OpenGLES textures */
/** Draw using cached OpenGLES textures. Requires LV_USE_OPENGLES */
#define LV_USE_DRAW_OPENGLES 0
#if LV_USE_DRAW_OPENGLES
#define LV_DRAW_OPENGLES_TEXTURE_CACHE_COUNT 64
#endif
/** Draw using espressif PPA accelerator */
#define LV_USE_PPA 0
#if LV_USE_PPA
@@ -1309,6 +1313,8 @@
* The GBM library aims to provide a platform independent memory management system
* it supports the major GPU vendors - This option requires linking with libgbm */
#define LV_USE_LINUX_DRM_GBM_BUFFERS 0
#define LV_LINUX_DRM_USE_EGL 0
#endif
/** Interface for TFT_eSPI */
@@ -1375,12 +1381,16 @@
#define LV_UEFI_USE_MEMORY_SERVICES 0 /**< Use the memory functions from the boot services table */
#endif
/** Use OpenGL to open window on PC and handle mouse and keyboard */
/** Use a generic OpenGL driver that can be used to embed in other applications or used with GLFW/EGL */
#define LV_USE_OPENGLES 0
#if LV_USE_OPENGLES
#define LV_USE_OPENGLES_DEBUG 1 /**< Enable or disable debug for opengles */
#endif
/** Use GLFW to open window on PC and handle mouse and keyboard. Requires*/
#define LV_USE_GLFW 0
/** QNX Screen display and input drivers */
#define LV_USE_QNX 0
#if LV_USE_QNX
+8
View File
@@ -215,6 +215,10 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN);
#define LV_WAYLAND_WL_SHELL 0
#endif /* LV_USE_WAYLAND */
#if LV_USE_LINUX_DRM == 0
#define LV_LINUX_DRM_USE_EGL 0
#endif /*LV_USE_LINUX_DRM*/
#if LV_USE_SYSMON == 0
#define LV_USE_PERF_MONITOR 0
#define LV_USE_MEM_MONITOR 0
@@ -257,6 +261,10 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN);
#endif
#endif
#ifndef LV_USE_EGL
#define LV_USE_EGL LV_LINUX_DRM_USE_EGL
#endif /* LV_USE_EGL */
#if LV_USE_OS
#if (LV_USE_FREETYPE || LV_USE_THORVG) && LV_DRAW_THREAD_STACK_SIZE < (32 * 1024)
#warning "Increase LV_DRAW_THREAD_STACK_SIZE to at least 32KB for FreeType or ThorVG."
+50 -47
View File
@@ -11,11 +11,10 @@
#if LV_USE_DRAW_OPENGLES
#include "../lv_draw_private.h"
#include "../../misc/cache/lv_cache_entry_private.h"
#include "../../drivers/glfw/lv_opengles_debug.h"
#include "../../drivers/glfw/lv_opengles_texture.h"
#include "../../drivers/glfw/lv_opengles_driver.h"
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "../../drivers/opengles/lv_opengles_debug.h"
#include "../../drivers/opengles/lv_opengles_texture.h"
#include "../../drivers/opengles/lv_opengles_driver.h"
#include "../../drivers/opengles/lv_opengles_private.h"
#include "../../draw/lv_draw_label.h"
#include "../../draw/lv_draw_rect.h"
#include "../../draw/lv_draw_arc.h"
@@ -101,7 +100,7 @@ void lv_draw_opengles_init(void)
draw_opengles_unit->base_unit.evaluate_cb = evaluate;
draw_opengles_unit->base_unit.name = "OPENGLES";
draw_opengles_unit->texture_cache = lv_cache_create(&lv_cache_class_lru_rb_count,
sizeof(cache_data_t), 128, (lv_cache_ops_t) {
sizeof(cache_data_t), LV_DRAW_OPENGLES_TEXTURE_CACHE_COUNT, (lv_cache_ops_t) {
.compare_cb = (lv_cache_compare_cb_t)opengles_texture_cache_compare_cb,
.create_cb = (lv_cache_create_cb_t)opengles_texture_cache_create_cb,
.free_cb = (lv_cache_free_cb_t)opengles_texture_cache_free_cb,
@@ -195,9 +194,6 @@ static int32_t dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer)
if(texture == 0) {
lv_display_t * disp = lv_refr_get_disp_refreshing();
if(layer != disp->layer_head) {
void * buf = lv_draw_layer_alloc_buf(layer);
if(buf == NULL) return -1;
int32_t w = lv_area_get_width(&layer->buf_area);
int32_t h = lv_area_get_height(&layer->buf_area);
@@ -413,32 +409,33 @@ static void blend_texture_layer(lv_draw_task_t * t)
lv_layer_t * dest_layer = t->target_layer;
unsigned int target_texture = layer_get_texture(dest_layer);
LV_ASSERT(target_texture != 0);
int32_t targ_tex_w = lv_area_get_width(&dest_layer->buf_area);
int32_t targ_tex_h = lv_area_get_height(&dest_layer->buf_area);
GL_CALL(glBindTexture(GL_TEXTURE_2D, target_texture));
unsigned int framebuffer = get_framebuffer(u);
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer));
GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target_texture, 0));
if(target_texture) {
unsigned int framebuffer = get_framebuffer(u);
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer));
GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target_texture, 0));
}
lv_opengles_viewport(0, 0, targ_tex_w, targ_tex_h);
// TODO rotation
bool h_flip = false;
bool v_flip = false;
#if LV_USE_3DTEXTURE
if(t->type == LV_DRAW_TASK_TYPE_3D) {
lv_draw_3d_dsc_t * _3d_dsc = (lv_draw_3d_dsc_t *)t->draw_dsc;
h_flip = _3d_dsc->h_flip;
v_flip = _3d_dsc->v_flip;
}
#endif
lv_opengles_render_texture(src_texture, &area, draw_dsc->opa, targ_tex_w, targ_tex_h, &t->clip_area, h_flip,
v_flip);
!v_flip);
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
if(target_texture) {
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
}
GL_CALL(glBindTexture(GL_TEXTURE_2D, 0));
GL_CALL(glDeleteTextures(1, &src_texture));
LV_PROFILER_DRAW_END;
}
@@ -451,11 +448,13 @@ static void draw_from_cached_texture(lv_draw_task_t * t)
data_to_find.draw_dsc = (lv_draw_dsc_base_t *)t->draw_dsc;
bool h_flip = false;
bool v_flip = false;
#if LV_USE_3DTEXTURE
if(t->type == LV_DRAW_TASK_TYPE_3D) {
lv_draw_3d_dsc_t * _3d_dsc = (lv_draw_3d_dsc_t *)t->draw_dsc;
h_flip = _3d_dsc->h_flip;
v_flip = _3d_dsc->v_flip;
}
#endif
data_to_find.w = lv_area_get_width(&t->_real_area);
data_to_find.h = lv_area_get_height(&t->_real_area);
data_to_find.texture = 0;
@@ -515,15 +514,14 @@ static void draw_from_cached_texture(lv_draw_task_t * t)
lv_layer_t * dest_layer = t->target_layer;
unsigned int target_texture = layer_get_texture(dest_layer);
LV_ASSERT(target_texture != 0);
int32_t targ_tex_w = lv_area_get_width(&dest_layer->buf_area);
int32_t targ_tex_h = lv_area_get_height(&dest_layer->buf_area);
GL_CALL(glBindTexture(GL_TEXTURE_2D, target_texture));
unsigned int framebuffer = get_framebuffer(u);
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer));
GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target_texture, 0));
if(target_texture) {
unsigned int framebuffer = get_framebuffer(u);
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer));
GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target_texture, 0));
}
lv_opengles_viewport(0, 0, targ_tex_w, targ_tex_h);
lv_area_move(&t->clip_area, -dest_layer->buf_area.x1, -dest_layer->buf_area.y1);
@@ -531,7 +529,9 @@ static void draw_from_cached_texture(lv_draw_task_t * t)
lv_area_move(&render_area, -dest_layer->buf_area.x1, -dest_layer->buf_area.y1);
lv_opengles_render_texture(texture, &render_area, 0xff, targ_tex_w, targ_tex_h, &t->clip_area, h_flip, v_flip);
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
if(target_texture) {
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
}
lv_cache_release(u->texture_cache, entry_cached, u);
@@ -551,6 +551,8 @@ static void execute_drawing(lv_draw_opengles_unit_t * u)
lv_draw_task_t * t = u->task_act;
t->draw_unit = (lv_draw_unit_t *)u;
/* the shader-based fill is not working reliably with EGL. */
#if !LV_USE_EGL
if(t->type == LV_DRAW_TASK_TYPE_FILL) {
lv_draw_fill_dsc_t * fill_dsc = t->draw_dsc;
if(fill_dsc->radius == 0 && fill_dsc->grad.dir == LV_GRAD_DIR_NONE) {
@@ -560,22 +562,26 @@ static void execute_drawing(lv_draw_opengles_unit_t * u)
lv_area_move(&fill_area, -layer->buf_area.x1, -layer->buf_area.y1);
unsigned int target_texture = layer_get_texture(layer);
LV_ASSERT(target_texture != 0);
int32_t targ_tex_w = lv_area_get_width(&layer->buf_area);
int32_t targ_tex_h = lv_area_get_height(&layer->buf_area);
unsigned int framebuffer = get_framebuffer(u);
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer));
GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target_texture, 0));
if(target_texture) {
unsigned int framebuffer = get_framebuffer(u);
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer));
GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target_texture, 0));
}
lv_opengles_viewport(0, 0, targ_tex_w, targ_tex_h);
lv_opengles_render_fill(fill_dsc->color, &fill_area, fill_dsc->opa, targ_tex_w, targ_tex_h);
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
if(target_texture) {
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
}
return;
}
}
#endif /*!LV_USE_EGL*/
if(t->type == LV_DRAW_TASK_TYPE_LAYER) {
blend_texture_layer(t);
@@ -609,11 +615,8 @@ static unsigned int create_texture(int32_t w, int32_t h, const void * data)
{
LV_PROFILER_DRAW_BEGIN;
unsigned int texture;
GL_CALL(glGenTextures(1, &texture));
GL_CALL(glBindTexture(GL_TEXTURE_2D, texture));
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
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));
@@ -622,11 +625,11 @@ static unsigned int create_texture(int32_t w, int32_t h, const void * data)
* have full ARGB pixels since the alpha channel is required for blending.
*/
GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, data));
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 20);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
GL_CALL(glGenerateMipmap(GL_TEXTURE_2D));
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 20));
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST));
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
GL_CALL(glBindTexture(GL_TEXTURE_2D, 0));
LV_PROFILER_DRAW_END;
return texture;
@@ -640,15 +643,14 @@ static void lv_draw_opengles_3d(lv_draw_task_t * t, const lv_draw_3d_dsc_t * dsc
lv_layer_t * dest_layer = t->target_layer;
unsigned int target_texture = layer_get_texture(dest_layer);
LV_ASSERT(target_texture != 0);
int32_t targ_tex_w = lv_area_get_width(&dest_layer->buf_area);
int32_t targ_tex_h = lv_area_get_height(&dest_layer->buf_area);
GL_CALL(glBindTexture(GL_TEXTURE_2D, target_texture));
unsigned int framebuffer = get_framebuffer(u);
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer));
GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target_texture, 0));
if(target_texture) {
unsigned int framebuffer = get_framebuffer(u);
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer));
GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target_texture, 0));
}
lv_opengles_viewport(0, 0, targ_tex_w, targ_tex_h);
lv_area_t clip_area = t->clip_area;
@@ -657,8 +659,9 @@ static void lv_draw_opengles_3d(lv_draw_task_t * t, const lv_draw_3d_dsc_t * dsc
lv_opengles_render_texture(dsc->tex_id, coords, dsc->opa, targ_tex_w, targ_tex_h, &clip_area, dsc->h_flip,
!dsc->v_flip);
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
GL_CALL(glBindTexture(GL_TEXTURE_2D, 0));
if(target_texture) {
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
}
LV_PROFILER_DRAW_END;
}
#endif /*LV_USE_3DTEXTURE*/
File diff suppressed because it is too large Load Diff
-441
View File
@@ -1,441 +0,0 @@
/**
* @file lv_glfw_window.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_glfw_window_private.h"
#if LV_USE_OPENGLES
#include <stdlib.h>
#include "../../core/lv_refr.h"
#include "../../stdlib/lv_sprintf.h"
#include "../../stdlib/lv_string.h"
#include "../../core/lv_global.h"
#include "../../display/lv_display_private.h"
#include "../../indev/lv_indev.h"
#include "../../lv_init.h"
#include "../../misc/lv_area_private.h"
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "lv_opengles_driver.h"
#include "lv_opengles_texture.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void window_update_handler(lv_timer_t * t);
static uint32_t lv_glfw_tick_count_callback(void);
static lv_glfw_window_t * lv_glfw_get_lv_window_from_window(GLFWwindow * window);
static void glfw_error_cb(int error, const char * description);
static int lv_glfw_init(void);
static int lv_glew_init(void);
static void lv_glfw_timer_init(void);
static void lv_glfw_window_config(GLFWwindow * window, bool use_mouse_indev);
static void lv_glfw_window_quit(void);
static void window_close_callback(GLFWwindow * window);
static void key_callback(GLFWwindow * window, int key, int scancode, int action, int mods);
static void mouse_button_callback(GLFWwindow * window, int button, int action, int mods);
static void mouse_move_callback(GLFWwindow * window, double xpos, double ypos);
static void proc_mouse(lv_glfw_window_t * window);
static void indev_read_cb(lv_indev_t * indev, lv_indev_data_t * data);
static void framebuffer_size_callback(GLFWwindow * window, int width, int height);
/**********************
* STATIC VARIABLES
**********************/
static bool glfw_inited;
static bool glew_inited;
static lv_timer_t * update_handler_timer;
static lv_ll_t glfw_window_ll;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
lv_glfw_window_t * lv_glfw_window_create_ex(int32_t hor_res, int32_t ver_res, bool use_mouse_indev, bool h_flip,
bool v_flip, const char * title)
{
LV_ASSERT_NULL(title);
if(lv_glfw_init() != 0) {
LV_LOG_ERROR("Failed to init glfw");
return NULL;
}
lv_glfw_window_t * window = lv_ll_ins_tail(&glfw_window_ll);
LV_ASSERT_MALLOC(window);
if(window == NULL) {
LV_LOG_ERROR("Failed to create glfw window");
return NULL;
}
lv_memzero(window, sizeof(*window));
/* Create window with graphics context */
lv_glfw_window_t * existing_window = lv_ll_get_head(&glfw_window_ll);
window->window = glfwCreateWindow(hor_res, ver_res, title, NULL,
existing_window ? existing_window->window : NULL);
if(window->window == NULL) {
LV_LOG_ERROR("glfwCreateWindow fail");
lv_ll_remove(&glfw_window_ll, window);
lv_free(window);
return NULL;
}
glfwSetWindowTitle(window->window, title);
window->h_flip = h_flip;
window->v_flip = v_flip;
window->hor_res = hor_res;
window->ver_res = ver_res;
lv_ll_init(&window->textures, sizeof(lv_glfw_texture_t));
window->use_indev = use_mouse_indev;
glfwSetWindowUserPointer(window->window, window);
lv_glfw_timer_init();
lv_glfw_window_config(window->window, use_mouse_indev);
lv_glew_init();
glfwMakeContextCurrent(window->window);
lv_opengles_init();
return window;
}
lv_glfw_window_t * lv_glfw_window_create(int32_t hor_res, int32_t ver_res, bool use_mouse_indev)
{
return lv_glfw_window_create_ex(hor_res, ver_res, use_mouse_indev, false, false, "LVGL Simulator");
}
void lv_glfw_window_set_title(lv_glfw_window_t * window, const char * new_title)
{
glfwSetWindowTitle(window->window, new_title);
}
void lv_glfw_window_delete(lv_glfw_window_t * window)
{
glfwDestroyWindow(window->window);
if(window->use_indev) {
lv_glfw_texture_t * texture;
LV_LL_READ(&window->textures, texture) {
if(texture->indev != NULL) lv_indev_delete(texture->indev);
}
}
lv_ll_clear(&window->textures);
lv_ll_remove(&glfw_window_ll, window);
lv_free(window);
if(lv_ll_is_empty(&glfw_window_ll)) {
lv_glfw_window_quit();
}
}
void * lv_glfw_window_get_glfw_window(lv_glfw_window_t * window)
{
return (void *)(window->window);
}
void lv_glfw_window_set_flip(lv_glfw_window_t * window, bool h_flip, bool v_flip)
{
window->h_flip = h_flip;
window->v_flip = v_flip;
}
lv_glfw_texture_t * lv_glfw_window_add_texture(lv_glfw_window_t * window, unsigned int texture_id, int32_t w, int32_t h)
{
lv_glfw_texture_t * texture = lv_ll_ins_tail(&window->textures);
LV_ASSERT_MALLOC(texture);
if(texture == NULL) return NULL;
lv_memzero(texture, sizeof(*texture));
texture->window = window;
texture->texture_id = texture_id;
lv_area_set(&texture->area, 0, 0, w - 1, h - 1);
texture->opa = LV_OPA_COVER;
if(window->use_indev) {
lv_display_t * texture_disp = lv_opengles_texture_get_from_texture_id(texture_id);
if(texture_disp != NULL) {
lv_indev_t * indev = lv_indev_create();
if(indev == NULL) {
lv_ll_remove(&window->textures, texture);
lv_free(texture);
return NULL;
}
texture->indev = indev;
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
lv_indev_set_read_cb(indev, indev_read_cb);
lv_indev_set_driver_data(indev, texture);
lv_indev_set_mode(indev, LV_INDEV_MODE_EVENT);
lv_indev_set_display(indev, texture_disp);
}
}
return texture;
}
void lv_glfw_texture_remove(lv_glfw_texture_t * texture)
{
if(texture->indev != NULL) {
lv_indev_delete(texture->indev);
}
lv_ll_remove(&texture->window->textures, texture);
lv_free(texture);
}
void lv_glfw_texture_set_x(lv_glfw_texture_t * texture, int32_t x)
{
lv_area_set_pos(&texture->area, x, texture->area.y1);
}
void lv_glfw_texture_set_y(lv_glfw_texture_t * texture, int32_t y)
{
lv_area_set_pos(&texture->area, texture->area.x1, y);
}
void lv_glfw_texture_set_opa(lv_glfw_texture_t * texture, lv_opa_t opa)
{
texture->opa = opa;
}
lv_indev_t * lv_glfw_texture_get_mouse_indev(lv_glfw_texture_t * texture)
{
return texture->indev;
}
/**********************
* STATIC FUNCTIONS
**********************/
static int lv_glfw_init(void)
{
if(glfw_inited) {
return 0;
}
glfwSetErrorCallback(glfw_error_cb);
int ret = glfwInit();
if(ret == 0) {
LV_LOG_ERROR("glfwInit fail.");
return 1;
}
lv_ll_init(&glfw_window_ll, sizeof(lv_glfw_window_t));
glfw_inited = true;
return 0;
}
static int lv_glew_init(void)
{
if(glew_inited) {
return 0;
}
GLenum ret = glewInit();
if(ret != GLEW_OK) {
LV_LOG_ERROR("glewInit fail: %d.", ret);
return ret;
}
LV_LOG_INFO("GL version: %s", glGetString(GL_VERSION));
LV_LOG_INFO("GLSL version: %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
glew_inited = true;
return 0;
}
static void lv_glfw_timer_init(void)
{
if(update_handler_timer == NULL) {
update_handler_timer = lv_timer_create(window_update_handler, LV_DEF_REFR_PERIOD, NULL);
lv_tick_set_cb(lv_glfw_tick_count_callback);
}
}
static void lv_glfw_window_config(GLFWwindow * window, bool use_mouse_indev)
{
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
if(use_mouse_indev) {
glfwSetMouseButtonCallback(window, mouse_button_callback);
glfwSetCursorPosCallback(window, mouse_move_callback);
}
glfwSetKeyCallback(window, key_callback);
glfwSetWindowCloseCallback(window, window_close_callback);
}
static void lv_glfw_window_quit(void)
{
lv_timer_delete(update_handler_timer);
update_handler_timer = NULL;
glfwTerminate();
glfw_inited = false;
lv_deinit();
exit(0);
}
static void window_update_handler(lv_timer_t * t)
{
LV_UNUSED(t);
lv_glfw_window_t * window;
glfwPollEvents();
/* delete windows that are ready to close */
window = lv_ll_get_head(&glfw_window_ll);
while(window) {
lv_glfw_window_t * window_to_delete = window->closing ? window : NULL;
window = lv_ll_get_next(&glfw_window_ll, window);
if(window_to_delete) {
glfwSetWindowShouldClose(window_to_delete->window, GLFW_TRUE);
lv_glfw_window_delete(window_to_delete);
}
}
/* render each window */
LV_LL_READ(&glfw_window_ll, window) {
glfwMakeContextCurrent(window->window);
lv_opengles_viewport(0, 0, window->hor_res, window->ver_res);
lv_opengles_render_clear();
/* render each texture in the window */
lv_glfw_texture_t * texture;
LV_LL_READ(&window->textures, texture) {
/* if the added texture is an LVGL opengles texture display, refresh it before rendering it */
lv_display_t * texture_disp = lv_opengles_texture_get_from_texture_id(texture->texture_id);
if(texture_disp != NULL) {
lv_refr_now(texture_disp);
}
lv_area_t clip_area = texture->area;
#if LV_USE_DRAW_OPENGLES
lv_opengles_render_texture(texture->texture_id, &texture->area, texture->opa, window->hor_res, window->ver_res,
&clip_area, window->h_flip, texture_disp == NULL ? window->v_flip : !window->v_flip);
#else
lv_opengles_render_texture(texture->texture_id, &texture->area, texture->opa, window->hor_res, window->ver_res,
&clip_area, window->h_flip, window->v_flip);
#endif
}
/* Swap front and back buffers */
glfwSwapBuffers(window->window);
}
}
static void glfw_error_cb(int error, const char * description)
{
LV_LOG_ERROR("GLFW Error %d: %s", error, description);
}
static lv_glfw_window_t * lv_glfw_get_lv_window_from_window(GLFWwindow * window)
{
return glfwGetWindowUserPointer(window);
}
static void window_close_callback(GLFWwindow * window)
{
lv_glfw_window_t * lv_window = lv_glfw_get_lv_window_from_window(window);
lv_window->closing = 1;
}
static void key_callback(GLFWwindow * window, int key, int scancode, int action, int mods)
{
LV_UNUSED(scancode);
LV_UNUSED(mods);
if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
lv_glfw_window_t * lv_window = lv_glfw_get_lv_window_from_window(window);
lv_window->closing = 1;
}
}
static void mouse_button_callback(GLFWwindow * window, int button, int action, int mods)
{
LV_UNUSED(mods);
if(button == GLFW_MOUSE_BUTTON_LEFT) {
lv_glfw_window_t * lv_window = lv_glfw_get_lv_window_from_window(window);
lv_window->mouse_last_state = action == GLFW_PRESS ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
proc_mouse(lv_window);
}
}
static void mouse_move_callback(GLFWwindow * window, double xpos, double ypos)
{
lv_glfw_window_t * lv_window = lv_glfw_get_lv_window_from_window(window);
lv_window->mouse_last_point.x = (int32_t)xpos;
lv_window->mouse_last_point.y = (int32_t)ypos;
proc_mouse(lv_window);
}
static void proc_mouse(lv_glfw_window_t * window)
{
/* mouse activity will affect the topmost LVGL display texture */
lv_glfw_texture_t * texture;
LV_LL_READ_BACK(&window->textures, texture) {
if(lv_area_is_point_on(&texture->area, &window->mouse_last_point, 0)) {
/* adjust the mouse pointer coordinates so that they are relative to the texture */
if(window->h_flip) {
texture->indev_last_point.x = texture->area.x2 - window->mouse_last_point.x;
}
else {
texture->indev_last_point.x = window->mouse_last_point.x - texture->area.x1;
}
if(window->v_flip) {
texture->indev_last_point.y = (texture->area.y2 - window->mouse_last_point.y);
}
else {
texture->indev_last_point.y = (window->mouse_last_point.y - texture->area.y1);
}
texture->indev_last_state = window->mouse_last_state;
lv_indev_read(texture->indev);
break;
}
}
}
static void indev_read_cb(lv_indev_t * indev, lv_indev_data_t * data)
{
lv_glfw_texture_t * texture = lv_indev_get_driver_data(indev);
data->point = texture->indev_last_point;
data->state = texture->indev_last_state;
}
static void framebuffer_size_callback(GLFWwindow * window, int width, int height)
{
lv_glfw_window_t * lv_window = lv_glfw_get_lv_window_from_window(window);
lv_window->hor_res = width;
lv_window->ver_res = height;
}
static uint32_t lv_glfw_tick_count_callback(void)
{
double tick = glfwGetTime() * 1000.0;
return (uint32_t)tick;
}
#endif /*LV_USE_OPENGLES*/
-143
View File
@@ -1,143 +0,0 @@
/**
* @file lv_glfw_window.h
*
*/
#ifndef LV_GLFW_WINDOW_H
#define LV_GLFW_WINDOW_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../lv_conf_internal.h"
#if LV_USE_OPENGLES
#include "../../misc/lv_types.h"
#include "../../display/lv_display.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Create a GLFW window with no textures and initialize OpenGL
* @param hor_res width in pixels of the window
* @param ver_res height in pixels of the window
* @param use_mouse_indev send pointer indev input to LVGL display textures
* @return the new GLFW window handle
*/
lv_glfw_window_t * lv_glfw_window_create(int32_t hor_res, int32_t ver_res, bool use_mouse_indev);
/**
* Create a GLFW window with no textures and initialize OpenGL
* @param hor_res width in pixels of the window
* @param ver_res height in pixels of the window
* @param use_mouse_indev send pointer indev input to LVGL display textures
* @param h_flip Should the window contents be horizontally mirrored?
* @param v_flip Should the window contents be vertically mirrored?
* @param title The window title
* @return the new GLFW window handle
*/
lv_glfw_window_t * lv_glfw_window_create_ex(int32_t hor_res, int32_t ver_res, bool use_mouse_indev, bool h_flip,
bool v_flip, const char * title);
/**
* Set the window's title text
* @param window GLFW window to configure
* @param new_title The new title text
*/
void lv_glfw_window_set_title(lv_glfw_window_t * window, const char * new_title);
/**
* Delete a GLFW window. If it is the last one, the process will exit
* @param window GLFW window to delete
*/
void lv_glfw_window_delete(lv_glfw_window_t * window);
/**
* Set the horizontal / vertical flipping of a GLFW window
* @param window GLFW window to configure
* @param h_flip Should the window contents be horizontally mirrored?
* @param v_flip Should the window contents be vertically mirrored?
*/
void lv_glfw_window_set_flip(lv_glfw_window_t * window, bool h_flip, bool v_flip);
/**
* Get the GLFW window handle for an lv_glfw_window
* @param window GLFW window to return the handle of
* @return the GLFW window handle
*/
void * lv_glfw_window_get_glfw_window(lv_glfw_window_t * window);
/**
* Add a texture to the GLFW window. It can be an LVGL display texture, or any OpenGL texture
* @param window GLFW window
* @param texture_id OpenGL texture ID
* @param w width in pixels of the texture
* @param h height in pixels of the texture
* @return the new texture handle
*/
lv_glfw_texture_t * lv_glfw_window_add_texture(lv_glfw_window_t * window, unsigned int texture_id, int32_t w,
int32_t h);
/**
* Remove a texture from its GLFW window and delete it
* @param texture handle of a GLFW window texture
*/
void lv_glfw_texture_remove(lv_glfw_texture_t * texture);
/**
* Set the x position of a texture within its GLFW window
* @param texture handle of a GLFW window texture
* @param x new x position of the texture
*/
void lv_glfw_texture_set_x(lv_glfw_texture_t * texture, int32_t x);
/**
* Set the y position of a texture within its GLFW window
* @param texture handle of a GLFW window texture
* @param y new y position of the texture
*/
void lv_glfw_texture_set_y(lv_glfw_texture_t * texture, int32_t y);
/**
* Set the opacity of a texture in a GLFW window
* @param texture handle of a GLFW window texture
* @param opa new opacity of the texture
*/
void lv_glfw_texture_set_opa(lv_glfw_texture_t * texture, lv_opa_t opa);
/**
* Get the mouse indev associated with a texture in a GLFW window, if it exists
* @param texture handle of a GLFW window texture
* @return the indev or `NULL`
* @note there will only be an indev if the texture is based on an
* LVGL display texture and the window was created with
* `use_mouse_indev` as `true`
*/
lv_indev_t * lv_glfw_texture_get_mouse_indev(lv_glfw_texture_t * texture);
/**********************
* MACROS
**********************/
#endif /* LV_USE_OPENGLES */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LV_GLFW_WINDOW_H */
-72
View File
@@ -1,72 +0,0 @@
/**
* @file lv_glfw_window_private.h
*
*/
#ifndef LV_GLFW_WINDOW_PRIVATE_H
#define LV_GLFW_WINDOW_PRIVATE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "lv_glfw_window.h"
#if LV_USE_OPENGLES
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "../../misc/lv_area.h"
#include "../../display/lv_display.h"
#include "../../indev/lv_indev.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
struct _lv_glfw_window_t {
GLFWwindow * window;
int32_t hor_res;
int32_t ver_res;
bool h_flip;
bool v_flip;
lv_ll_t textures;
lv_point_t mouse_last_point;
lv_indev_state_t mouse_last_state;
uint8_t use_indev : 1;
uint8_t closing : 1;
};
struct _lv_glfw_texture_t {
lv_glfw_window_t * window;
unsigned int texture_id;
lv_area_t area;
lv_opa_t opa;
lv_indev_t * indev;
lv_point_t indev_last_point;
lv_indev_state_t indev_last_state;
};
/**********************
* GLOBAL PROTOTYPES
**********************/
/**********************
* MACROS
**********************/
#endif /*LV_USE_OPENGLES*/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_GLFW_WINDOW_PRIVATE_H*/
+5 -3
View File
@@ -51,9 +51,11 @@ extern "C" {
#include "windows/lv_windows_input.h"
#include "windows/lv_windows_display.h"
#include "glfw/lv_glfw_window.h"
#include "glfw/lv_opengles_texture.h"
#include "glfw/lv_opengles_driver.h"
#include "opengles/lv_opengles_window.h"
#include "opengles/lv_opengles_texture.h"
#include "opengles/lv_opengles_driver.h"
#include "opengles/lv_opengles_glfw.h"
#include "opengles/lv_opengles_egl.h"
#include "qnx/lv_qnx.h"
@@ -10,6 +10,8 @@
#include "lv_opengles_debug.h"
#if LV_USE_OPENGLES
#include "lv_opengles_private.h"
#include "../../misc/lv_log.h"
/*********************
@@ -36,6 +38,7 @@
* GLOBAL FUNCTIONS
**********************/
#if LV_USE_OPENGLES_DEBUG
void GLClearError()
{
while(glGetError() != GL_NO_ERROR);
@@ -48,6 +51,7 @@ void GLLogCall(const char * function, const char * file, int line)
LV_LOG_ERROR("[OpenGL Error] (%d) %s %s:%d", error, function, file, line);
}
}
#endif
/**********************
* STATIC FUNCTIONS
@@ -10,17 +10,37 @@
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../lv_conf_internal.h"
#if LV_USE_OPENGLES
#include <stdbool.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
#if LV_USE_OPENGLES_DEBUG
void GLClearError(void);
void GLLogCall(const char * function, const char * file, int line);
#endif
/**********************
* MACROS
**********************/
#if LV_USE_OPENGLES_DEBUG
#define GL_CALL(x) do {\
GLClearError();\
@@ -6,15 +6,17 @@
/*********************
* INCLUDES
*********************/
#include "../../display/lv_display.h"
#include "../../misc/lv_area_private.h"
#include "lv_opengles_driver.h"
#if LV_USE_OPENGLES
#include "../../misc/lv_types.h"
#include "../../misc/lv_profiler.h"
#include "lv_opengles_debug.h"
#include "lv_opengles_driver.h"
#include "lv_opengles_private.h"
#include "../../display/lv_display.h"
#include "../../misc/lv_area_private.h"
/*********************
* DEFINES
@@ -85,6 +87,8 @@ static int shader_location[] = { 0, 0, 0, 0, 0, 0 };
static const char * vertex_shader =
"#version 300 es\n"
"\n"
"precision mediump float;\n"
"\n"
"in vec4 position;\n"
"in vec2 texCoord;\n"
"\n"
@@ -96,19 +100,19 @@ static const char * vertex_shader =
"{\n"
" gl_Position = vec4((u_VertexTransform * vec3(position.xy, 1)).xy, position.zw);\n"
" v_TexCoord = texCoord;\n"
"};\n";
"}\n";
static const char * fragment_shader =
"#version 300 es\n"
"\n"
"precision lowp float;\n"
"\n"
"layout(location = 0) out vec4 color;\n"
"out vec4 color;\n"
"\n"
"in vec2 v_TexCoord;\n"
"\n"
"uniform sampler2D u_Texture;\n"
"uniform int u_ColorDepth;\n"
"uniform float u_ColorDepth;\n"
"uniform float u_Opa;\n"
"uniform bool u_IsFill;\n"
"uniform vec3 u_FillColor;\n"
@@ -117,18 +121,18 @@ static const char * fragment_shader =
"{\n"
" vec4 texColor;\n"
" if (u_IsFill) {\n"
" texColor = vec4(u_FillColor, 1.0f);\n"
" texColor = vec4(u_FillColor, 1.0);\n"
" } else {\n"
" texColor = texture(u_Texture, v_TexCoord);\n"
" }\n"
" if (u_ColorDepth == 8) {\n"
" if (abs(u_ColorDepth - 8.0) < 0.1) {\n"
" float gray = texColor.r;\n"
" color = vec4(gray, gray, gray, u_Opa);\n"
" } else {\n"
" float combinedAlpha = texColor.a * u_Opa;\n"
" color = vec4(texColor.rgb * combinedAlpha, combinedAlpha);\n"
" }\n"
"};\n";
"}\n";
/**********************
* MACROS
@@ -206,7 +210,7 @@ void lv_opengles_render_clear(void)
void lv_opengles_viewport(int32_t x, int32_t y, int32_t w, int32_t h)
{
LV_PROFILER_DRAW_BEGIN;
glViewport(x, y, w, h);
GL_CALL(glViewport(x, y, w, h));
LV_PROFILER_DRAW_END;
}
@@ -235,7 +239,7 @@ static void lv_opengles_render_internal(unsigned int texture, const lv_area_t *
float hor_translate = (float)intersection.x1 / (float)disp_w * 2.0f - (1.0f - hor_scale);
float ver_translate = -((float)intersection.y1 / (float)disp_h * 2.0f - (1.0f - ver_scale));
hor_scale = h_flip ? -hor_scale : hor_scale;
ver_scale = v_flip ? -ver_scale : ver_scale;
ver_scale = v_flip ? ver_scale : -ver_scale;
float matrix[9] = {
hor_scale, 0.0f, hor_translate,
0.0f, ver_scale, ver_translate,
@@ -243,18 +247,14 @@ static void lv_opengles_render_internal(unsigned int texture, const lv_area_t *
};
if(texture != 0) {
float x_coef = 1.0f / (float)(2 * lv_area_get_width(texture_area));
float y_coef = 1.0f / (float)(2 * lv_area_get_height(texture_area));
float ix_co = 1.0f - x_coef;
float iy_co = 1.0f - y_coef;
float clip_x1 = h_flip ? lv_opengles_map_float(texture_clip_area->x2, texture_area->x2, texture_area->x1, x_coef, ix_co)
: lv_opengles_map_float(texture_clip_area->x1, texture_area->x1, texture_area->x2, x_coef, ix_co);
float clip_x2 = h_flip ? lv_opengles_map_float(texture_clip_area->x1, texture_area->x2, texture_area->x1, x_coef, ix_co)
: lv_opengles_map_float(texture_clip_area->x2, texture_area->x1, texture_area->x2, x_coef, ix_co);
float clip_y1 = v_flip ? lv_opengles_map_float(texture_clip_area->y1, texture_area->y1, texture_area->y2, y_coef, iy_co)
: lv_opengles_map_float(texture_clip_area->y2, texture_area->y2, texture_area->y1, y_coef, iy_co);
float clip_y2 = v_flip ? lv_opengles_map_float(texture_clip_area->y2, texture_area->y1, texture_area->y2, y_coef, iy_co)
: lv_opengles_map_float(texture_clip_area->y1, texture_area->y2, texture_area->y1, y_coef, iy_co);
float clip_x1 = h_flip ? lv_opengles_map_float(texture_clip_area->x2, texture_area->x2, texture_area->x1, 0.f, 1.f)
: lv_opengles_map_float(texture_clip_area->x1, texture_area->x1, texture_area->x2, 0.f, 1.f);
float clip_x2 = h_flip ? lv_opengles_map_float(texture_clip_area->x1, texture_area->x2, texture_area->x1, 0.f, 1.f)
: lv_opengles_map_float(texture_clip_area->x2, texture_area->x1, texture_area->x2, 0.f, 1.f);
float clip_y1 = v_flip ? lv_opengles_map_float(texture_clip_area->y2, texture_area->y2, texture_area->y1, 0.f, 1.f)
: lv_opengles_map_float(texture_clip_area->y1, texture_area->y1, texture_area->y2, 0.f, 1.f);
float clip_y2 = v_flip ? lv_opengles_map_float(texture_clip_area->y1, texture_area->y2, texture_area->y1, 0.f, 1.f)
: lv_opengles_map_float(texture_clip_area->y2, texture_area->y1, texture_area->y2, 0.f, 1.f);
float positions[LV_OPENGLES_VERTEX_BUFFER_LEN] = {
-1.f, 1.0f, clip_x1, clip_y2,
@@ -266,7 +266,7 @@ static void lv_opengles_render_internal(unsigned int texture, const lv_area_t *
}
lv_opengles_shader_bind();
lv_opengles_shader_set_uniform1i("u_ColorDepth", LV_COLOR_DEPTH);
lv_opengles_shader_set_uniform1f("u_ColorDepth", LV_COLOR_DEPTH);
lv_opengles_shader_set_uniform1i("u_Texture", 0);
lv_opengles_shader_set_uniformmatrix3fv("u_VertexTransform", 1, true, matrix);
lv_opengles_shader_set_uniform1f("u_Opa", (float)opa / (float)LV_OPA_100);
@@ -279,8 +279,8 @@ static void lv_opengles_render_internal(unsigned int texture, const lv_area_t *
static void lv_opengles_enable_blending(void)
{
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
GL_CALL(glEnable(GL_BLEND));
GL_CALL(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
}
static void lv_opengles_vertex_buffer_init(const void * data, unsigned int size)
@@ -34,13 +34,13 @@ extern "C" {
/**
* Initialize OpenGL
* @note it is not necessary to call this if you use `lv_glfw_window_create`
* @note it is not necessary to call this if you use `lv_opengles_glfw_window_create`
*/
void lv_opengles_init(void);
/**
* Deinitialize OpenGL
* @note it is not necessary to call this if you use `lv_glfw_window_create`
* @note it is not necessary to call this if you use `lv_opengles_glfw_window_create`
*/
void lv_opengles_deinit(void);
File diff suppressed because it is too large Load Diff
+70
View File
@@ -0,0 +1,70 @@
/**
* @file lv_opengles_egl.h
*
*/
#ifndef LV_OPENGLES_EGL_H
#define LV_OPENGLES_EGL_H
#ifdef __cplusplus
extern "C" {
#endif
#include "../../lv_conf_internal.h"
#if LV_USE_EGL
#include "../../misc/lv_types.h"
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef void (*lv_opengles_egl_window_cb_t)(lv_opengles_window_t * window);
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Create an EGL OpenGL window with no textures. OpenGL should be initialized beforehand.
* @param hor_res width in pixels of the window
* @param ver_res height in pixels of the window
* @param native_window_handle a handle to a native window for the platform
* @param device a `EGLNativeDisplayType`
* @param pre called before rendering
* @param post1 called after rendering, before swapping
* @param post2 called after swapping
* @return the new EGL OpenGL window handle
*/
lv_opengles_window_t * lv_opengles_egl_window_create(int32_t hor_res, int32_t ver_res, void * native_window_handle,
void * device,
lv_opengles_egl_window_cb_t pre,
lv_opengles_egl_window_cb_t post1,
lv_opengles_egl_window_cb_t post2);
void * lv_opengles_egl_window_get_surface(lv_opengles_window_t * window);
void * lv_opengles_egl_window_get_display(lv_opengles_window_t * window);
void lv_opengles_egl_window_set_user_data(lv_opengles_window_t * window, void * user_data);
void * lv_opengles_egl_window_get_user_data(lv_opengles_window_t * window);
/**********************
* MACROS
**********************/
#endif /*LV_USE_EGL*/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_OPENGLES_EGL_H*/
File diff suppressed because it is too large Load Diff
+88
View File
@@ -0,0 +1,88 @@
/**
* @file lv_opengles_glfw.h
*
*/
#ifndef LV_OPENGLES_GLFW_H
#define LV_OPENGLES_GLFW_H
#ifdef __cplusplus
extern "C" {
#endif
#include "../../lv_conf_internal.h"
#if LV_USE_GLFW
#include "../../misc/lv_types.h"
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Create a GLFW OpenGL window with no textures and initialize OpenGL
* @param hor_res width in pixels of the window
* @param ver_res height in pixels of the window
* @param use_mouse_indev send pointer indev input to LVGL display textures
* @return the new GLFW OpenGL window handle
*/
lv_opengles_window_t * lv_opengles_glfw_window_create(int32_t hor_res, int32_t ver_res, bool use_mouse_indev);
/**
* Create a GLFW window with no textures and initialize OpenGL
* @param hor_res width in pixels of the window
* @param ver_res height in pixels of the window
* @param use_mouse_indev send pointer indev input to LVGL display textures
* @param h_flip Should the window contents be horizontally mirrored?
* @param v_flip Should the window contents be vertically mirrored?
* @param title The window title
* @return the new GLFW window handle
*/
lv_opengles_window_t * lv_opengles_glfw_window_create_ex(int32_t hor_res, int32_t ver_res, bool use_mouse_indev,
bool h_flip, bool v_flip, const char * title);
/**
* Set the window's title text
* @param window GLFW window to configure
* @param new_title The new title text
*/
void lv_opengles_glfw_window_set_title(lv_opengles_window_t * window, const char * new_title);
/**
* Set the horizontal / vertical flipping of a GLFW window
* @param window GLFW window to configure
* @param h_flip Should the window contents be horizontally mirrored?
* @param v_flip Should the window contents be vertically mirrored?
*/
void lv_opengles_glfw_window_set_flip(lv_opengles_window_t * window, bool h_flip, bool v_flip);
/**
* Get the GLFW window handle for a GLFW lv_opengles_window_t
* @param window GLFW window to return the handle of
* @return the GLFW window handle
*/
void * lv_opengles_glfw_window_get_glfw_window(lv_opengles_window_t * window);
/**********************
* MACROS
**********************/
#endif /*LV_USE_GLFW*/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_OPENGLES_GLFW_H*/
@@ -0,0 +1,64 @@
/**
* @file lv_opengles_private.h
*
*/
#ifndef LV_OPENGLES_PRIVATE_H
#define LV_OPENGLES_PRIVATE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../lv_conf_internal.h"
#if LV_USE_OPENGLES
#if LV_USE_EGL
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <EGL/egl.h>
#include <GLES3/gl3.h>
#else
/* For now, by default we add glew and glfw.
In the future we need to consider adding a config for setting these includes*/
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#endif /*LV_USE_EGL*/
/*********************
* DEFINES
*********************/
/* In desktop GL (<Gl/gl.h>) these symbols are defined but for EGL
* they are defined as extensions with the _EXT suffix */
#ifndef GL_BGRA
#define GL_BGRA GL_BGRA_EXT
#endif /*GL_BGRA*/
#ifndef GL_BGR
#define GL_BGR GL_BGR_EXT
#endif /*GL_BGR*/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**********************
* MACROS
**********************/
#endif /*LV_USE_OPENGLES*/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_OPENGLES_PRIVATE_H*/
@@ -11,10 +11,11 @@
#if LV_USE_OPENGLES
#include "lv_opengles_debug.h"
#include "lv_opengles_private.h"
#include "../../display/lv_display_private.h"
#include <stdlib.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
/*********************
* DEFINES
@@ -60,14 +61,22 @@ lv_display_t * lv_opengles_texture_create(int32_t w, int32_t h)
lv_display_delete(disp);
return NULL;
}
#if LV_USE_DRAW_OPENGLES
static size_t LV_ATTRIBUTE_MEM_ALIGN dummy_buf;
lv_display_set_buffers(disp, &dummy_buf, NULL, w * h * 4, LV_DISPLAY_RENDER_MODE_DIRECT);
#else
uint32_t stride = lv_draw_buf_width_to_stride(w, lv_display_get_color_format(disp));
uint32_t buf_size = stride * h;
dsc->fb1 = malloc(buf_size);
LV_ASSERT_MALLOC(dsc->fb1);
if(dsc->fb1 == NULL) {
lv_free(dsc);
lv_display_delete(disp);
return NULL;
}
lv_display_set_buffers(disp, dsc->fb1, NULL, buf_size, LV_DISPLAY_RENDER_MODE_DIRECT);
#endif
GL_CALL(glGenTextures(1, &dsc->texture_id));
GL_CALL(glBindTexture(GL_TEXTURE_2D, dsc->texture_id));
@@ -92,16 +101,19 @@ lv_display_t * lv_opengles_texture_create(int32_t w, int32_t h)
#error("Unsupported color format")
#endif
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 20);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
GL_CALL(glGenerateMipmap(GL_TEXTURE_2D));
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 20));
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST));
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
lv_display_set_buffers(disp, dsc->fb1, NULL, buf_size, LV_DISPLAY_RENDER_MODE_DIRECT);
lv_display_set_flush_cb(disp, flush_cb);
lv_display_set_driver_data(disp, dsc);
lv_display_add_event_cb(disp, release_disp_cb, LV_EVENT_DELETE, disp);
#if LV_USE_DRAW_OPENGLES
lv_display_delete_refr_timer(disp);
#endif
return disp;
}
+102
View File
@@ -0,0 +1,102 @@
/**
* @file lv_opengles_window.h
*
*/
#ifndef LV_OPENGLES_WINDOW_H
#define LV_OPENGLES_WINDOW_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../lv_conf_internal.h"
#if LV_USE_OPENGLES
#include "../../misc/lv_types.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Delete an OpenGL window. If it is the last one, the process will exit
* @param window OpenGL window to delete
*/
void lv_opengles_window_delete(lv_opengles_window_t * window);
/**
* Add a texture to the OpenGL window. It can be an LVGL display texture, or any OpenGL texture
* @param window OpenGL window
* @param texture_id OpenGL texture ID
* @param w width in pixels of the texture
* @param h height in pixels of the texture
* @return the new texture handle
*/
lv_opengles_window_texture_t * lv_opengles_window_add_texture(lv_opengles_window_t * window, unsigned int texture_id,
int32_t w, int32_t h);
lv_display_t * lv_opengles_window_display_create(lv_opengles_window_t * window, int32_t w, int32_t h);
lv_opengles_window_texture_t * lv_opengles_window_display_get_window_texture(lv_display_t * window_display);
/**
* Remove a texture from its OpenGL window and delete it
* @param texture handle of an OpenGL window texture
*/
void lv_opengles_window_texture_remove(lv_opengles_window_texture_t * texture);
/**
* Set the x position of a texture within its OpenGL window
* @param texture handle of an OpenGL window texture
* @param x new x position of the texture
*/
void lv_opengles_window_texture_set_x(lv_opengles_window_texture_t * texture, int32_t x);
/**
* Set the y position of a texture within its OpenGL window
* @param texture handle of an OpenGL window texture
* @param y new y position of the texture
*/
void lv_opengles_window_texture_set_y(lv_opengles_window_texture_t * texture, int32_t y);
/**
* Set the opacity of a texture in an OpenGL window
* @param texture handle of an OpenGL window texture
* @param opa new opacity of the texture
*/
void lv_opengles_window_texture_set_opa(lv_opengles_window_texture_t * texture, lv_opa_t opa);
/**
* Get the mouse indev associated with a texture in an OpenGL window, if it exists
* @param texture handle of an OpenGL window texture
* @return the indev or `NULL`
* @note there will only be an indev if the texture is based on an
* LVGL display texture and the window was created with
* `use_mouse_indev` as `true`
*/
lv_indev_t * lv_opengles_window_texture_get_mouse_indev(lv_opengles_window_texture_t * texture);
/**********************
* MACROS
**********************/
#endif /* LV_USE_OPENGLES */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LV_OPENGLES_WINDOW_H */
@@ -14,7 +14,8 @@
#include "../../../../misc/lv_math.h"
#include "../../../../misc/lv_log.h"
#include "../../../../stdlib/lv_string.h"
#include "../../../../drivers/glfw/lv_opengles_debug.h"
#include "../../../../drivers/opengles/lv_opengles_private.h"
#include "../../../../drivers/opengles/lv_opengles_debug.h"
#include "../../opengl_shader/lv_opengl_shader_internal.h"
#include "../lv_gltf_view_internal.h"
@@ -18,7 +18,8 @@
#include "../fastgltf/lv_fastgltf.hpp"
#include "../../../misc/lv_types.h"
#include "../../../stdlib/lv_sprintf.h"
#include "../../../drivers/glfw/lv_opengles_debug.h"
#include "../../../drivers/opengles/lv_opengles_private.h"
#include "../../../drivers/opengles/lv_opengles_debug.h"
#include "../math/lv_gltf_math.hpp"
#include <algorithm>
@@ -9,7 +9,8 @@
#include "../../../lv_conf_internal.h"
#if LV_USE_GLTF
#include "../../../drivers/glfw/lv_opengles_debug.h"
#include "../../../drivers/opengles/lv_opengles_private.h"
#include "../../../drivers/opengles/lv_opengles_debug.h"
#include "../../../misc/lv_types.h"
#include "../../../misc/lv_rb_private.h"
@@ -17,7 +17,8 @@
#include "../../../misc/lv_types.h"
#include "../../../stdlib/lv_mem.h"
#include "../../../stdlib/lv_sprintf.h"
#include "../../../drivers/glfw/lv_opengles_debug.h"
#include "../../../drivers/opengles/lv_opengles_private.h"
#include "../../../drivers/opengles/lv_opengles_debug.h"
#include "../../../stdlib/lv_string.h"
#include <GL/glew.h>
@@ -11,7 +11,8 @@
#if LV_USE_GLTF
#include "../../../drivers/glfw/lv_opengles_debug.h"
#include "../../../drivers/opengles/lv_opengles_private.h"
#include "../../../drivers/opengles/lv_opengles_debug.h"
#include "../../../misc/lv_assert.h"
#include "../../../stdlib/lv_mem.h"
/*********************
+15
View File
@@ -38,6 +38,21 @@ extern "C" {
#define lv_draw_buf_cache_operation_cb lv_draw_buf_cache_operation_cb_t
#define lv_draw_buf_width_to_stride_cb lv_draw_buf_width_to_stride_cb_t
#define lv_glfw_window_t lv_opengles_window_t
#define lv_glfw_texture_t lv_opengles_window_texture_t
#define lv_glfw_window_create lv_opengles_glfw_window_create
#define lv_glfw_window_create_ex lv_opengles_glfw_window_create_ex
#define lv_glfw_window_set_title lv_opengles_glfw_window_set_title
#define lv_glfw_window_delete lv_opengles_window_delete
#define lv_glfw_window_set_flip lv_opengles_glfw_window_set_flip
#define lv_glfw_window_add_texture lv_opengles_window_add_texture
#define lv_glfw_texture_remove lv_opengles_window_texture_remove
#define lv_glfw_texture_set_x lv_opengles_window_texture_set_x
#define lv_glfw_texture_set_y lv_opengles_window_texture_set_y
#define lv_glfw_texture_set_opa lv_opengles_window_texture_set_opa
#define lv_glfw_texture_get_mouse_indev lv_opengles_window_texture_get_mouse_indev
#define lv_glfw_window_get_glfw_window lv_opengles_glfw_window_get_glfw_window
#ifdef __cplusplus
} /*extern "C"*/
+38 -2
View File
@@ -1009,7 +1009,7 @@
#endif
#endif
/** Draw using cached OpenGLES textures */
/** Draw using cached OpenGLES textures. Requires LV_USE_OPENGLES */
#ifndef LV_USE_DRAW_OPENGLES
#ifdef CONFIG_LV_USE_DRAW_OPENGLES
#define LV_USE_DRAW_OPENGLES CONFIG_LV_USE_DRAW_OPENGLES
@@ -1018,6 +1018,16 @@
#endif
#endif
#if LV_USE_DRAW_OPENGLES
#ifndef LV_DRAW_OPENGLES_TEXTURE_CACHE_COUNT
#ifdef CONFIG_LV_DRAW_OPENGLES_TEXTURE_CACHE_COUNT
#define LV_DRAW_OPENGLES_TEXTURE_CACHE_COUNT CONFIG_LV_DRAW_OPENGLES_TEXTURE_CACHE_COUNT
#else
#define LV_DRAW_OPENGLES_TEXTURE_CACHE_COUNT 64
#endif
#endif
#endif
/** Draw using espressif PPA accelerator */
#ifndef LV_USE_PPA
#ifdef CONFIG_LV_USE_PPA
@@ -4208,6 +4218,14 @@
#define LV_USE_LINUX_DRM_GBM_BUFFERS 0
#endif
#endif
#ifndef LV_LINUX_DRM_USE_EGL
#ifdef CONFIG_LV_LINUX_DRM_USE_EGL
#define LV_LINUX_DRM_USE_EGL CONFIG_LV_LINUX_DRM_USE_EGL
#else
#define LV_LINUX_DRM_USE_EGL 0
#endif
#endif
#endif
/** Interface for TFT_eSPI */
@@ -4416,7 +4434,7 @@
#endif
#endif
/** Use OpenGL to open window on PC and handle mouse and keyboard */
/** Use a generic OpenGL driver that can be used to embed in other applications or used with GLFW/EGL */
#ifndef LV_USE_OPENGLES
#ifdef CONFIG_LV_USE_OPENGLES
#define LV_USE_OPENGLES CONFIG_LV_USE_OPENGLES
@@ -4438,6 +4456,16 @@
#endif
#endif
/** Use GLFW to open window on PC and handle mouse and keyboard. Requires*/
#ifndef LV_USE_GLFW
#ifdef CONFIG_LV_USE_GLFW
#define LV_USE_GLFW CONFIG_LV_USE_GLFW
#else
#define LV_USE_GLFW 0
#endif
#endif
/** QNX Screen display and input drivers */
#ifndef LV_USE_QNX
#ifdef CONFIG_LV_USE_QNX
@@ -4729,6 +4757,10 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN);
#define LV_WAYLAND_WL_SHELL 0
#endif /* LV_USE_WAYLAND */
#if LV_USE_LINUX_DRM == 0
#define LV_LINUX_DRM_USE_EGL 0
#endif /*LV_USE_LINUX_DRM*/
#if LV_USE_SYSMON == 0
#define LV_USE_PERF_MONITOR 0
#define LV_USE_MEM_MONITOR 0
@@ -4771,6 +4803,10 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN);
#endif
#endif
#ifndef LV_USE_EGL
#define LV_USE_EGL LV_LINUX_DRM_USE_EGL
#endif /* LV_USE_EGL */
#if LV_USE_OS
#if (LV_USE_FREETYPE || LV_USE_THORVG) && LV_DRAW_THREAD_STACK_SIZE < (32 * 1024)
#warning "Increase LV_DRAW_THREAD_STACK_SIZE to at least 32KB for FreeType or ThorVG."
+2 -2
View File
@@ -350,8 +350,8 @@ typedef struct _lv_rlottie_t lv_rlottie_t;
typedef struct _lv_ffmpeg_player_t lv_ffmpeg_player_t;
typedef struct _lv_glfw_window_t lv_glfw_window_t;
typedef struct _lv_glfw_texture_t lv_glfw_texture_t;
typedef struct _lv_opengles_window_t lv_opengles_window_t;
typedef struct _lv_opengles_window_texture_t lv_opengles_window_texture_t;
typedef uint32_t lv_prop_id_t;
+1 -1
View File
@@ -1183,7 +1183,7 @@
* shared across sub-systems and libraries using the Linux DMA-BUF API.
* The GBM library aims to provide a platform independent memory management system
* it supports the major GPU vendors - This option requires linking with libgbm */
#define LV_LINUX_DRM_GBM_BUFFERS 0
#define LV_USE_LINUX_DRM_GBM_BUFFERS 0
#endif
/** Interface for TFT_eSPI */