| 1 | // Copyright © SixtyFPS GmbH <info@slint.dev> |
| 2 | // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 |
| 3 | |
| 4 | #pragma once |
| 5 | |
| 6 | #include "slint-platform.h" |
| 7 | #include "esp_lcd_touch.h" |
| 8 | #include "esp_lcd_types.h" |
| 9 | |
| 10 | /** |
| 11 | * This data structure configures the Slint platform for use with ESP-IDF, in particular |
| 12 | * the esp_lcd component ( |
| 13 | * https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/lcd.html ) |
| 14 | * for touch input and on-screen rendering. |
| 15 | * |
| 16 | * Slint supports three different ways of rendering: |
| 17 | * |
| 18 | * * Single-buffering: Allocate one frame-buffer at a location of your choosing in RAM, and |
| 19 | * set the `buffer1` field. |
| 20 | * * Double-buffering: Call `esp_lcd_rgb_panel_get_frame_buffer` to obtain two frame buffers |
| 21 | * allocated by the `esp_lcd` driver and set `buffer1` and `buffer2`. |
| 22 | * * Line-by-line rendering: Set neither `buffer1` nor `buffer2` to instruct Slint to allocate |
| 23 | * a buffer (with MALLOC_CAP_INTERNAL) big enough to hold one line, |
| 24 | * render into it, and send it to the display. |
| 25 | * |
| 26 | * Use single-buffering if you can allocate a buffer in a memory region that allows the esp_lcd |
| 27 | * driver to efficiently transfer to the display. Use double-buffering if your driver supports |
| 28 | * calling `esp_lcd_rgb_panel_get_frame_buffer` and the buffers can be accessed directly by the |
| 29 | * display controller. Use line-by-line rendering if you don't have sufficient memory or rendering |
| 30 | * to internal memory (MALLOC_CAP_INTERNAL) and flushing to the display is faster than rendering |
| 31 | * into memory buffers that may be slower to access for the CPU. |
| 32 | * |
| 33 | * The data structure is a template where the pixel type is configurable. |
| 34 | * The default depends on the sdkconfig, but you can use either `slint::Rgb8Pixel` or |
| 35 | * `slint::platform::Rgb565Pixel`, depending on how the display is configured. |
| 36 | */ |
| 37 | template<typename PixelType = |
| 38 | #if CONFIG_BSP_LCD_COLOR_FORMAT_RGB888 |
| 39 | slint::Rgb8Pixel |
| 40 | #else |
| 41 | slint::platform::Rgb565Pixel |
| 42 | #endif |
| 43 | > |
| 44 | |
| 45 | struct SlintPlatformConfiguration |
| 46 | { |
| 47 | /// The size of the screen in pixels. |
| 48 | slint::PhysicalSize size; |
| 49 | /// The handle to the display as previously initialized by `bsp_display_new` or |
| 50 | /// `esp_lcd_panel_init`. Must be set to a valid, non-null esp_lcd_panel_handle_t. |
| 51 | esp_lcd_panel_handle_t panel_handle = nullptr; |
| 52 | /// The touch screen handle, if the device is equipped with a touch screen. Set to nullptr |
| 53 | /// otherwise; |
| 54 | esp_lcd_touch_handle_t touch_handle = nullptr; |
| 55 | /// The buffer Slint will render into. It must have have the size of at least one frame. Slint |
| 56 | /// calls esp_lcd_panel_draw_bitmap to flush the buffer to the screen. |
| 57 | std::optional<std::span<PixelType>> buffer1 = {}; |
| 58 | /// If specified, this is a second buffer that will be used for double-buffering. Use this if |
| 59 | /// your LCD panel supports double buffering: Call `esp_lcd_rgb_panel_get_frame_buffer` to |
| 60 | /// obtain two buffers and set `buffer` and `buffer2` in this data structure. |
| 61 | std::optional<std::span<PixelType>> buffer2 = {}; |
| 62 | slint::platform::SoftwareRenderer::RenderingRotation rotation = |
| 63 | slint::platform::SoftwareRenderer::RenderingRotation::NoRotation; |
| 64 | /// Swap the 2 bytes of RGB 565 pixels before sending to the display, or turn 24-bit RGB into |
| 65 | /// BGR. Use this if your CPU is little endian but the display expects big-endian. |
| 66 | union { |
| 67 | [[deprecated("Renamed to byte_swap" )]] bool color_swap_16; |
| 68 | bool byte_swap = false; |
| 69 | }; |
| 70 | }; |
| 71 | |
| 72 | template<typename... Args> |
| 73 | SlintPlatformConfiguration(Args...) -> SlintPlatformConfiguration<>; |
| 74 | |
| 75 | /** |
| 76 | * Initialize the Slint platform for ESP-IDF |
| 77 | * |
| 78 | * This must be called before any other call to the Slint library. |
| 79 | * |
| 80 | * - `size` is the size of the screen |
| 81 | * - `panel` is a handle to the display. |
| 82 | * - `touch` is a handle to the touch screen, if the device has a touch screen |
| 83 | * - `buffer1`, is a buffer of at least the size of the frame in which the slint scene |
| 84 | * will be drawn. Slint will take care to flush it to the screen |
| 85 | * - `buffer2`, if specified, is a second buffer to be used with double buffering, |
| 86 | * both buffer1 and buffer2 should then be obtained with `esp_lcd_rgb_panel_get_frame_buffer` |
| 87 | * |
| 88 | * Note: For compatibility, this function overload selects RGB16 byte swapping if single-buffering |
| 89 | * is selected as rendering method. |
| 90 | * |
| 91 | * \deprecated Prefer the overload taking a SlintPlatformConfiguration |
| 92 | */ |
| 93 | [[deprecated("Use the overload taking a SlintPlatformConfiguration" )]] |
| 94 | void slint_esp_init(slint::PhysicalSize size, esp_lcd_panel_handle_t panel, |
| 95 | std::optional<esp_lcd_touch_handle_t> touch, |
| 96 | std::span<slint::platform::Rgb565Pixel> buffer1, |
| 97 | std::optional<std::span<slint::platform::Rgb565Pixel>> buffer2 = {}); |
| 98 | |
| 99 | /** |
| 100 | * Initialize the Slint platform for ESP-IDF. |
| 101 | * |
| 102 | * This must be called before any other call to the Slint library. |
| 103 | */ |
| 104 | void slint_esp_init(const SlintPlatformConfiguration<slint::platform::Rgb565Pixel> &config); |
| 105 | void slint_esp_init(const SlintPlatformConfiguration<slint::Rgb8Pixel> &config); |
| 106 | |