-
Notifications
You must be signed in to change notification settings - Fork 43
blog: add lvgl plus PPA. #597
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
uLipe
wants to merge
1
commit into
espressif:main
Choose a base branch
from
uLipe:feature/ppa_lvgl
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| --- | ||
| title: "Felipe Neves" | ||
| --- |
245 changes: 245 additions & 0 deletions
245
content/blog/2025/11/lvgl-plus-pixel-processing-accelerator/index.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,245 @@ | ||
| --- | ||
| title: "Using the Espressif Pixel Processing Accelerator with LVGL 9.4" | ||
| date: "2025-11-23" | ||
| summary: "The Espressif Pixel Processing Accelerator integration in LVGL 9.4 brings hardware acceleration for fills, blending, and display transforms to ESP32-P4 devices, while keeping the LVGL API unchanged." | ||
| authors: | ||
| - felipe-neves | ||
| tags: ["component","lvgl","ESP-IDF"] | ||
| --- | ||
|
|
||
| ## Introduction | ||
|
|
||
| LVGL 9.4 introduces experimental support for the Espressif Pixel Processing Accelerator (PPA) as a **draw unit**, allowing rendering operations to be offloaded from the CPU to dedicated hardware on ESP32-P4 devices. | ||
|
|
||
| This article explains: | ||
|
|
||
| * What the PPA is on ESP32-P4 | ||
| * How LVGL models it as a draw unit | ||
| * How to enable PPA support | ||
| * Why the acceleration is fully transparent to user code | ||
|
|
||
| --- | ||
|
|
||
| ## What is the Pixel Processing Accelerator? | ||
|
|
||
| On ESP32-P4, the Pixel Processing Accelerator (PPA) is a hardware block designed to accelerate common pixel and image operations, including: | ||
|
|
||
| * Scale, rotate, mirror transformations | ||
| * Blending of foreground and background images | ||
| * Solid rectangle fills | ||
|
|
||
| In ESP-IDF, these are exposed through functions from its driver component such as: | ||
|
|
||
| * `ppa_do_blend()` | ||
| * `ppa_do_fill()` | ||
|
|
||
| LVGL 9.4 takes advantage of these operations via its draw pipeline, offloading supported tasks to the PPA when running on compatible Espressif targets. | ||
|
|
||
| --- | ||
|
|
||
| ## LVGL Draw Units in a Nutshell | ||
|
|
||
| In LVGL 9.x, rendering is decomposed into **draw tasks** processed by one or more **draw units**, which are implementations of `lv_draw_unit_t`. | ||
|
|
||
| Draw units can handle operations such as: | ||
|
|
||
| * Filling rectangles | ||
| * Blending images | ||
| * Drawing labels, arcs, lines, and more | ||
|
|
||
| Common draw units include: | ||
|
|
||
| * Software renderer | ||
| * Vendor-specific units such as the new Espressif PPA backend | ||
| * Advanced 2D Graphic accelerators. | ||
|
|
||
| The LVGL scheduler decides which unit handles each task, routing PPA-compatible operations to the PPA draw unit whenever possible. | ||
|
|
||
| --- | ||
|
|
||
| ## PPA as an LVGL Draw Unit | ||
|
|
||
| LVGL 9.4 includes a dedicated draw unit for Espressif PPA, implemented inside LVGL’s backend and registered alongside the software renderer when enabled. | ||
|
|
||
| Once the feature is active: | ||
|
|
||
| * LVGL keeps the normal software renderer | ||
| * A PPA draw unit is added | ||
| * Supported operations (fill, blend, scale/rotate/mirror) are routed to PPA | ||
| * Unsupported operations gracefully fall back to software | ||
|
|
||
| From the application’s perspective: | ||
|
|
||
| * No PPA-specific API calls are required | ||
| * All LVGL widget APIs remain the same | ||
| * PPA acceleration is completely transparent | ||
|
|
||
| --- | ||
|
|
||
| ## Enabling the LVGL PPA Draw Unit | ||
|
|
||
| ### 1. Requirements | ||
|
|
||
| * Target SoC: ESP32-P4 (PPA hardware block available) | ||
| * LVGL version: 9.4 or later | ||
| * ESP-IDF version with PPA driver support (e.g., ESP-IDF 5.5.x) | ||
| * ESP-LVGL-Port component v2.6 or later. | ||
| * (Optional) ESP-BSP if running LVGL under Espressif Development Board. | ||
|
|
||
| ### 2. LVGL Configuration | ||
|
|
||
| Enable PPA in LVGL via Kconfig. Add to `sdkconfig.defaults`: | ||
|
|
||
| ``` | ||
| # Enable PPA draw unit in LVGL | ||
| CONFIG_LV_USE_PPA=y | ||
|
|
||
| # Required alignment for draw buffers | ||
| CONFIG_LV_DRAW_BUF_ALIGN=64 | ||
| ``` | ||
|
|
||
| After updating config: | ||
|
|
||
| ``` | ||
| idf.py menuconfig | ||
| idf.py build | ||
| ``` | ||
|
|
||
| Once rebuilt, LVGL automatically registers the PPA draw unit. | ||
| No application source changes are needed. | ||
|
|
||
| --- | ||
|
|
||
| ## Starting LVGL with Double Buffering | ||
|
|
||
| Espressif recommends using **full-screen double buffering** to get maximum performance, as PPA operates best on large continuous buffer regions. | ||
|
|
||
| Example initialization: | ||
|
|
||
| ```c | ||
| #include "lvgl.h" | ||
| #include "bsp/esp-bsp.h" | ||
|
|
||
| void app_main(void) | ||
| { | ||
| bsp_display_cfg_t cfg = { | ||
| .lvgl_port_cfg = ESP_LVGL_PORT_INIT_CONFIG(), | ||
| .buffer_size = BSP_LCD_H_RES * BSP_LCD_V_RES, | ||
| .double_buffer = 1, | ||
|
|
||
| .hw_cfg = { | ||
| #if CONFIG_BSP_LCD_TYPE_HDMI | ||
| #if CONFIG_BSP_LCD_HDMI_800x600_60HZ | ||
| .hdmi_resolution = BSP_HDMI_RES_800x600, | ||
| #elif CONFIG_BSP_LCD_HDMI_1280x720_60HZ | ||
| .hdmi_resolution = BSP_HDMI_RES_1280x720, | ||
| #elif CONFIG_BSP_LCD_HDMI_1280x800_60HZ | ||
| .hdmi_resolution = BSP_HDMI_RES_1280x800, | ||
| #elif CONFIG_BSP_LCD_HDMI_1920x1080_30HZ | ||
| .hdmi_resolution = BSP_HDMI_RES_1920x1080, | ||
| #endif | ||
| #else | ||
| .hdmi_resolution = BSP_HDMI_RES_NONE, | ||
| #endif | ||
| .dsi_bus = { | ||
| .phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT, | ||
| .lane_bit_rate_mbps = BSP_LCD_MIPI_DSI_LANE_BITRATE_MBPS, | ||
| } | ||
| }, | ||
|
|
||
| .flags = { | ||
| #if CONFIG_BSP_LCD_COLOR_FORMAT_RGB888 | ||
| .buff_dma = false, | ||
| #else | ||
| .buff_dma = true, | ||
| #endif | ||
| .buff_spiram = true, | ||
| .sw_rotate = true, | ||
| } | ||
| }; | ||
|
|
||
| bsp_display_start_with_config(&cfg); | ||
| bsp_display_backlight_on(); | ||
|
|
||
| bsp_display_lock(0); | ||
| lv_demo_widgets(); | ||
| bsp_display_unlock(); | ||
| } | ||
| ``` | ||
|
|
||
| This ensures: | ||
|
|
||
| * Full-resolution buffers | ||
| * DMA-capable regions when necessary | ||
| * Highest PPA efficiency | ||
|
|
||
| --- | ||
|
|
||
| ## Using PPA for Rotation and Mirroring (Port-Level Acceleration) | ||
|
|
||
| The PPA integration has two layers: | ||
|
|
||
| 1. **LVGL PPA draw unit** — accelerates LVGL drawing | ||
| 2. **Espressif LVGL port PPA** — accelerates final framebuffer rotation/mirroring before output | ||
|
|
||
| To enable the second layer: | ||
|
|
||
| ``` | ||
| CONFIG_LVGL_PORT_ENABLE_PPA=y | ||
| ``` | ||
|
|
||
| When active: | ||
|
|
||
| * LVGL sets rotation/mirror metadata | ||
| * The Espressif port applies PPA transforms to the final framebuffer | ||
| * No application code changes are needed | ||
|
|
||
| This layer can provide major performance gains (e.g., rotation at near-zero CPU cost). | ||
|
|
||
| --- | ||
|
|
||
| ## Transparency for Application Code | ||
|
|
||
| One of the main design goals is complete transparency: | ||
|
|
||
| * No need to include PPA headers | ||
| * No need to manage PPA clients or transactions | ||
| * No changes to LVGL widget code | ||
| * No special calls or pipeline management | ||
|
|
||
| Once enabled via configuration, LVGL and the Espressif port: | ||
|
|
||
| * Create the PPA draw unit | ||
| * Select when to use PPA vs software | ||
| * Optionally apply PPA rotation/mirroring before sending to the display | ||
|
|
||
| Your UI code remains unchanged. | ||
|
|
||
| --- | ||
|
|
||
| ## Verifying That PPA is Working | ||
|
|
||
| Use the LVGL benchmark demo: | ||
|
|
||
| ```c | ||
| bsp_display_lock(0); | ||
| lv_demo_benchmark(); | ||
| bsp_display_unlock(); | ||
| ``` | ||
|
|
||
| With PPA enabled, you should observe: | ||
|
|
||
| * Around 30% improvement on many operations | ||
| * Up to 9× improvement in certain full-screen or fill-heavy cases | ||
|
|
||
| Compare FPS with and without PPA configuration. | ||
|
|
||
| --- | ||
|
|
||
| ## Limitations and Notes | ||
|
|
||
| * **Experimental**: LVGL 9.4 marks PPA as experimental | ||
| * **Operation coverage**: Best on rectangle fills; image blend benefits vary | ||
| * **Bandwidth constraints**: PSRAM/DMA bandwidth may limit gains | ||
| * **Buffer alignment**: Must set `CONFIG_LV_DRAW_BUF_ALIGN=64` | ||
| * **Best performance**: Full-screen double buffering | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure, if this is a good code for example. This is from BSP and you need to use BSP for using this (but BSP is optional above).
The second point, this code using HDMI from BSP and this is not good as example. Better is to use some LCD from EV board for explanation.
The third, in example shouldn't be
#if.