From 78cbdfc15183a529710ec3e525ea0597975cf6f7 Mon Sep 17 00:00:00 2001 From: Rbb666 <64397326+Rbb666@users.noreply.github.com> Date: Thu, 8 Jun 2023 16:42:34 +0800 Subject: [PATCH] add(gpu): add renesas-ra6m3 gpu adaptation (#4270) --- Kconfig | 10 + lv_conf_template.h | 8 + src/core/lv_obj.c | 9 + src/draw/renesas/lv_draw_renesas.mk | 7 + src/draw/renesas/lv_gpu_d2_draw_label.c | 292 ++++++++++ src/draw/renesas/lv_gpu_d2_ra6m3.c | 742 ++++++++++++++++++++++++ src/draw/renesas/lv_gpu_d2_ra6m3.h | 56 ++ src/hal/lv_hal_disp.c | 8 +- src/lv_conf_internal.h | 20 + 9 files changed, 1150 insertions(+), 2 deletions(-) create mode 100644 src/draw/renesas/lv_draw_renesas.mk create mode 100644 src/draw/renesas/lv_gpu_d2_draw_label.c create mode 100644 src/draw/renesas/lv_gpu_d2_ra6m3.c create mode 100644 src/draw/renesas/lv_gpu_d2_ra6m3.h diff --git a/Kconfig b/Kconfig index d4766b5c4..23c2c25fc 100644 --- a/Kconfig +++ b/Kconfig @@ -228,6 +228,16 @@ menu "LVGL configuration" Must be defined to include path of CMSIS header of target processor e.g. "stm32f769xx.h" or "stm32f429xx.h" + config LV_USE_GPU_RA6M3_G2D + bool "Enable RA6M3 G2D GPU." + config LV_GPU_RA6M3_G2D_INCLUDE + string "include path of target processor" + depends on LV_USE_GPU_RA6M3_G2D + default "hal_data.h" + help + Must be defined to include path of target processor + e.g. "hal_data.h" + config LV_USE_GPU_SWM341_DMA2D bool "Enable SWM341 DMA2D GPU." config LV_GPU_SWM341_DMA2D_INCLUDE diff --git a/lv_conf_template.h b/lv_conf_template.h index 86ca20764..1e31047e9 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -187,6 +187,14 @@ #define LV_GPU_DMA2D_CMSIS_INCLUDE #endif +/*Enable RA6M3 G2D GPU*/ +#define LV_USE_GPU_RA6M3_G2D 0 +#if LV_USE_GPU_RA6M3_G2D + /*include path of target processor + e.g. "hal_data.h"*/ + #define LV_GPU_RA6M3_G2D_INCLUDE "hal_data.h" +#endif + /*Use SWM341's DMA2D GPU*/ #define LV_USE_GPU_SWM341_DMA2D 0 #if LV_USE_GPU_SWM341_DMA2D diff --git a/src/core/lv_obj.c b/src/core/lv_obj.c index 8890fcbe0..d7bd04545 100644 --- a/src/core/lv_obj.c +++ b/src/core/lv_obj.c @@ -30,6 +30,10 @@ #include "../draw/stm32_dma2d/lv_gpu_stm32_dma2d.h" #endif +#if LV_USE_GPU_RA6M3_G2D + #include "../draw/renesas/lv_gpu_d2_ra6m3.h" +#endif + #if LV_USE_GPU_SWM341_DMA2D #include "../draw/swm341_dma2d/lv_gpu_swm341_dma2d.h" #endif @@ -119,6 +123,11 @@ void lv_init(void) lv_draw_stm32_dma2d_init(); #endif +#if LV_USE_GPU_RA6M3_G2D + /*Initialize G2D GPU*/ + lv_draw_ra6m3_g2d_init(); +#endif + #if LV_USE_GPU_SWM341_DMA2D /*Initialize DMA2D GPU*/ lv_draw_swm341_dma2d_init(); diff --git a/src/draw/renesas/lv_draw_renesas.mk b/src/draw/renesas/lv_draw_renesas.mk new file mode 100644 index 000000000..b5e3ad100 --- /dev/null +++ b/src/draw/renesas/lv_draw_renesas.mk @@ -0,0 +1,7 @@ +CSRCS += lv_gpu_d2_ra6m3.c +CSRCS += lv_gpu_d2_draw_label.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/renesas +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/renesas + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/renesas" diff --git a/src/draw/renesas/lv_gpu_d2_draw_label.c b/src/draw/renesas/lv_gpu_d2_draw_label.c new file mode 100644 index 000000000..b12866de5 --- /dev/null +++ b/src/draw/renesas/lv_gpu_d2_draw_label.c @@ -0,0 +1,292 @@ +/** + * @file lv_gpu_d2_draw_label.c + * + * @description HAL layer for display driver + * + */ + +/********************* + * INCLUDES + *********************/ +#include "../../draw/lv_draw_label.h" +#include "../../misc/lv_assert.h" +#include "../../core/lv_refr.h" +#include "lv_gpu_d2_ra6m3.h" + +#if LV_USE_GPU_RA6M3_G2D +#include LV_GPU_RA6M3_G2D_INCLUDE + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * GLOBAL VARIABLES + **********************/ +extern const uint8_t _lv_bpp1_opa_table[2]; +extern const uint8_t _lv_bpp2_opa_table[4]; +extern const uint8_t _lv_bpp4_opa_table[16]; +extern const uint8_t _lv_bpp8_opa_table[256]; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +LV_ATTRIBUTE_FAST_MEM static void draw_letter_normal(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t * dsc, + const lv_point_t * pos, lv_font_glyph_dsc_t * g, const uint8_t * map_p) +{ + + const uint8_t * bpp_opa_table_p; + uint32_t bitmask_init; + uint32_t bitmask; + uint32_t bpp = g->bpp; + lv_opa_t opa = dsc->opa; + uint32_t shades; + if(bpp == 3) bpp = 4; + +#if LV_USE_IMGFONT + if(bpp == LV_IMGFONT_BPP) { //is imgfont + lv_area_t fill_area; + fill_area.x1 = pos->x; + fill_area.y1 = pos->y; + fill_area.x2 = pos->x + g->box_w - 1; + fill_area.y2 = pos->y + g->box_h - 1; + lv_draw_img_dsc_t img_dsc; + lv_draw_img_dsc_init(&img_dsc); + img_dsc.angle = 0; + img_dsc.zoom = LV_IMG_ZOOM_NONE; + img_dsc.opa = dsc->opa; + img_dsc.blend_mode = dsc->blend_mode; + lv_draw_img(draw_ctx, &img_dsc, &fill_area, map_p); + return; + } +#endif + + switch(bpp) { + case 1: + bpp_opa_table_p = _lv_bpp1_opa_table; + bitmask_init = 0x80; + shades = 2; + break; + case 2: + bpp_opa_table_p = _lv_bpp2_opa_table; + bitmask_init = 0xC0; + shades = 4; + break; + case 4: + bpp_opa_table_p = _lv_bpp4_opa_table; + bitmask_init = 0xF0; + shades = 16; + break; + case 8: + bpp_opa_table_p = _lv_bpp8_opa_table; + bitmask_init = 0xFF; + shades = 256; + break; /*No opa table, pixel value will be used directly*/ + default: + LV_LOG_WARN("lv_draw_letter: invalid bpp"); + return; /*Invalid bpp. Can't render the letter*/ + } + + static lv_opa_t opa_table[256]; + static lv_opa_t prev_opa = LV_OPA_TRANSP; + static uint32_t prev_bpp = 0; + if(opa < LV_OPA_MAX) { + if(prev_opa != opa || prev_bpp != bpp) { + uint32_t i; + for(i = 0; i < shades; i++) { + opa_table[i] = bpp_opa_table_p[i] == LV_OPA_COVER ? opa : ((bpp_opa_table_p[i] * opa) >> 8); + } + } + bpp_opa_table_p = opa_table; + prev_opa = opa; + prev_bpp = bpp; + } + + int32_t col, row; + int32_t box_w = g->box_w; + int32_t box_h = g->box_h; + int32_t width_bit = box_w * bpp; /*Letter width in bits*/ + + /*Calculate the col/row start/end on the map*/ + int32_t col_start = pos->x >= draw_ctx->clip_area->x1 ? 0 : draw_ctx->clip_area->x1 - pos->x; + int32_t col_end = pos->x + box_w <= draw_ctx->clip_area->x2 ? box_w : draw_ctx->clip_area->x2 - pos->x + 1; + int32_t row_start = pos->y >= draw_ctx->clip_area->y1 ? 0 : draw_ctx->clip_area->y1 - pos->y; + int32_t row_end = pos->y + box_h <= draw_ctx->clip_area->y2 ? box_h : draw_ctx->clip_area->y2 - pos->y + 1; + + /*Move on the map too*/ + uint32_t bit_ofs = (row_start * width_bit) + (col_start * bpp); + map_p += bit_ofs >> 3; + + uint8_t letter_px; + uint32_t col_bit; + col_bit = bit_ofs & 0x7; /*"& 0x7" equals to "% 8" just faster*/ + + lv_draw_sw_blend_dsc_t blend_dsc; + lv_memset_00(&blend_dsc, sizeof(blend_dsc)); + blend_dsc.color = dsc->color; + blend_dsc.opa = LV_OPA_COVER; + blend_dsc.blend_mode = dsc->blend_mode; + + lv_coord_t hor_res = lv_disp_get_hor_res(_lv_refr_get_disp_refreshing()); + uint32_t mask_buf_size = box_w * box_h > hor_res ? hor_res : box_w * box_h; + lv_opa_t * mask_buf = lv_mem_buf_get(mask_buf_size); + blend_dsc.mask_buf = mask_buf; + int32_t mask_p = 0; + + lv_area_t fill_area; + fill_area.x1 = col_start + pos->x; + fill_area.x2 = col_end + pos->x - 1; + fill_area.y1 = row_start + pos->y; + fill_area.y2 = fill_area.y1; +#if LV_DRAW_COMPLEX + lv_coord_t fill_w = lv_area_get_width(&fill_area); + lv_area_t mask_area; + lv_area_copy(&mask_area, &fill_area); + mask_area.y2 = mask_area.y1 + row_end; + bool mask_any = lv_draw_mask_is_any(&mask_area); +#endif + blend_dsc.blend_area = &fill_area; + blend_dsc.mask_area = &fill_area; + + uint32_t col_bit_max = 8 - bpp; + uint32_t col_bit_row_ofs = (box_w + col_start - col_end) * bpp; + + for(row = row_start ; row < row_end; row++) { +#if LV_DRAW_COMPLEX + int32_t mask_p_start = mask_p; +#endif + bitmask = bitmask_init >> col_bit; + for(col = col_start; col < col_end; col++) { + /*Load the pixel's opacity into the mask*/ + letter_px = (*map_p & bitmask) >> (col_bit_max - col_bit); + if(letter_px) { + mask_buf[mask_p] = bpp_opa_table_p[letter_px]; + } + else { + mask_buf[mask_p] = 0; + } + + /*Go to the next column*/ + if(col_bit < col_bit_max) { + col_bit += bpp; + bitmask = bitmask >> bpp; + } + else { + col_bit = 0; + bitmask = bitmask_init; + map_p++; + } + + /*Next mask byte*/ + mask_p++; + } + +#if LV_DRAW_COMPLEX + /*Apply masks if any*/ + if(mask_any) { + blend_dsc.mask_res = lv_draw_mask_apply(mask_buf + mask_p_start, fill_area.x1, fill_area.y2, + fill_w); + if(blend_dsc.mask_res == LV_DRAW_MASK_RES_TRANSP) { + lv_memset_00(mask_buf + mask_p_start, fill_w); + } + } +#endif + + if((uint32_t) mask_p + (col_end - col_start) < mask_buf_size) { + fill_area.y2 ++; + } + else { + blend_dsc.mask_res = LV_DRAW_MASK_RES_CHANGED; + lv_draw_ra6m3_2d_blend(draw_ctx, &blend_dsc); + + fill_area.y1 = fill_area.y2 + 1; + fill_area.y2 = fill_area.y1; + mask_p = 0; + } + + col_bit += col_bit_row_ofs; + map_p += (col_bit >> 3); + col_bit = col_bit & 0x7; + } + + /*Flush the last part*/ + if(fill_area.y1 != fill_area.y2) { + fill_area.y2--; + blend_dsc.mask_res = LV_DRAW_MASK_RES_CHANGED; + lv_draw_ra6m3_2d_blend(draw_ctx, &blend_dsc); + mask_p = 0; + } + + lv_mem_buf_release(mask_buf); +} + +void lv_draw_gpu_letter(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t * dsc, const lv_point_t * pos_p, + uint32_t letter) +{ + const lv_font_t * font_p = dsc->font; + + lv_opa_t opa = dsc->opa; + if(opa < LV_OPA_MIN) return; + if(opa > LV_OPA_MAX) opa = LV_OPA_COVER; + + if(font_p == NULL) { + LV_LOG_WARN("lv_draw_letter: font is NULL"); + return; + } + + lv_font_glyph_dsc_t g; + bool g_ret = lv_font_get_glyph_dsc(font_p, &g, letter, '\0'); + if(g_ret == false) { + /*Add warning if the dsc is not found + *but do not print warning for non printable ASCII chars (e.g. '\n')*/ + if(letter >= 0x20 && + letter != 0xf8ff && /*LV_SYMBOL_DUMMY*/ + letter != 0x200c) { /*ZERO WIDTH NON-JOINER*/ + LV_LOG_WARN("lv_draw_letter: glyph dsc. not found for U+%X", letter); + } + return; + } + + /*Don't draw anything if the character is empty. E.g. space*/ + if((g.box_h == 0) || (g.box_w == 0)) return; + + lv_point_t gpos; + gpos.x = pos_p->x + g.ofs_x; + gpos.y = pos_p->y + (dsc->font->line_height - dsc->font->base_line) - g.box_h - g.ofs_y; + + /*If the letter is completely out of mask don't draw it*/ + if(gpos.x + g.box_w < draw_ctx->clip_area->x1 || + gpos.x > draw_ctx->clip_area->x2 || + gpos.y + g.box_h < draw_ctx->clip_area->y1 || + gpos.y > draw_ctx->clip_area->y2) { + return; + } + + const uint8_t * map_p = lv_font_get_glyph_bitmap(font_p, letter); + if(map_p == NULL) { + LV_LOG_WARN("lv_draw_letter: character's bitmap not found"); + return; + } + + if(font_p->subpx) { +#if LV_DRAW_COMPLEX && LV_USE_FONT_SUBPX + draw_letter_subpx(pos_x, pos_y, &g, clip_area, map_p, color, opa, blend_mode); +#else + LV_LOG_WARN("Can't draw sub-pixel rendered letter because LV_USE_FONT_SUBPX == 0 in lv_conf.h"); +#endif + } + else { + draw_letter_normal(draw_ctx, dsc, &gpos, &g, map_p); + } +} + +#endif diff --git a/src/draw/renesas/lv_gpu_d2_ra6m3.c b/src/draw/renesas/lv_gpu_d2_ra6m3.c new file mode 100644 index 000000000..ba4c08425 --- /dev/null +++ b/src/draw/renesas/lv_gpu_d2_ra6m3.c @@ -0,0 +1,742 @@ +/** + * @file lv_gpu_d2_ra6m3.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_gpu_d2_ra6m3.h" +#include "../../core/lv_refr.h" +#include + +#if LV_USE_GPU_RA6M3_G2D + +#include LV_GPU_RA6M3_G2D_INCLUDE + +/********************* + * DEFINES + *********************/ +#define LOG_ERRORS +#ifdef LOG_ERRORS + #define STRINGIFY(x) #x + #define TOSTRING(x) STRINGIFY(x) + + #define ERROR_LIST_SIZE (4) + #define D2_EXEC(a) lv_port_gpu_log_error(a, __func__, __LINE__) +#else + /* here is error logging not enabled */ + #define D2_EXEC(a) a; +#endif + +/********************** + * TYPEDEFS + **********************/ +typedef struct { + d2_s32 error; + const char * func; + int line; +} log_error_entry; + +/********************** + * STATIC PROTOTYPES + **********************/ +#ifdef LOG_ERRORS + static void lv_port_gpu_log_error(d2_s32 status, const char * func, int line); +#endif +static void invalidate_cache(void); + +void lv_draw_gpu_letter(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t * dsc, const lv_point_t * pos_p, + uint32_t letter); + +/********************** + * STATIC VARIABLES + **********************/ +#ifdef LOG_ERRORS + static log_error_entry log_error_list[ERROR_LIST_SIZE]; + static int error_list_index; + static int error_count; +#endif + +static d2_device * _d2_handle; +static d2_renderbuffer * renderbuffer; + +static d2_s32 src_cf_val, dst_cf_val; +static lv_draw_img_dsc_t img_dsc; +static bool color_key_enabled, alpha_enabled, blend_enabled, colorize_enabled; + +/********************** + * STATIC FUNCTIONS + **********************/ +static d2_s32 lv_port_gpu_cf_lv_to_d2(lv_img_cf_t cf) +{ + d2_s32 d2_cf; + +#if (DLG_LVGL_CF == 1) + switch(cf & ~(1 << 5)) { +#else + switch(cf) { +#endif /* (DLG_LVGL_CF == 1) */ + case LV_IMG_CF_TRUE_COLOR: + d2_cf = d2_mode_rgb565; + break; + case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED: + d2_cf = d2_mode_rgb565; + break; + case LV_IMG_CF_ALPHA_1BIT: + d2_cf = d2_mode_alpha1; + break; + case LV_IMG_CF_ALPHA_2BIT: + d2_cf = d2_mode_alpha2; + break; + case LV_IMG_CF_ALPHA_4BIT: + d2_cf = d2_mode_alpha4; + break; + case LV_IMG_CF_ALPHA_8BIT: + d2_cf = d2_mode_alpha8; + break; + case LV_IMG_CF_INDEXED_1BIT: + d2_cf = d2_mode_i1 | d2_mode_clut; + break; + case LV_IMG_CF_INDEXED_2BIT: + d2_cf = d2_mode_i2 | d2_mode_clut; + break; + case LV_IMG_CF_INDEXED_4BIT: + d2_cf = d2_mode_i4 | d2_mode_clut; + break; + case LV_IMG_CF_INDEXED_8BIT: + d2_cf = d2_mode_i8 | d2_mode_clut; + break; +#if (DLG_LVGL_CF == 1) + case LV_IMG_CF_RGB565: + d2_cf = d2_mode_rgb565; + break; + case LV_IMG_CF_RGB888: + d2_cf = d2_mode_rgb888; + break; + case LV_IMG_CF_RGBA8888: + d2_cf = d2_mode_rgba8888; + break; +#endif /* DLG_LVGL_CF */ + default: + return -1; + } + +#if (DLG_LVGL_CF == 1) + return d2_cf | (cf & (1 << 5) ? d2_mode_rle : 0); +#else + return d2_cf; +#endif /* (DLG_LVGL_CF == 1) */ +} + +static bool lv_port_gpu_cf_fb_valid(d2_s32 cf) +{ + if((cf & (d2_mode_rle | d2_mode_clut)) || cf < 0) { + return false; + } + + switch(cf) { + case d2_mode_alpha8: + case d2_mode_rgb565: + case d2_mode_argb8888: + case d2_mode_argb4444: + case d2_mode_rgba8888: + case d2_mode_rgba4444: + return true; + default: + return false; + } +} + +static bool lv_port_gpu_cf_has_alpha(d2_s32 cf) +{ + switch(cf & ~(d2_mode_clut | d2_mode_rle)) { + case d2_mode_argb8888: + case d2_mode_rgba8888: + case d2_mode_argb4444: + case d2_mode_rgba4444: + case d2_mode_argb1555: + case d2_mode_rgba5551: + case d2_mode_ai44: + case d2_mode_i8: + case d2_mode_i4: + case d2_mode_i2: + case d2_mode_i1: + case d2_mode_alpha8: + case d2_mode_alpha4: + case d2_mode_alpha2: + case d2_mode_alpha1: + return true; + default: + return false; + } +} + +static bool lv_port_gpu_cf_is_alpha(d2_s32 cf) +{ + switch(cf & ~d2_mode_rle) { + case d2_mode_alpha8: + case d2_mode_alpha4: + case d2_mode_alpha2: + case d2_mode_alpha1: + return true; + default: + return false; + } +} + +static d2_color lv_port_gpu_color_lv_to_d2(lv_color_t color) +{ + uint8_t alpha, red, green, blue; + + alpha = 0xFF; + red = color.ch.red << 3 | color.ch.red >> 2; + green = color.ch.green << 2 | color.ch.green >> 4; + blue = color.ch.blue << 3 | color.ch.blue >> 2; + + return (alpha) << 24UL + | (red) << 16UL + | (green) << 8UL + | (blue) << 0UL; +} + +static void lv_port_gpu_get_recolor_consts(d2_color * cl, d2_color * ch) +{ + d2_color c = lv_port_gpu_color_lv_to_d2(img_dsc.recolor); + d2_alpha r, g, b, opa = img_dsc.recolor_opa > LV_OPA_MAX ? LV_OPA_COVER : img_dsc.recolor_opa; + + r = ((uint32_t)((uint8_t)(c >> 16UL)) * opa) / 255; + g = ((uint32_t)((uint8_t)(c >> 8UL)) * opa) / 255; + b = ((uint32_t)((uint8_t)(c >> 0UL)) * opa) / 255; + *cl = r << 16UL | g << 8UL | b << 0UL; + + r += 255 - opa; + g += 255 - opa; + b += 255 - opa; + *ch = r << 16UL | g << 8UL | b << 0UL; +} + +static int lv_port_gpu_handle_indexed_color(const lv_color_t ** src, const d2_color ** clut, d2_s32 cf) +{ + int clut_len = 0; + + if(cf & d2_mode_clut) { + /* Calculate CLUT length in entries */ + switch(cf & ~(d2_mode_clut | d2_mode_rle)) { + case d2_mode_i1: + clut_len = 2; + break; + case d2_mode_i2: + clut_len = 4; + break; + case d2_mode_i4: + clut_len = 16; + break; + case d2_mode_i8: + clut_len = 256; + break; + case d2_mode_ai44: + clut_len = 16; + break; + default: + return 0; + } + + *clut = (const d2_color *)*src; + *src = (const lv_color_t *)((const uint32_t *)*src + clut_len); + } + return clut_len; +} + +static int lv_port_gpu_cf_bpp(d2_s32 cf) +{ + switch(cf & ~(d2_mode_clut | d2_mode_rle)) { + case d2_mode_argb8888: + return 32; + case d2_mode_rgba8888: + return 32; + case d2_mode_rgb888: + return 32; + case d2_mode_argb4444: + return 16; + case d2_mode_rgba4444: + return 16; + case d2_mode_argb1555: + return 16; + case d2_mode_rgba5551: + return 16; + case d2_mode_rgb565: + return 16; + case d2_mode_ai44: + return 8; + case d2_mode_i8: + return 8; + case d2_mode_i4: + return 4; + case d2_mode_i2: + return 2; + case d2_mode_i1: + return 1; + case d2_mode_alpha8: + return 8; + case d2_mode_alpha4: + return 4; + case d2_mode_alpha2: + return 2; + case d2_mode_alpha1: + return 1; + default: + return 0; + } +} + +static d2_s32 lv_port_gpu_cf_get_default(void) +{ + return d2_mode_rgb565; +} + +static void lv_port_gpu_config_blit_clear(void) +{ + alpha_enabled = false; + color_key_enabled = false; + blend_enabled = true; + colorize_enabled = false; + + lv_draw_img_dsc_init(&img_dsc); + + src_cf_val = lv_port_gpu_cf_get_default(); + dst_cf_val = lv_port_gpu_cf_get_default(); +} + +void lv_port_gpu_init(void) +{ + lv_port_gpu_config_blit_clear(); +} + +static void lv_port_gpu_rotate_point(int * x, int * y, float cos_angle, float sin_angle, int pivot_x, int pivot_y) +{ + float fx, fy; + + *x -= pivot_x; + *y -= pivot_y; + + fx = ((float) * x) / 16.0f; + fy = ((float) * y) / 16.0f; + + *x = (int)(((fx * cos_angle) - (fy * sin_angle)) * 16.0f); + *y = (int)(((fx * sin_angle) + (fy * cos_angle)) * 16.0f); + + *x += pivot_x; + *y += pivot_y; +} + +void lv_draw_ra6m3_g2d_init(void) +{ + if(_d2_handle != NULL) { + return; + } + + _d2_handle = d2_opendevice(0); + + if(_d2_handle == NULL) + return; + + /* set blocksize for default displaylist */ + if(d2_setdlistblocksize(_d2_handle, 25) != D2_OK) { + LV_LOG_ERROR("Could NOT d2_setdlistblocksize\n"); + d2_closedevice(_d2_handle); + + return; + } + + /* bind the hardware */ + if(d2_inithw(_d2_handle, 0) != D2_OK) { + LV_LOG_ERROR("Could NOT d2_inithw\n"); + d2_closedevice(_d2_handle); + + return; + } + + renderbuffer = d2_newrenderbuffer(_d2_handle, 20, 20); + if(!renderbuffer) { + LV_LOG_ERROR("NO renderbuffer\n"); + d2_closedevice(_d2_handle); + + return; + } +} + +static void lv_port_gpu_hw_deinit(void) +{ + if(_d2_handle == NULL) + return; + + D2_EXEC(d2_freerenderbuffer(_d2_handle, renderbuffer)); + D2_EXEC(d2_closedevice(_d2_handle)); + + renderbuffer = NULL; + _d2_handle = NULL; +} + +void lv_port_gpu_flush(void) +{ + lv_port_gpu_hw_deinit(); +} + +static void lv_port_gpu_start_render(void) +{ + D2_EXEC(d2_selectrenderbuffer(_d2_handle, renderbuffer)); +} + +static void lv_port_gpu_complete_render(void) +{ + D2_EXEC(d2_flushframe(_d2_handle)); +} + +void lv_port_gpu_wait(lv_draw_ctx_t * draw_ctx) +{ + lv_port_gpu_complete_render(); + + lv_draw_sw_wait_for_finish(draw_ctx); +} + +static void lv_port_gpu_execute_render(void) +{ + if(_d2_handle) { + D2_EXEC(d2_executerenderbuffer(_d2_handle, renderbuffer, 0)); + } +} + +void lv_port_gpu_blit(int32_t x, int32_t y, lv_color_t * dst, const lv_area_t * fill_area) +{ + uint32_t ModeSrc; + + ModeSrc = d2_mode_rgb565; + + lv_coord_t dst_width, dst_hight; + dst_width = lv_area_get_width(fill_area); + dst_hight = lv_area_get_height(fill_area); + + d2_selectrenderbuffer(_d2_handle, renderbuffer); + + // Generate render operations + d2_framebuffer(_d2_handle, (uint16_t *)&fb_background[0], LV_HOR_RES_MAX, LV_HOR_RES_MAX, + MAX(fill_area->y2 + 1, 2), lv_port_gpu_cf_get_default()); + + d2_cliprect(_d2_handle, 0, 0, LV_HOR_RES_MAX - 1, fill_area->y2); + d2_setblitsrc(_d2_handle, (void *) dst, dst_width, dst_width, dst_hight, ModeSrc); + d2_blitcopy(_d2_handle, dst_width, dst_hight, 0, 0, D2_FIX4(dst_width), D2_FIX4(dst_hight), + D2_FIX4(fill_area->x1), D2_FIX4(fill_area->y1), 0); + + // Execute render operations + d2_executerenderbuffer(_d2_handle, renderbuffer, 0); +} + +void lv_port_gpu_fill(lv_color_t * dest_buf, const lv_area_t * fill_area, lv_coord_t dst_width, + lv_color_t color, lv_opa_t opa) +{ + invalidate_cache(); + + lv_port_gpu_start_render(); + + D2_EXEC(d2_framebuffer(_d2_handle, d1_maptovidmem(_d2_handle, dest_buf), MAX(dst_width, 2), MAX(dst_width, 2), + MAX(fill_area->y2 + 1, 2), lv_port_gpu_cf_get_default())); + + D2_EXEC(d2_cliprect(_d2_handle, 0, 0, dst_width - 1, fill_area->y2)); + D2_EXEC(d2_setalpha(_d2_handle, opa > LV_OPA_MAX ? 0xFF : opa)); + D2_EXEC(d2_setcolor(_d2_handle, 0, lv_port_gpu_color_lv_to_d2(color))); + D2_EXEC(d2_renderbox(_d2_handle, D2_FIX4(fill_area->x1), D2_FIX4(fill_area->y1), + D2_FIX4(lv_area_get_width(fill_area)), D2_FIX4(lv_area_get_height(fill_area)))); + + lv_port_gpu_execute_render(); +} + +bool lv_port_gpu_config_blit(const lv_draw_img_dsc_t * draw_dsc, lv_img_cf_t dst_cf, + lv_img_cf_t src_cf, bool alpha_en, bool color_key_en, bool blend_en, bool colorize_en) +{ + d2_s32 d2_src_cf, d2_dst_cf; + + if(blend_en && draw_dsc->blend_mode != LV_BLEND_MODE_NORMAL + && draw_dsc->blend_mode != LV_BLEND_MODE_ADDITIVE) { + return false; + } + + d2_src_cf = lv_port_gpu_cf_lv_to_d2(src_cf); + d2_dst_cf = lv_port_gpu_cf_lv_to_d2(dst_cf); + if(d2_src_cf < 0 || !lv_port_gpu_cf_fb_valid(d2_dst_cf)) { + return false; + } + src_cf_val = d2_src_cf; + dst_cf_val = d2_dst_cf; + + img_dsc = *draw_dsc; + + /* Disable alpha if alpha channel does not exist */ + alpha_enabled = lv_port_gpu_cf_has_alpha(src_cf_val) ? alpha_en : 0; + color_key_enabled = color_key_en; + blend_enabled = blend_en; + colorize_enabled = colorize_en | lv_port_gpu_cf_is_alpha(src_cf_val); + + return true; +} + +static void lv_port_gpu_blit_internal(const lv_area_t * dest_area, const lv_color_t * src_buf, + const lv_area_t * src_area, d2_u32 flags) +{ + const lv_area_t * img_area = src_area; + lv_area_t img_area_scaled; + lv_coord_t w, h, img_w, img_h; + d2_s32 pitch; + int bpp = lv_port_gpu_cf_bpp(src_cf_val); + + D2_EXEC(d2_cliprect(_d2_handle, dest_area->x1, dest_area->y1, dest_area->x2, dest_area->y2)); + + pitch = w = lv_area_get_width(src_area); + h = lv_area_get_height(src_area); + + if(img_dsc.zoom != LV_IMG_ZOOM_NONE) { + img_area_scaled.x1 = src_area->x1 + ((((int32_t)0 - img_dsc.pivot.x) * img_dsc.zoom) >> 8) + img_dsc.pivot.x; + img_area_scaled.x2 = src_area->x1 + ((((int32_t)w - img_dsc.pivot.x) * img_dsc.zoom) >> 8) + img_dsc.pivot.x; + img_area_scaled.y1 = src_area->y1 + ((((int32_t)0 - img_dsc.pivot.y) * img_dsc.zoom) >> 8) + img_dsc.pivot.y; + img_area_scaled.y2 = src_area->y1 + ((((int32_t)h - img_dsc.pivot.y) * img_dsc.zoom) >> 8) + img_dsc.pivot.y; + img_area = &img_area_scaled; + } + + img_w = lv_area_get_width(img_area); + img_h = lv_area_get_height(img_area); + + if(0 < bpp && bpp < 8) { + pitch = (w + (8 - bpp)) & (~(8 - bpp)); + } + + if(img_dsc.angle == 0) { + D2_EXEC(d2_setblitsrc(_d2_handle, (void *) src_buf, pitch, w, h, src_cf_val)); + + D2_EXEC(d2_blitcopy(_d2_handle, w, h, 0, 0, + D2_FIX4(img_w), D2_FIX4(img_h), D2_FIX4(img_area->x1), D2_FIX4(img_area->y1), flags)); + } + else { + int x, y, x1, y1, x2, y2, x3, y3, x4, y4, dxu, dxv, dyu, dyv, xx, xy, yx, yy; + int pivot_scaled_x, pivot_scaled_y; + int tex_offset = (flags & d2_bf_filter) ? -32767 : 0; + d2_u8 amode, cmode = d2_to_copy; + float angle = ((float)img_dsc.angle / 10) * M_PI / 180; + float cos_angle = cosf(angle); + float sin_angle = sinf(angle); + d2_u8 fillmode_backup; + + /* setup texture params */ + fillmode_backup = d2_getfillmode(_d2_handle); + D2_EXEC(d2_setfillmode(_d2_handle, d2_fm_texture)); + D2_EXEC(d2_settexture(_d2_handle, (void *) src_buf, pitch, w, h, src_cf_val)); + D2_EXEC(d2_settexturemode(_d2_handle, flags & (d2_bf_filter | d2_bf_wrap))); + amode = flags & d2_bf_usealpha ? d2_to_copy : d2_to_one; + cmode = flags & d2_bf_colorize2 ? d2_to_blend : d2_to_copy; + D2_EXEC(d2_settextureoperation(_d2_handle, amode, cmode, cmode, cmode)); + if(flags & d2_bf_colorize2) { + d2_color cl = d2_getcolor(_d2_handle, 0), ch = d2_getcolor(_d2_handle, 1); + D2_EXEC(d2_settexopparam(_d2_handle, d2_cc_red, (uint8_t)(cl >> 16UL), + (uint8_t)(ch >> 16UL))); + D2_EXEC(d2_settexopparam(_d2_handle, d2_cc_green, (uint8_t)(cl >> 8UL), + (uint8_t)(ch >> 8UL))); + D2_EXEC(d2_settexopparam(_d2_handle, d2_cc_blue, (uint8_t)(cl >> 0UL), + (uint8_t)(ch >> 0UL))); + } + + x = D2_FIX4(img_area->x1); + y = D2_FIX4(img_area->y1); + + /* define quad points */ + x1 = D2_FIX4(0); + y1 = D2_FIX4(0); + x2 = D2_FIX4(img_w); + y2 = D2_FIX4(0); + x3 = D2_FIX4(img_w); + y3 = D2_FIX4(img_h); + x4 = D2_FIX4(0); + y4 = D2_FIX4(img_h); + + /* rotate points for quad */ + pivot_scaled_x = (img_dsc.pivot.x * img_dsc.zoom) >> 4; + pivot_scaled_y = (img_dsc.pivot.y * img_dsc.zoom) >> 4; + + lv_port_gpu_rotate_point(&x1, &y1, cos_angle, sin_angle, pivot_scaled_x, pivot_scaled_y); + lv_port_gpu_rotate_point(&x2, &y2, cos_angle, sin_angle, pivot_scaled_x, pivot_scaled_y); + lv_port_gpu_rotate_point(&x3, &y3, cos_angle, sin_angle, pivot_scaled_x, pivot_scaled_y); + lv_port_gpu_rotate_point(&x4, &y4, cos_angle, sin_angle, pivot_scaled_x, pivot_scaled_y); + + /* compute texture increments */ + xx = (int)(cos_angle * 65536.0f); + xy = (int)(sin_angle * 65536.0f); + yx = (int)(-sin_angle * 65536.0f); + yy = (int)(cos_angle * 65536.0f); + dxu = ((D2_FIX16(w) / D2_FIX4(img_w)) * xx) >> 12; + dxv = ((D2_FIX16(w) / D2_FIX4(img_w)) * xy) >> 12; + dyu = ((D2_FIX16(h) / D2_FIX4(img_h)) * yx) >> 12; + dyv = ((D2_FIX16(h) / D2_FIX4(img_h)) * yy) >> 12; + + /* map texture exactly to rotated quad, so texel center is always (0/0) top-left */ + D2_EXEC(d2_settexelcenter(_d2_handle, 0, 0)); + D2_EXEC(d2_settexturemapping(_d2_handle, (d2_point)(x + x1), (d2_point)(y + y1), + tex_offset, tex_offset, dxu, dxv, dyu, dyv)); + + int minx = MAX(dest_area->x1, D2_INT4(x + MIN(x1, MIN(x2, MIN(x3, x4))))); + int maxx = MIN(dest_area->x2, D2_INT4(x + MAX(x1, MAX(x2, MAX(x3, x4))))); + int slice = (flags & d2_bf_filter) ? 6 : 8; + + /* Perform render operation in slices to acheive better performance */ + for(int posx = minx; posx < maxx; posx += slice) { + D2_EXEC(d2_cliprect(_d2_handle, posx, dest_area->y1, MIN(posx + slice - 1, maxx), dest_area->y2)); + D2_EXEC(d2_renderquad(_d2_handle, (d2_point)(x + x1), (d2_point)(y + y1), + (d2_point)(x + x2), (d2_point)(y + y2), + (d2_point)(x + x3), (d2_point)(y + y3), + (d2_point)(x + x4), (d2_point)(y + y4), 0)); + } + D2_EXEC(d2_setfillmode(_d2_handle, fillmode_backup)); + } +} + +void lv_port_ra_gpu_blit(lv_color_t * dst, const lv_area_t * dst_area, lv_coord_t dest_stride, + const lv_color_t * src, const lv_area_t * src_area, lv_opa_t opa) +{ + d2_u32 flags = 0; + const d2_color * clut = NULL; + int clut_len = 0; + + invalidate_cache(); + + clut_len = lv_port_gpu_handle_indexed_color(&src, &clut, src_cf_val); + + lv_port_gpu_start_render(); + + D2_EXEC(d2_framebuffer(_d2_handle, d1_maptovidmem(_d2_handle, dst), MAX(dest_stride, 2), + MAX(dst_area->x2 + 1, 2), MAX(dst_area->y2 + 1, 2), dst_cf_val)); + + flags |= alpha_enabled ? d2_bf_usealpha : 0; + + D2_EXEC(d2_setalpha(_d2_handle, opa > LV_OPA_MAX ? LV_OPA_COVER : opa)); + + if(clut) { + D2_EXEC(d2_writetexclut_direct(_d2_handle, clut, 0, clut_len)); + } + + flags |= color_key_enabled ? d2_bf_usealpha : 0; + flags |= (colorize_enabled || img_dsc.recolor_opa != LV_OPA_TRANSP) ? d2_bf_colorize2 : 0; + if(colorize_enabled) { + D2_EXEC(d2_setcolor(_d2_handle, 0, lv_port_gpu_color_lv_to_d2(img_dsc.recolor))); + D2_EXEC(d2_setcolor(_d2_handle, 1, lv_port_gpu_color_lv_to_d2(img_dsc.recolor))); + } + else if(img_dsc.recolor_opa != LV_OPA_TRANSP) { + d2_color cl = 0, ch = 0; + lv_port_gpu_get_recolor_consts(&cl, &ch); + D2_EXEC(d2_setcolor(_d2_handle, 0, cl)); + D2_EXEC(d2_setcolor(_d2_handle, 1, ch)); + } + + flags |= ((img_dsc.angle || img_dsc.zoom != LV_IMG_ZOOM_NONE) && img_dsc.antialias) ? d2_bf_filter : 0; + + if(blend_enabled) { + D2_EXEC(d2_setblendmode(_d2_handle, d2_bm_alpha, + img_dsc.blend_mode != LV_BLEND_MODE_NORMAL ? d2_bm_one : d2_bm_one_minus_alpha)); + D2_EXEC(d2_setalphablendmode(_d2_handle, d2_bm_one, d2_bm_one_minus_alpha)); + } + else { + D2_EXEC(d2_setblendmode(_d2_handle, d2_bm_one, d2_bm_zero)); + D2_EXEC(d2_setalphablendmode(_d2_handle, d2_bm_one, d2_bm_zero)); + } + + lv_port_gpu_blit_internal(dst_area, src, src_area, flags); + + lv_port_gpu_execute_render(); +} + +void lv_draw_ra6m3_2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc) +{ + lv_area_t blend_area; + if(!_lv_area_intersect(&blend_area, dsc->blend_area, draw_ctx->clip_area)) return; + + bool done = false; + + if(dsc->mask_buf == NULL && dsc->blend_mode == LV_BLEND_MODE_NORMAL && lv_area_get_size(&blend_area) > 100) { + lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area); + + lv_color_t * dest_buf = draw_ctx->buf; + + const lv_color_t * src_buf = dsc->src_buf; + if(src_buf) { + lv_draw_sw_blend_basic(draw_ctx, dsc); + + lv_area_t src_area; + src_area.x1 = blend_area.x1 - (dsc->blend_area->x1 - draw_ctx->buf_area->x1); + src_area.y1 = blend_area.y1 - (dsc->blend_area->y1 - draw_ctx->buf_area->y1); + src_area.x2 = src_area.x1 + lv_area_get_width(dsc->blend_area) - 1; + src_area.y2 = src_area.y1 + lv_area_get_height(dsc->blend_area) - 1; + + lv_port_ra_gpu_blit(dest_buf, &blend_area, dest_stride, src_buf, &src_area, dsc->opa); + done = true; + } + else if(dsc->opa >= LV_OPA_MAX) { + lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); + lv_port_gpu_fill(dest_buf, &blend_area, dest_stride, dsc->color, dsc->opa); + done = true; + } + } + + if(!done) lv_draw_sw_blend_basic(draw_ctx, dsc); +} + +static void lv_port_gpu_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc, + const lv_area_t * coords, const uint8_t * map_p, lv_img_cf_t color_format) +{ + /*TODO basic ARGB8888 image can be handles here*/ + + lv_draw_sw_img_decoded(draw_ctx, dsc, coords, map_p, color_format); +} + +void lv_draw_ra6m3_2d_ctx_init(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx) +{ + lv_draw_sw_init_ctx(drv, draw_ctx); + + lv_draw_ra6m3_dma2d_ctx_t * ra_2d_draw_ctx = (lv_draw_sw_ctx_t *)draw_ctx; + + ra_2d_draw_ctx->blend = lv_draw_ra6m3_2d_blend; + ra_2d_draw_ctx->base_draw.draw_img_decoded = lv_port_gpu_img_decoded; + ra_2d_draw_ctx->base_draw.wait_for_finish = lv_port_gpu_wait; + ra_2d_draw_ctx->base_draw.draw_letter = lv_draw_gpu_letter; + //ra_2d_draw_ctx->base_draw.buffer_copy = lv_draw_ra6m3_2d_buffer_copy; +} + +void lv_draw_stm32_dma2d_ctx_deinit(lv_disp_t * disp, lv_draw_ctx_t * draw_ctx) +{ + LV_UNUSED(disp); + LV_UNUSED(draw_ctx); +} + +static void invalidate_cache(void) +{ + lv_disp_t * disp = _lv_refr_get_disp_refreshing(); + if(disp->driver->clean_dcache_cb) disp->driver->clean_dcache_cb(disp->driver); +} + +#ifdef LOG_ERRORS +static void lv_port_gpu_log_error(d2_s32 status, const char * func, int line) +{ + if(status) { + log_error_list[error_list_index].error = status; + log_error_list[error_list_index].func = func; + log_error_list[error_list_index].line = line; + LV_LOG_ERROR("%s\r\n", d2_geterrorstring(_d2_handle)); + LV_LOG_ERROR("%d:\t%d - %s : %d\r\n", error_count, + log_error_list[error_list_index].error, + log_error_list[error_list_index].func, + log_error_list[error_list_index].line); + + error_count++; + error_list_index++; + if(error_list_index >= ERROR_LIST_SIZE) { + error_list_index = 0; + } + } +} +#endif +#endif /* LV_USE_GPU_RA6M3_G2D */ diff --git a/src/draw/renesas/lv_gpu_d2_ra6m3.h b/src/draw/renesas/lv_gpu_d2_ra6m3.h new file mode 100644 index 000000000..5d37ce45e --- /dev/null +++ b/src/draw/renesas/lv_gpu_d2_ra6m3.h @@ -0,0 +1,56 @@ +/** + * @file lv_gpu_d2_ra6m3.h + * + */ +#ifndef LV_GPU_D2_RA6M3_H +#define LV_GPU_D2_RA6M3_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../misc/lv_color.h" + +#if LV_USE_GPU_RA6M3_G2D +#include "../../core/lv_disp.h" +#include "../sw/lv_draw_sw.h" + +/********************** + * DEFINE + **********************/ +#define MIN(A, B) ((A) < (B) ? (A) : (B)) +#define MAX(A, B) ((A) > (B) ? (A) : (B)) +#define M_PI 3.1415926 + +/********************** + * TYPEDEFS + **********************/ +typedef lv_draw_sw_ctx_t lv_draw_ra6m3_dma2d_ctx_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ +void lv_draw_ra6m3_g2d_init(void); + +void lv_port_gpu_init(void); + +void lv_port_gpu_flush(void); + +void lv_port_gpu_blit(int32_t x, int32_t y, lv_color_t * dst, const lv_area_t * fill_area); + +void lv_draw_ra6m3_2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc); + +void lv_draw_ra6m3_2d_ctx_init(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx); + +void lv_draw_ra6m3_2d_ctx_deinit(lv_disp_drv_t * disp, lv_draw_ctx_t * draw_ctx); + +#endif /*LV_USE_GPU_GD32_IPA*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif diff --git a/src/hal/lv_hal_disp.c b/src/hal/lv_hal_disp.c index 10640a28a..0cebc3354 100644 --- a/src/hal/lv_hal_disp.c +++ b/src/hal/lv_hal_disp.c @@ -25,6 +25,7 @@ #include "../draw/arm2d/lv_gpu_arm2d.h" #include "../draw/nxp/vglite/lv_draw_vglite.h" #include "../draw/nxp/pxp/lv_draw_pxp.h" +#include "../draw/renesas/lv_gpu_d2_ra6m3.h" #if LV_USE_THEME_DEFAULT #include "../extra/themes/default/lv_theme_default.h" @@ -95,8 +96,11 @@ void lv_disp_drv_init(lv_disp_drv_t * driver) driver->dpi = LV_DPI_DEF; driver->color_chroma_key = LV_COLOR_CHROMA_KEY; - -#if LV_USE_GPU_STM32_DMA2D +#if LV_USE_GPU_RA6M3_G2D + driver->draw_ctx_init = lv_draw_ra6m3_2d_ctx_init; + driver->draw_ctx_deinit = lv_draw_ra6m3_2d_ctx_init; + driver->draw_ctx_size = sizeof(lv_draw_ra6m3_dma2d_ctx_t); +#elif LV_USE_GPU_STM32_DMA2D driver->draw_ctx_init = lv_draw_stm32_dma2d_ctx_init; driver->draw_ctx_deinit = lv_draw_stm32_dma2d_ctx_init; driver->draw_ctx_size = sizeof(lv_draw_stm32_dma2d_ctx_t); diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index 4cd3895f2..a625ba960 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -445,6 +445,26 @@ #endif #endif +/*Enable RA6M3 G2D GPU*/ +#ifndef LV_USE_GPU_RA6M3_G2D + #ifdef CONFIG_LV_USE_GPU_RA6M3_G2D + #define LV_USE_GPU_RA6M3_G2D CONFIG_LV_USE_GPU_RA6M3_G2D + #else + #define LV_USE_GPU_RA6M3_G2D 0 + #endif +#endif +#if LV_USE_GPU_RA6M3_G2D + /*include path of target processor + e.g. "hal_data.h"*/ + #ifndef LV_GPU_RA6M3_G2D_INCLUDE + #ifdef CONFIG_LV_GPU_RA6M3_G2D_INCLUDE + #define LV_GPU_RA6M3_G2D_INCLUDE CONFIG_LV_GPU_RA6M3_G2D_INCLUDE + #else + #define LV_GPU_RA6M3_G2D_INCLUDE "hal_data.h" + #endif + #endif +#endif + /*Use SWM341's DMA2D GPU*/ #ifndef LV_USE_GPU_SWM341_DMA2D #ifdef CONFIG_LV_USE_GPU_SWM341_DMA2D