diff --git a/Kconfig b/Kconfig index 3381015c61..d4e3cf04fa 100644 --- a/Kconfig +++ b/Kconfig @@ -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" diff --git a/docs/src/details/integration/chip/espressif.rst b/docs/src/details/integration/chip/espressif.rst index 78b050284c..74e25923ae 100644 --- a/docs/src/details/integration/chip/espressif.rst +++ b/docs/src/details/integration/chip/espressif.rst @@ -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. diff --git a/docs/src/details/integration/renderers/espressif_ppa.rst b/docs/src/details/integration/renderers/espressif_ppa.rst new file mode 100644 index 0000000000..58160d9a92 --- /dev/null +++ b/docs/src/details/integration/renderers/espressif_ppa.rst @@ -0,0 +1,8 @@ +====================================== +Espressif Pixel Processing Accelerator +====================================== + +API +*** + +:ref:`lv_draw_ppa_h` diff --git a/docs/src/details/integration/renderers/index.rst b/docs/src/details/integration/renderers/index.rst index 53788cd68a..25b49a6e5e 100644 --- a/docs/src/details/integration/renderers/index.rst +++ b/docs/src/details/integration/renderers/index.rst @@ -7,6 +7,7 @@ Renderers and GPUs sw arm2d + espressif_ppa nema_gfx nxp_pxp nxp_vglite_gpu diff --git a/env_support/cmake/esp.cmake b/env_support/cmake/esp.cmake index 8aaed350eb..73c28372fe 100644 --- a/env_support/cmake/esp.cmake +++ b/env_support/cmake/esp.cmake @@ -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") diff --git a/lv_conf_template.h b/lv_conf_template.h index 6abfbb94ad..2ed3b13d5b 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -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 *=======================*/ diff --git a/src/draw/espressif/ppa/lv_draw_ppa.c b/src/draw/espressif/ppa/lv_draw_ppa.c new file mode 100644 index 0000000000..cfb9863c21 --- /dev/null +++ b/src/draw/espressif/ppa/lv_draw_ppa.c @@ -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*/ diff --git a/src/draw/espressif/ppa/lv_draw_ppa.h b/src/draw/espressif/ppa/lv_draw_ppa.h new file mode 100644 index 0000000000..542b0fed9e --- /dev/null +++ b/src/draw/espressif/ppa/lv_draw_ppa.h @@ -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 */ diff --git a/src/draw/espressif/ppa/lv_draw_ppa_buf.c b/src/draw/espressif/ppa/lv_draw_ppa_buf.c new file mode 100644 index 0000000000..1ec6d59a64 --- /dev/null +++ b/src/draw/espressif/ppa/lv_draw_ppa_buf.c @@ -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 */ diff --git a/src/draw/espressif/ppa/lv_draw_ppa_fill.c b/src/draw/espressif/ppa/lv_draw_ppa_fill.c new file mode 100644 index 0000000000..b27488376d --- /dev/null +++ b/src/draw/espressif/ppa/lv_draw_ppa_fill.c @@ -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 */ diff --git a/src/draw/espressif/ppa/lv_draw_ppa_img.c b/src/draw/espressif/ppa/lv_draw_ppa_img.c new file mode 100644 index 0000000000..a74e6f1434 --- /dev/null +++ b/src/draw/espressif/ppa/lv_draw_ppa_img.c @@ -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 */ diff --git a/src/draw/espressif/ppa/lv_draw_ppa_private.h b/src/draw/espressif/ppa/lv_draw_ppa_private.h new file mode 100644 index 0000000000..4096f619dc --- /dev/null +++ b/src/draw/espressif/ppa/lv_draw_ppa_private.h @@ -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 */ diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index 0ad8e64e10..10fe6fbf8c 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.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 *=======================*/ diff --git a/src/lv_init.c b/src/lv_init.c index 7192f72d9d..790652d6a0 100644 --- a/src/lv_init.c +++ b/src/lv_init.c @@ -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