mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-10 04:37:55 +08:00
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:
@@ -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.
|
||||
|
||||
|
||||
@@ -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>");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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
@@ -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*/
|
||||
@@ -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 */
|
||||
@@ -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*/
|
||||
@@ -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
@@ -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
@@ -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*/
|
||||
+19
-7
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
/*********************
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user