mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-19 03:02:27 +08:00
feat(draw/ppa): add initial Pixel Processing Accelerator infrastructure for ESP (#8270)
Arduino Lint / lint (push) Has been cancelled
Build Examples with C++ Compiler / build-examples (push) Has been cancelled
MicroPython CI / Build esp32 port (push) Has been cancelled
MicroPython CI / Build rp2 port (push) Has been cancelled
MicroPython CI / Build stm32 port (push) Has been cancelled
MicroPython CI / Build unix port (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_NORMAL_8BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_SDL - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_VG_LITE - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_VG_LITE - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_VG_LITE - gcc - Windows (push) Has been cancelled
C/C++ CI / Build ESP IDF ESP32S3 (push) Has been cancelled
C/C++ CI / Run tests with 32bit build (push) Has been cancelled
C/C++ CI / Run tests with 64bit build (push) Has been cancelled
BOM Check / bom-check (push) Has been cancelled
Verify that lv_conf_internal.h matches repository state / verify-conf-internal (push) Has been cancelled
Verify the widget property name / verify-property-name (push) Has been cancelled
Verify code formatting / verify-formatting (push) Has been cancelled
Build docs / build-and-deploy (push) Has been cancelled
Test API JSON generator / Test API JSON (push) Has been cancelled
Check Makefile / Build using Makefile (push) Has been cancelled
Check Makefile for UEFI / Build using Makefile for UEFI (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_32B - Ubuntu (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_64B - Ubuntu (push) Has been cancelled
Port repo release update / run-release-branch-updater (push) Has been cancelled
Verify Font License / verify-font-license (push) Has been cancelled
Verify Kconfig / verify-kconfig (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled
Arduino Lint / lint (push) Has been cancelled
Build Examples with C++ Compiler / build-examples (push) Has been cancelled
MicroPython CI / Build esp32 port (push) Has been cancelled
MicroPython CI / Build rp2 port (push) Has been cancelled
MicroPython CI / Build stm32 port (push) Has been cancelled
MicroPython CI / Build unix port (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_NORMAL_8BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_SDL - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_VG_LITE - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_VG_LITE - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_VG_LITE - gcc - Windows (push) Has been cancelled
C/C++ CI / Build ESP IDF ESP32S3 (push) Has been cancelled
C/C++ CI / Run tests with 32bit build (push) Has been cancelled
C/C++ CI / Run tests with 64bit build (push) Has been cancelled
BOM Check / bom-check (push) Has been cancelled
Verify that lv_conf_internal.h matches repository state / verify-conf-internal (push) Has been cancelled
Verify the widget property name / verify-property-name (push) Has been cancelled
Verify code formatting / verify-formatting (push) Has been cancelled
Build docs / build-and-deploy (push) Has been cancelled
Test API JSON generator / Test API JSON (push) Has been cancelled
Check Makefile / Build using Makefile (push) Has been cancelled
Check Makefile for UEFI / Build using Makefile for UEFI (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_32B - Ubuntu (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_64B - Ubuntu (push) Has been cancelled
Port repo release update / run-release-branch-updater (push) Has been cancelled
Verify Font License / verify-font-license (push) Has been cancelled
Verify Kconfig / verify-kconfig (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled
Signed-off-by: Felipe Neves <felipe@lvgl.io>
This commit is contained in:
@@ -527,6 +527,16 @@ menu "LVGL configuration"
|
||||
bool "Draw using cached OpenGLES textures"
|
||||
default n
|
||||
depends on LV_USE_OPENGLES
|
||||
|
||||
config LV_USE_PPA
|
||||
bool "Use Espressif's PPA accelerator for ESP SoCs"
|
||||
default n
|
||||
|
||||
config LV_USE_PPA_IMG
|
||||
bool "Use Espressif's PPA accelerator for Image draw"
|
||||
default n
|
||||
depends on LV_USE_PPA
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Feature Configuration"
|
||||
|
||||
@@ -196,3 +196,39 @@ The process is described in details below, using ``SPIFFS`` as demonstration.
|
||||
CONFIG_LV_USE_FS_STDIO=y
|
||||
CONFIG_LV_FS_STDIO_LETTER=65
|
||||
CONFIG_LV_FS_DEFAULT_DRIVER_LETTER=65
|
||||
|
||||
Support for Pixel Processing Accelerator
|
||||
----------------------------------------
|
||||
|
||||
Some ESP32 chip series, like the ESP32-P4 support the Pixel Processing Accelerator hardware (PPA), which is capable of
|
||||
speeding-up the filling and image blending operations, this peripheral works with the
|
||||
DMA-2D hardware which is responsible to move the input/output buffers into/from the PPA processing engine.
|
||||
|
||||
Supported devices
|
||||
-----------------
|
||||
|
||||
The Espressif targets that supports the PPA are:
|
||||
|
||||
- ESP32-P4 series.
|
||||
|
||||
|
||||
Using the PPA on your ESP-IDF project
|
||||
-------------------------------------
|
||||
|
||||
LVGL supports, in experimental level, the filling and the image blending
|
||||
acceleration through the PPA, the user can enable it inside their ``sdkconfig.default`` by
|
||||
adding the following option to enable the PPA draw unit in conjunction to the software render:
|
||||
|
||||
.. code:: c
|
||||
|
||||
CONFIG_LV_USE_PPA=y
|
||||
|
||||
Save the file and then rebuild the project, this will be sufficient to add the PPA code and it will start to run automatically, so
|
||||
no further steps are required from the user code perspective.
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
|
||||
Please notice that the PPA is at experimental level where some performance gains are expected on drawing tasks related
|
||||
to rectangle copy or filling, while for image blending, even though it is operational, there is no signifcant gains,
|
||||
the initial cause for that according to the PPA section from reference manual is due to the DMA-2D memory bandwidth.
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
======================================
|
||||
Espressif Pixel Processing Accelerator
|
||||
======================================
|
||||
|
||||
API
|
||||
***
|
||||
|
||||
:ref:`lv_draw_ppa_h`
|
||||
@@ -7,6 +7,7 @@ Renderers and GPUs
|
||||
|
||||
sw
|
||||
arm2d
|
||||
espressif_ppa
|
||||
nema_gfx
|
||||
nxp_pxp
|
||||
nxp_vglite_gpu
|
||||
|
||||
@@ -61,7 +61,7 @@ else()
|
||||
idf_component_register(SRCS ${SOURCES} ${EXAMPLE_SOURCES} ${DEMO_SOURCES}
|
||||
INCLUDE_DIRS ${LVGL_ROOT_DIR} ${LVGL_ROOT_DIR}/src ${LVGL_ROOT_DIR}/../
|
||||
${LVGL_ROOT_DIR}/examples ${LVGL_ROOT_DIR}/demos
|
||||
REQUIRES esp_timer)
|
||||
REQUIRES esp_timer esp_driver_ppa esp_mm log)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(${COMPONENT_LIB} PUBLIC "-DLV_CONF_INCLUDE_SIMPLE")
|
||||
|
||||
@@ -357,6 +357,11 @@
|
||||
/** Draw using cached OpenGLES textures */
|
||||
#define LV_USE_DRAW_OPENGLES 0
|
||||
|
||||
/** Draw using espressif PPA accelerator */
|
||||
#define LV_USE_PPA 0
|
||||
#if LV_USE_PPA
|
||||
#define LV_USE_PPA_IMG 0
|
||||
#endif
|
||||
/*=======================
|
||||
* FEATURE CONFIGURATION
|
||||
*=======================*/
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
/**
|
||||
* @file lv_draw_ppa.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_ppa_private.h"
|
||||
#include "lv_draw_ppa.h"
|
||||
|
||||
#if LV_USE_PPA
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define DRAW_UNIT_ID_PPA 80
|
||||
#define DRAW_UNIT_PPA_PREF_SCORE 70
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static int32_t ppa_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task);
|
||||
static int32_t ppa_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer);
|
||||
static int32_t ppa_delete(lv_draw_unit_t * draw_unit);
|
||||
static void ppa_execute_drawing(lv_draw_ppa_unit_t * u);
|
||||
static bool ppa_isr(ppa_client_handle_t ppa_client, ppa_event_data_t * event_data, void * user_data);
|
||||
|
||||
#if LV_PPA_NONBLOCKING_OPS
|
||||
static void ppa_thread(void * arg);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_ppa_init(void)
|
||||
{
|
||||
esp_err_t res;
|
||||
ppa_client_config_t cfg = {0};
|
||||
ppa_event_callbacks_t ppa_cbs = {
|
||||
.on_trans_done = ppa_isr,
|
||||
|
||||
};
|
||||
|
||||
/* Create draw unit */
|
||||
lv_draw_buf_ppa_init_handlers();
|
||||
lv_draw_ppa_unit_t * draw_ppa_unit = lv_draw_create_unit(sizeof(lv_draw_ppa_unit_t));
|
||||
draw_ppa_unit->base_unit.evaluate_cb = ppa_evaluate;
|
||||
draw_ppa_unit->base_unit.dispatch_cb = ppa_dispatch;
|
||||
draw_ppa_unit->base_unit.delete_cb = ppa_delete;
|
||||
draw_ppa_unit->base_unit.name = "ESP_PPA";
|
||||
|
||||
/* Register SRM client */
|
||||
cfg.oper_type = PPA_OPERATION_SRM;
|
||||
cfg.max_pending_trans_num = 4;
|
||||
res = ppa_register_client(&cfg, &draw_ppa_unit->srm_client);
|
||||
LV_ASSERT(res == ESP_OK);
|
||||
|
||||
/* Register Fill client */
|
||||
cfg.oper_type = PPA_OPERATION_FILL;
|
||||
res = ppa_register_client(&cfg, &draw_ppa_unit->fill_client);
|
||||
LV_ASSERT(res == ESP_OK);
|
||||
|
||||
/* Register Blend client */
|
||||
cfg.oper_type = PPA_OPERATION_BLEND;
|
||||
res = ppa_register_client(&cfg, &draw_ppa_unit->blend_client);
|
||||
LV_ASSERT(res == ESP_OK);
|
||||
|
||||
ppa_client_register_event_callbacks(draw_ppa_unit->srm_client, &ppa_cbs);
|
||||
ppa_client_register_event_callbacks(draw_ppa_unit->fill_client, &ppa_cbs);
|
||||
ppa_client_register_event_callbacks(draw_ppa_unit->blend_client, &ppa_cbs);
|
||||
|
||||
#if LV_PPA_NONBLOCKING_OPS
|
||||
lv_result_t lv_res = lv_thread_init(&draw_ppa_unit->thread, "ppa_thread", LV_DRAW_THREAD_PRIO, ppa_thread, 8192,
|
||||
draw_ppa_unit);
|
||||
LV_ASSERT(lv_res == LV_RESULT_OK);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void lv_draw_ppa_deinit(void)
|
||||
{
|
||||
/* No global deinit required */
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static bool ppa_isr(ppa_client_handle_t ppa_client, ppa_event_data_t * event_data, void * user_data)
|
||||
{
|
||||
|
||||
#if LV_PPA_NONBLOCKING_OPS
|
||||
lv_draw_ppa_unit_t * u = (lv_draw_ppa_unit_t *)user_data;
|
||||
lv_thread_sync_signal_isr(&u->interrupt_signal);
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int32_t ppa_evaluate(lv_draw_unit_t * u, lv_draw_task_t * t)
|
||||
{
|
||||
LV_UNUSED(u);
|
||||
const lv_draw_dsc_base_t * base = (lv_draw_dsc_base_t *)t->draw_dsc;
|
||||
|
||||
if(!ppa_dest_cf_supported(base->layer->color_format)) return 0;
|
||||
|
||||
switch(t->type) {
|
||||
case LV_DRAW_TASK_TYPE_FILL: {
|
||||
const lv_draw_fill_dsc_t * dsc = (lv_draw_fill_dsc_t *)t->draw_dsc;
|
||||
if((dsc->radius != 0 || dsc->grad.dir != LV_GRAD_DIR_NONE)) return 0;
|
||||
|
||||
if(t->preference_score > DRAW_UNIT_PPA_PREF_SCORE) {
|
||||
t->preference_score = DRAW_UNIT_PPA_PREF_SCORE;
|
||||
t->preferred_draw_unit_id = DRAW_UNIT_ID_PPA;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if LV_USE_PPA_IMG
|
||||
case LV_DRAW_TASK_TYPE_IMAGE: {
|
||||
lv_draw_image_dsc_t * dsc = t->draw_dsc;
|
||||
if(!(dsc->header.cf < LV_COLOR_FORMAT_PROPRIETARY_START
|
||||
&& dsc->clip_radius == 0
|
||||
&& dsc->bitmap_mask_src == NULL
|
||||
&& dsc->sup == NULL
|
||||
&& dsc->tile == 0
|
||||
&& dsc->blend_mode == LV_BLEND_MODE_NORMAL
|
||||
&& dsc->recolor_opa <= LV_OPA_MIN
|
||||
&& dsc->skew_y == 0
|
||||
&& dsc->skew_x == 0
|
||||
&& dsc->scale_x == 256
|
||||
&& dsc->scale_y == 256
|
||||
&& dsc->rotation == 0
|
||||
&& lv_image_src_get_type(dsc->src) == LV_IMAGE_SRC_VARIABLE
|
||||
&& (dsc->header.cf == LV_COLOR_FORMAT_ARGB8888
|
||||
|| dsc->header.cf == LV_COLOR_FORMAT_XRGB8888
|
||||
|| dsc->header.cf == LV_COLOR_FORMAT_RGB888
|
||||
|| dsc->header.cf == LV_COLOR_FORMAT_RGB565)
|
||||
&& (dsc->base.layer->color_format == LV_COLOR_FORMAT_ARGB8888
|
||||
|| dsc->base.layer->color_format == LV_COLOR_FORMAT_XRGB8888
|
||||
|| dsc->base.layer->color_format == LV_COLOR_FORMAT_RGB888
|
||||
|| dsc->base.layer->color_format == LV_COLOR_FORMAT_RGB565))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(t->preference_score > DRAW_UNIT_PPA_PREF_SCORE) {
|
||||
t->preference_score = DRAW_UNIT_PPA_PREF_SCORE;
|
||||
t->preferred_draw_unit_id = DRAW_UNIT_ID_PPA;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t ppa_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer)
|
||||
{
|
||||
lv_draw_ppa_unit_t * u = (lv_draw_ppa_unit_t *)draw_unit;
|
||||
if(u->task_act) return 0;
|
||||
|
||||
lv_draw_task_t * t = lv_draw_get_available_task(layer, NULL, DRAW_UNIT_ID_PPA);
|
||||
if(!t || t->preferred_draw_unit_id != DRAW_UNIT_ID_PPA) return LV_DRAW_UNIT_IDLE;
|
||||
if(!lv_draw_layer_alloc_buf(layer)) return LV_DRAW_UNIT_IDLE;
|
||||
|
||||
t->state = LV_DRAW_TASK_STATE_IN_PROGRESS;
|
||||
u->task_act = t;
|
||||
u->task_act->draw_unit = draw_unit;
|
||||
|
||||
ppa_execute_drawing(u);
|
||||
|
||||
#if !LV_PPA_NONBLOCKING_OPS
|
||||
u->task_act->state = LV_DRAW_TASK_STATE_READY;
|
||||
u->task_act = NULL;
|
||||
lv_draw_dispatch_request();
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int32_t ppa_delete(lv_draw_unit_t * draw_unit)
|
||||
{
|
||||
lv_draw_ppa_unit_t * u = (lv_draw_ppa_unit_t *)draw_unit;
|
||||
ppa_unregister_client(u->srm_client);
|
||||
ppa_unregister_client(u->fill_client);
|
||||
ppa_unregister_client(u->blend_client);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ppa_execute_drawing(lv_draw_ppa_unit_t * u)
|
||||
{
|
||||
lv_draw_task_t * t = u->task_act;
|
||||
lv_layer_t * layer = t->target_layer;
|
||||
lv_draw_buf_t * buf = layer->draw_buf;
|
||||
lv_area_t area;
|
||||
lv_area_t draw_area;
|
||||
|
||||
if(!lv_area_intersect(&area, &t->area, &t->clip_area)) return;
|
||||
|
||||
lv_area_move(&draw_area, -layer->buf_area.x1, -layer->buf_area.y1);
|
||||
lv_draw_buf_invalidate_cache(buf, &draw_area);
|
||||
|
||||
switch(t->type) {
|
||||
case LV_DRAW_TASK_TYPE_FILL:
|
||||
lv_draw_ppa_fill(t, (lv_draw_fill_dsc_t *)t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_IMAGE:
|
||||
lv_draw_ppa_img(t, (lv_draw_image_dsc_t *)t->draw_dsc, &t->area);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_PPA_NONBLOCKING_OPS
|
||||
static void ppa_thread(void * arg)
|
||||
{
|
||||
lv_draw_ppa_unit_t * u = arg;
|
||||
lv_thread_sync_init(&u->interrupt_signal);
|
||||
|
||||
while(1) {
|
||||
do {
|
||||
lv_thread_sync_wait(&u->interrupt_signal);
|
||||
} while(u->task_act != NULL);
|
||||
|
||||
u->task_act->state = LV_DRAW_TASK_STATE_READY;
|
||||
u->task_act = NULL;
|
||||
lv_draw_dispatch_request();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*LV_USE_PPA*/
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @file lv_draw_ppa.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_PPA_H
|
||||
#define LV_DRAW_PPA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_PPA
|
||||
|
||||
#include "../../lv_draw_private.h"
|
||||
#include "../../../display/lv_display_private.h"
|
||||
#include "../../../misc/lv_area_private.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_draw_ppa_init(void);
|
||||
void lv_draw_ppa_deinit(void);
|
||||
void lv_draw_buf_ppa_init_handlers(void);
|
||||
|
||||
void lv_draw_ppa_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
void lv_draw_ppa_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* LV_USE_PPA */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /* LV_DRAW_PPA_H */
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @file lv_draw_ppa_buf.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_ppa_private.h"
|
||||
#include "lv_draw_ppa.h"
|
||||
|
||||
#if LV_USE_PPA
|
||||
#include LV_STDINT_INCLUDE
|
||||
#include "../../lv_draw_buf_private.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
*********************/
|
||||
static void invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area);
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
*********************/
|
||||
|
||||
void lv_draw_buf_ppa_init_handlers(void)
|
||||
{
|
||||
lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers();
|
||||
lv_draw_buf_handlers_t * image_handlers = lv_draw_buf_get_image_handlers();
|
||||
|
||||
handlers->invalidate_cache_cb = invalidate_cache;
|
||||
image_handlers->invalidate_cache_cb = invalidate_cache;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
*********************/
|
||||
|
||||
static void invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area)
|
||||
{
|
||||
esp_cache_msync((void *)PPA_PTR_ALIGN_DOWN(draw_buf->data, CONFIG_CACHE_L1_CACHE_LINE_SIZE),
|
||||
PPA_ALIGN_DOWN(draw_buf->data_size, CONFIG_CACHE_L1_CACHE_LINE_SIZE),
|
||||
ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_TYPE_DATA);
|
||||
}
|
||||
#endif /* LV_USE_PPA */
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @file lv_draw_ppa_fill.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lv_draw_ppa_private.h"
|
||||
#include "lv_draw_ppa.h"
|
||||
|
||||
#if LV_USE_PPA
|
||||
|
||||
void lv_draw_ppa_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
lv_draw_ppa_unit_t * u = (lv_draw_ppa_unit_t *)t->draw_unit;
|
||||
lv_draw_buf_t * draw_buf = t->target_layer->draw_buf;
|
||||
int width = lv_area_get_width(coords);
|
||||
int height = lv_area_get_height(coords);
|
||||
|
||||
if(width <= 0 || height <= 0) {
|
||||
LV_LOG_WARN("Invalid draw area for filling!");
|
||||
return;
|
||||
}
|
||||
|
||||
ppa_fill_oper_config_t cfg = {
|
||||
.fill_argb_color.val = lv_color_to_u32(dsc->color),
|
||||
.fill_block_w = width,
|
||||
.fill_block_h = height,
|
||||
.out = {
|
||||
.buffer = draw_buf->data,
|
||||
.buffer_size = draw_buf->data_size,
|
||||
.pic_w = width,
|
||||
.pic_h = height,
|
||||
.block_offset_x = 0,
|
||||
.block_offset_y = 0,
|
||||
.fill_cm = lv_color_format_to_ppa_fill(draw_buf->header.cf),
|
||||
},
|
||||
|
||||
#if LV_PPA_NONBLOCKING_OPS
|
||||
.mode = PPA_TRANS_MODE_NON_BLOCKING,
|
||||
.user_data = u,
|
||||
#else
|
||||
.mode = PPA_TRANS_MODE_BLOCKING,
|
||||
#endif
|
||||
};
|
||||
|
||||
esp_err_t ret = ppa_do_fill(u->fill_client, &cfg);
|
||||
if(ret != ESP_OK) {
|
||||
LV_LOG_ERROR("PPA fill failed: %d", ret);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* LV_USE_PPA */
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* @file lv_draw_ppa_img.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lv_draw_ppa_private.h"
|
||||
#include "lv_draw_ppa.h"
|
||||
|
||||
#if LV_USE_PPA
|
||||
|
||||
void lv_draw_ppa_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_draw_ppa_unit_t * u = (lv_draw_ppa_unit_t *)t->draw_unit;
|
||||
lv_draw_buf_t * draw_buf = t->target_layer->draw_buf;
|
||||
const lv_image_dsc_t * img_dsc = dsc->src;
|
||||
int width = lv_area_get_width(coords);
|
||||
int height = lv_area_get_height(coords);
|
||||
|
||||
ppa_blend_oper_config_t cfg = {
|
||||
.in_bg = {
|
||||
.buffer = (void *)draw_buf->data,
|
||||
.pic_w = width,
|
||||
.pic_h = height,
|
||||
.block_w = width,
|
||||
.block_h = height,
|
||||
.block_offset_x = 0,
|
||||
.block_offset_y = 0,
|
||||
.blend_cm = lv_color_format_to_ppa_blend(draw_buf->header.cf)
|
||||
},
|
||||
.in_fg = {
|
||||
.buffer = (void *)img_dsc->data,
|
||||
.pic_w = width,
|
||||
.pic_h = height,
|
||||
.block_w = width,
|
||||
.block_h = height,
|
||||
.block_offset_x = 0,
|
||||
.block_offset_y = 0,
|
||||
.blend_cm = lv_color_format_to_ppa_blend(dsc->header.cf)
|
||||
},
|
||||
.out = {
|
||||
.buffer = draw_buf->data,
|
||||
.buffer_size = draw_buf->data_size,
|
||||
.pic_w = width,
|
||||
.pic_h = height,
|
||||
.block_offset_x = 0,
|
||||
.block_offset_y = 0,
|
||||
.blend_cm = lv_color_format_to_ppa_blend(draw_buf->header.cf)
|
||||
},
|
||||
.bg_rgb_swap = false,
|
||||
.bg_byte_swap = false,
|
||||
.fg_rgb_swap = false,
|
||||
.fg_byte_swap = false,
|
||||
.bg_alpha_update_mode = PPA_ALPHA_FIX_VALUE,
|
||||
.bg_alpha_fix_val = 0xff,
|
||||
|
||||
.fg_alpha_update_mode = PPA_ALPHA_FIX_VALUE,
|
||||
.fg_alpha_fix_val = dsc->opa,
|
||||
.bg_ck_en = false,
|
||||
.fg_ck_en = false,
|
||||
#if LV_PPA_NONBLOCKING_OPS
|
||||
.mode = PPA_TRANS_MODE_NON_BLOCKING,
|
||||
.user_data = u,
|
||||
#else
|
||||
.mode = PPA_TRANS_MODE_BLOCKING,
|
||||
#endif
|
||||
};
|
||||
|
||||
esp_err_t ret = ppa_do_blend(u->blend_client, &cfg);
|
||||
if(ret != ESP_OK) {
|
||||
LV_LOG_WARN("PPA draw_img blend failed: %d", ret);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* LV_USE_PPA */
|
||||
@@ -0,0 +1,185 @@
|
||||
/**
|
||||
* @file lv_ppa_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_PPA_PRIVATE_H
|
||||
#define LV_DRAW_PPA_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_PPA
|
||||
#if LV_PPA_NONBLOCKING_OPS
|
||||
#error "PPA draw in nonblocking is experimental and not supported yet, please make it to 0!"
|
||||
#endif
|
||||
|
||||
#ifndef LV_PPA_NONBLOCKING_OPS
|
||||
#define LV_PPA_NONBLOCKING_OPS 0
|
||||
#endif
|
||||
|
||||
#include LV_STDDEF_INCLUDE
|
||||
#include LV_STDBOOL_INCLUDE
|
||||
#include LV_STDINT_INCLUDE
|
||||
|
||||
#include "../../../misc/lv_color.h"
|
||||
#include "../../../misc/lv_log.h"
|
||||
#include "../../lv_draw_private.h"
|
||||
#include "../../../display/lv_display_private.h"
|
||||
#include "../../../misc/lv_area_private.h"
|
||||
|
||||
/* The ppa driver depends heavily on the esp-idf headers*/
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_LV_ATTRIBUTE_MEM_ALIGN_SIZE != CONFIG_CACHE_L1_CACHE_LINE_SIZE || CONFIG_LV_DRAW_BUF_ALIGN != CONFIG_CACHE_L1_CACHE_LINE_SIZE
|
||||
#error "For using PPA buffers need to be aligned to 64-byte boundary!"
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef CONFIG_SOC_PPA_SUPPORTED
|
||||
#error "This SoC does not support PPA"
|
||||
#endif
|
||||
|
||||
#include "driver/ppa.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_err.h"
|
||||
#include "hal/color_hal.h"
|
||||
#include "esp_cache.h"
|
||||
#include "esp_log.h"
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct lv_draw_ppa_unit {
|
||||
lv_draw_unit_t base_unit;
|
||||
lv_draw_task_t * task_act;
|
||||
ppa_client_handle_t srm_client;
|
||||
ppa_client_handle_t fill_client;
|
||||
ppa_client_handle_t blend_client;
|
||||
uint8_t * buf;
|
||||
#if LV_PPA_NONBLOCKING_OPS
|
||||
lv_thread_t thread;
|
||||
lv_thread_sync_t interrupt_signal;
|
||||
#endif
|
||||
} lv_draw_ppa_unit_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static inline bool ppa_src_cf_supported(lv_color_format_t cf)
|
||||
{
|
||||
bool is_cf_supported = false;
|
||||
|
||||
switch(cf) {
|
||||
case LV_COLOR_FORMAT_RGB565:
|
||||
case LV_COLOR_FORMAT_ARGB8888:
|
||||
case LV_COLOR_FORMAT_XRGB8888:
|
||||
is_cf_supported = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return is_cf_supported;
|
||||
}
|
||||
|
||||
static inline bool ppa_dest_cf_supported(lv_color_format_t cf)
|
||||
{
|
||||
bool is_cf_supported = false;
|
||||
|
||||
switch(cf) {
|
||||
case LV_COLOR_FORMAT_RGB565:
|
||||
case LV_COLOR_FORMAT_RGB888:
|
||||
case LV_COLOR_FORMAT_ARGB8888:
|
||||
case LV_COLOR_FORMAT_XRGB8888:
|
||||
is_cf_supported = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return is_cf_supported;
|
||||
}
|
||||
|
||||
static inline ppa_fill_color_mode_t lv_color_format_to_ppa_fill(lv_color_format_t lv_fmt)
|
||||
{
|
||||
switch(lv_fmt) {
|
||||
case LV_COLOR_FORMAT_RGB565:
|
||||
return PPA_FILL_COLOR_MODE_RGB565;
|
||||
case LV_COLOR_FORMAT_RGB888:
|
||||
return PPA_FILL_COLOR_MODE_RGB888;
|
||||
case LV_COLOR_FORMAT_ARGB8888:
|
||||
case LV_COLOR_FORMAT_XRGB8888:
|
||||
return PPA_FILL_COLOR_MODE_ARGB8888;
|
||||
default:
|
||||
return PPA_FILL_COLOR_MODE_RGB565;
|
||||
}
|
||||
}
|
||||
|
||||
static inline ppa_blend_color_mode_t lv_color_format_to_ppa_blend(lv_color_format_t lv_fmt)
|
||||
{
|
||||
switch(lv_fmt) {
|
||||
case LV_COLOR_FORMAT_RGB565:
|
||||
return PPA_BLEND_COLOR_MODE_RGB565;
|
||||
case LV_COLOR_FORMAT_RGB888:
|
||||
return PPA_BLEND_COLOR_MODE_RGB888;
|
||||
case LV_COLOR_FORMAT_ARGB8888:
|
||||
case LV_COLOR_FORMAT_XRGB8888:
|
||||
return PPA_BLEND_COLOR_MODE_ARGB8888;
|
||||
default:
|
||||
return PPA_BLEND_COLOR_MODE_RGB565;
|
||||
}
|
||||
}
|
||||
|
||||
static inline ppa_srm_color_mode_t lv_color_format_to_ppa_srm(lv_color_format_t lv_fmt)
|
||||
{
|
||||
switch(lv_fmt) {
|
||||
case LV_COLOR_FORMAT_RGB565:
|
||||
return PPA_SRM_COLOR_MODE_RGB565;
|
||||
case LV_COLOR_FORMAT_RGB888:
|
||||
return PPA_SRM_COLOR_MODE_RGB888;
|
||||
case LV_COLOR_FORMAT_ARGB8888:
|
||||
case LV_COLOR_FORMAT_XRGB8888:
|
||||
return PPA_SRM_COLOR_MODE_ARGB8888;
|
||||
default:
|
||||
return PPA_SRM_COLOR_MODE_RGB565;
|
||||
}
|
||||
}
|
||||
|
||||
#define PPA_ALIGN_UP(x, align) ((((x) + (align) - 1) / (align)) * (align))
|
||||
#define PPA_PTR_ALIGN_UP(p, align) \
|
||||
((void*)(((uintptr_t)(p) + (uintptr_t)((align) - 1)) & ~(uintptr_t)((align) - 1)))
|
||||
|
||||
#define PPA_ALIGN_DOWN(x, align) ((((x) - (align) - 1) / (align)) * (align))
|
||||
#define PPA_PTR_ALIGN_DOWN(p, align) \
|
||||
((void*)(((uintptr_t)(p) - (uintptr_t)((align) - 1)) & ~(uintptr_t)((align) - 1)))
|
||||
|
||||
#endif /* LV_USE_PPA */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /* LV_PPA_PRIVATE_H */
|
||||
@@ -1000,6 +1000,23 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** Draw using espressif PPA accelerator */
|
||||
#ifndef LV_USE_PPA
|
||||
#ifdef CONFIG_LV_USE_PPA
|
||||
#define LV_USE_PPA CONFIG_LV_USE_PPA
|
||||
#else
|
||||
#define LV_USE_PPA 0
|
||||
#endif
|
||||
#endif
|
||||
#if LV_USE_PPA
|
||||
#ifndef LV_USE_PPA_IMG
|
||||
#ifdef CONFIG_LV_USE_PPA_IMG
|
||||
#define LV_USE_PPA_IMG CONFIG_LV_USE_PPA_IMG
|
||||
#else
|
||||
#define LV_USE_PPA_IMG 0
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
/*=======================
|
||||
* FEATURE CONFIGURATION
|
||||
*=======================*/
|
||||
|
||||
@@ -74,6 +74,9 @@
|
||||
#if LV_USE_DRAW_OPENGLES
|
||||
#include "draw/opengles/lv_draw_opengles.h"
|
||||
#endif
|
||||
#if LV_USE_PPA
|
||||
#include "draw/espressif/ppa/lv_draw_ppa.h"
|
||||
#endif
|
||||
#if LV_USE_WINDOWS
|
||||
#include "drivers/windows/lv_windows_context.h"
|
||||
#endif
|
||||
@@ -260,6 +263,10 @@ void lv_init(void)
|
||||
lv_draw_opengles_init();
|
||||
#endif
|
||||
|
||||
#if LV_USE_PPA
|
||||
lv_draw_ppa_init();
|
||||
#endif
|
||||
|
||||
#if LV_USE_WINDOWS
|
||||
lv_windows_platform_init();
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user