ESP32 LVGL library from v8.3.7 to v8.3.8 (no functional change) (#19058)

* ESP32 LVGL library from v8.3.7 to v8.3.8 (no functional change)

* Update changelog
This commit is contained in:
s-hadinger 2023-07-06 22:03:05 +02:00 committed by GitHub
parent 57c4825ccd
commit d79c4a7cc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 1967 additions and 310 deletions

View File

@ -19,6 +19,7 @@ All notable changes to this project will be documented in this file.
### Changed
- Matter support for temperature in Fahrenheit (`SetOption8 1`) (#18987)
- Matter improve responsiveness
- ESP32 LVGL library from v8.3.7 to v8.3.8 (no functional change)
### Fixed
- Berry various fixes for Walrus Operator (#18982)

View File

@ -1,6 +1,6 @@
{
"name": "lvgl",
"version": "8.3.7",
"version": "8.3.8",
"keywords": "graphics, gui, embedded, tft, lvgl",
"description": "Graphics library to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint. It offers anti-aliasing, opacity, and animations using only one frame buffer.",
"repository": {

View File

@ -1,5 +1,5 @@
name=lvgl
version=8.3.7
version=8.3.8
author=kisvegabor
maintainer=kisvegabor,embeddedt,pete-pjb
sentence=Full-featured Graphics Library for Embedded Systems

View File

@ -1,6 +1,6 @@
/**
* @file lv_conf.h
* Configuration file for v8.3.7
* Configuration file for v8.3.8
*/
/*
@ -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

View File

@ -15,7 +15,7 @@ extern "C" {
***************************/
#define LVGL_VERSION_MAJOR 8
#define LVGL_VERSION_MINOR 3
#define LVGL_VERSION_PATCH 7
#define LVGL_VERSION_PATCH 8
#define LVGL_VERSION_INFO ""
/*********************

View File

@ -262,6 +262,7 @@ void lv_scr_load_anim(lv_obj_t * new_scr, lv_scr_load_anim_t anim_type, uint32_t
/*Shortcut for immediate load*/
if(time == 0 && delay == 0) {
scr_load_internal(new_scr);
if(auto_del) lv_obj_del(act_scr);
return;
}

View File

@ -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();

View File

@ -339,7 +339,7 @@
lv_color_t *rgb_tmp_buf = NULL; \
if(draw_dsc->recolor_opa > LV_OPA_MIN) { \
rgb_tmp_buf \
= lv_malloc(src_w * src_h * sizeof(lv_color_t)); \
= lv_mem_buf_get(src_w * src_h * sizeof(lv_color_t)); \
if (NULL == rgb_tmp_buf) { \
LV_LOG_WARN( \
"Failed to allocate memory for accelerating recolour, " \

View File

@ -198,11 +198,19 @@ lv_img_src_t lv_img_src_get_type(const void * src)
if(src == NULL) return img_src_type;
const uint8_t * u8_p = src;
/*The first byte shows the type of the image source*/
/*The first or fourth byte depending on platform endianess shows the type of the image source*/
#if LV_BIG_ENDIAN_SYSTEM
if(u8_p[3] >= 0x20 && u8_p[3] <= 0x7F) {
#else
if(u8_p[0] >= 0x20 && u8_p[0] <= 0x7F) {
#endif
img_src_type = LV_IMG_SRC_FILE; /*If it's an ASCII character then it's file name*/
}
#if LV_BIG_ENDIAN_SYSTEM
else if(u8_p[3] >= 0x80) {
#else
else if(u8_p[0] >= 0x80) {
#endif
img_src_type = LV_IMG_SRC_SYMBOL; /*Symbols begins after 0x7F*/
}
else {

View File

@ -59,10 +59,14 @@
static void lv_draw_pxp_wait_for_finish(lv_draw_ctx_t * draw_ctx);
static void lv_draw_pxp_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc);
static void lv_draw_pxp_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 cf);
static void lv_draw_pxp_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc);
static void lv_draw_pxp_buffer_copy(lv_draw_ctx_t * draw_ctx,
void * dest_buf, lv_coord_t dest_stride, const lv_area_t * dest_area,
void * src_buf, lv_coord_t src_stride, const lv_area_t * src_area);
/**********************
* STATIC VARIABLES
@ -84,6 +88,7 @@ void lv_draw_pxp_ctx_init(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx)
pxp_draw_ctx->base_draw.draw_img_decoded = lv_draw_pxp_img_decoded;
pxp_draw_ctx->blend = lv_draw_pxp_blend;
pxp_draw_ctx->base_draw.wait_for_finish = lv_draw_pxp_wait_for_finish;
pxp_draw_ctx->base_draw.buffer_copy = lv_draw_pxp_buffer_copy;
}
void lv_draw_pxp_ctx_deinit(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx)
@ -184,22 +189,28 @@ static void lv_draw_pxp_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_
return;
}
lv_area_t blend_area;
/*Let's get the blend area which is the intersection of the area to draw and the clip area.*/
if(!_lv_area_intersect(&blend_area, coords, draw_ctx->clip_area))
return; /*Fully clipped, nothing to do*/
lv_area_t rel_coords;
lv_area_copy(&rel_coords, coords);
lv_area_move(&rel_coords, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
/*Make the blend area relative to the buffer*/
lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
lv_area_t rel_clip_area;
lv_area_copy(&rel_clip_area, draw_ctx->clip_area);
lv_area_move(&rel_clip_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
lv_coord_t src_width = lv_area_get_width(coords);
lv_coord_t src_height = lv_area_get_height(coords);
bool has_mask = lv_draw_mask_is_any(&blend_area);
bool has_scale = (dsc->zoom != LV_IMG_ZOOM_NONE);
bool has_rotation = (dsc->angle != 0);
bool unsup_rotation = false;
lv_area_t blend_area;
if(has_rotation)
lv_area_copy(&blend_area, &rel_coords);
else if(!_lv_area_intersect(&blend_area, &rel_coords, &rel_clip_area))
return; /*Fully clipped, nothing to do*/
bool has_mask = lv_draw_mask_is_any(&blend_area);
lv_coord_t src_width = lv_area_get_width(coords);
lv_coord_t src_height = lv_area_get_height(coords);
if(has_rotation) {
/*
* PXP can only rotate at 90x angles.
@ -247,4 +258,18 @@ static void lv_draw_pxp_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_
dsc, cf);
}
static void lv_draw_pxp_buffer_copy(lv_draw_ctx_t * draw_ctx,
void * dest_buf, lv_coord_t dest_stride, const lv_area_t * dest_area,
void * src_buf, lv_coord_t src_stride, const lv_area_t * src_area)
{
LV_UNUSED(draw_ctx);
if(lv_area_get_size(dest_area) < LV_GPU_NXP_PXP_SIZE_LIMIT) {
lv_draw_sw_buffer_copy(draw_ctx, dest_buf, dest_stride, dest_area, src_buf, src_stride, src_area);
return;
}
lv_gpu_nxp_pxp_buffer_copy(dest_buf, dest_area, dest_stride, src_buf, src_area, src_stride);
}
#endif /*LV_USE_GPU_NXP_PXP*/

View File

@ -40,8 +40,6 @@
* DEFINES
*********************/
#define PXP_TEMP_BUF_SIZE LCD_WIDTH * LCD_HEIGHT * LCD_FB_BYTE_PER_PIXEL
#if LV_COLOR_16_SWAP
#error Color swap not implemented. Disable LV_COLOR_16_SWAP feature.
#endif
@ -50,10 +48,17 @@
#define PXP_OUT_PIXEL_FORMAT kPXP_OutputPixelFormatRGB565
#define PXP_AS_PIXEL_FORMAT kPXP_AsPixelFormatRGB565
#define PXP_PS_PIXEL_FORMAT kPXP_PsPixelFormatRGB565
#define PXP_TEMP_BUF_SIZE LCD_WIDTH * LCD_HEIGHT * 2U
#elif LV_COLOR_DEPTH == 32
#define PXP_OUT_PIXEL_FORMAT kPXP_OutputPixelFormatARGB8888
#define PXP_AS_PIXEL_FORMAT kPXP_AsPixelFormatARGB8888
#define PXP_PS_PIXEL_FORMAT kPXP_PsPixelFormatRGB888
#if (!(defined(FSL_FEATURE_PXP_HAS_NO_EXTEND_PIXEL_FORMAT) && FSL_FEATURE_PXP_HAS_NO_EXTEND_PIXEL_FORMAT)) && \
(!(defined(FSL_FEATURE_PXP_V3) && FSL_FEATURE_PXP_V3))
#define PXP_PS_PIXEL_FORMAT kPXP_PsPixelFormatARGB8888
#else
#define PXP_PS_PIXEL_FORMAT kPXP_PsPixelFormatRGB888
#endif
#define PXP_TEMP_BUF_SIZE LCD_WIDTH * LCD_HEIGHT * 4U
#elif
#error Only 16bit and 32bit color depth are supported. Set LV_COLOR_DEPTH to 16 or 32.
#endif
@ -100,7 +105,7 @@ static void lv_pxp_blit_opa(lv_color_t * dest_buf, const lv_area_t * dest_area,
* @param[in] dsc Image descriptor
* @param[in] cf Color format
*/
static void lv_pxp_blit_cover(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
static void lv_pxp_blit_cover(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride,
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf);
@ -286,7 +291,7 @@ void lv_gpu_nxp_pxp_blit(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_
lv_gpu_nxp_pxp_run();
}
void lv_gpu_nxp_pxp_blit_transform(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
void lv_gpu_nxp_pxp_blit_transform(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride,
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf)
{
@ -308,6 +313,33 @@ void lv_gpu_nxp_pxp_blit_transform(lv_color_t * dest_buf, const lv_area_t * dest
lv_pxp_blit_cf(dest_buf, dest_area, dest_stride, src_buf, src_area, src_stride, dsc, cf);
}
void lv_gpu_nxp_pxp_buffer_copy(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride)
{
lv_coord_t src_width = lv_area_get_width(src_area);
lv_coord_t src_height = lv_area_get_height(src_area);
lv_gpu_nxp_pxp_reset();
const pxp_pic_copy_config_t picCopyConfig = {
.srcPicBaseAddr = (uint32_t)src_buf,
.srcPitchBytes = src_stride * sizeof(lv_color_t),
.srcOffsetX = src_area->x1,
.srcOffsetY = src_area->y1,
.destPicBaseAddr = (uint32_t)dest_buf,
.destPitchBytes = dest_stride * sizeof(lv_color_t),
.destOffsetX = dest_area->x1,
.destOffsetY = dest_area->y1,
.width = src_width,
.height = src_height,
.pixelFormat = PXP_AS_PIXEL_FORMAT
};
PXP_StartPictureCopy(LV_GPU_NXP_PXP_ID, &picCopyConfig);
lv_gpu_nxp_pxp_wait();
}
/**********************
* STATIC FUNCTIONS
**********************/
@ -316,22 +348,25 @@ static void lv_pxp_blit_opa(lv_color_t * dest_buf, const lv_area_t * dest_area,
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf)
{
lv_coord_t temp_area_w = lv_area_get_width(dest_area);
lv_coord_t temp_area_h = lv_area_get_height(dest_area);
const lv_area_t temp_area = {
.x1 = 0,
.y1 = 0,
.x2 = temp_area_w - 1,
.y2 = temp_area_h - 1
};
lv_area_t temp_area;
lv_area_copy(&temp_area, dest_area);
lv_coord_t temp_stride = dest_stride;
lv_coord_t temp_w = lv_area_get_width(&temp_area);
lv_coord_t temp_h = lv_area_get_height(&temp_area);
/*Step 1: Transform with full opacity to temporary buffer*/
lv_pxp_blit_cover((lv_color_t *)temp_buf, &temp_area, temp_area_w, src_buf, src_area, src_stride, dsc, cf);
lv_pxp_blit_cover((lv_color_t *)temp_buf, &temp_area, temp_stride, src_buf, src_area, src_stride, dsc, cf);
/*Switch width and height if angle requires it*/
if(dsc->angle == 900 || dsc->angle == 2700) {
temp_area.x2 = temp_area.x1 + temp_h - 1;
temp_area.y2 = temp_area.y1 + temp_w - 1;
}
/*Step 2: Blit temporary result with required opacity to output*/
lv_pxp_blit_cf(dest_buf, dest_area, dest_stride, (lv_color_t *)temp_buf, &temp_area, temp_area_w, dsc, cf);
lv_pxp_blit_cf(dest_buf, &temp_area, dest_stride, (lv_color_t *)temp_buf, &temp_area, temp_stride, dsc, cf);
}
static void lv_pxp_blit_cover(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
static void lv_pxp_blit_cover(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride,
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf)
{
@ -343,28 +378,43 @@ static void lv_pxp_blit_cover(lv_color_t * dest_buf, const lv_area_t * dest_area
bool has_recolor = (dsc->recolor_opa != LV_OPA_TRANSP);
bool has_rotation = (dsc->angle != 0);
lv_point_t pivot = dsc->pivot;
lv_coord_t piv_offset_x;
lv_coord_t piv_offset_y;
lv_gpu_nxp_pxp_reset();
if(has_rotation) {
/*Convert rotation angle*/
/*Convert rotation angle and calculate offsets caused by pivot*/
pxp_rotate_degree_t pxp_angle;
switch(dsc->angle) {
case 0:
pxp_angle = kPXP_Rotate0;
piv_offset_x = 0;
piv_offset_y = 0;
break;
case 900:
piv_offset_x = pivot.x + pivot.y - dest_h;
piv_offset_y = pivot.y - pivot.x;
pxp_angle = kPXP_Rotate90;
break;
case 1800:
piv_offset_x = 2 * pivot.x - dest_w;
piv_offset_y = 2 * pivot.y - dest_h;
pxp_angle = kPXP_Rotate180;
break;
case 2700:
piv_offset_x = pivot.x - pivot.y;
piv_offset_y = pivot.x + pivot.y - dest_w;
pxp_angle = kPXP_Rotate270;
break;
default:
piv_offset_x = 0;
piv_offset_y = 0;
pxp_angle = kPXP_Rotate0;
}
PXP_SetRotateConfig(LV_GPU_NXP_PXP_ID, kPXP_RotateOutputBuffer, pxp_angle, kPXP_FlipDisable);
lv_area_move(dest_area, piv_offset_x, piv_offset_y);
}
/*AS buffer - source image*/

View File

@ -99,10 +99,24 @@ void lv_gpu_nxp_pxp_blit(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_
* @param[in] dsc Image descriptor
* @param[in] cf Color format
*/
void lv_gpu_nxp_pxp_blit_transform(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
void lv_gpu_nxp_pxp_blit_transform(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride,
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf);
/**
* BLock Image Transfer - copy rectangular image from src_buf to dst_buf, no transformation or blending.
*
*
* @param[in/out] dest_buf Destination buffer
* @param[in] dest_area Area with relative coordinates of destination buffer
* @param[in] dest_stride Stride of destination buffer in pixels
* @param[in] src_buf Source buffer
* @param[in] src_area Area with relative coordinates of source buffer
* @param[in] src_stride Stride of source buffer in pixels
*/
void lv_gpu_nxp_pxp_buffer_copy(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride);
/**********************
* MACROS
**********************/

View File

@ -149,7 +149,7 @@ void lv_gpu_nxp_pxp_wait(void);
#if LV_GPU_NXP_PXP_LOG_TRACES
#define PXP_LOG_TRACE(fmt, ...) \
do { \
LV_LOG_ERROR(fmt, ##__VA_ARGS__); \
LV_LOG(fmt, ##__VA_ARGS__); \
} while (0)
#else
#define PXP_LOG_TRACE(fmt, ...) \

View File

@ -69,6 +69,10 @@ static void lv_draw_vglite_wait_for_finish(lv_draw_ctx_t * draw_ctx);
static void lv_draw_vglite_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 cf);
static void lv_draw_vglite_buffer_copy(lv_draw_ctx_t * draw_ctx,
void * dest_buf, lv_coord_t dest_stride, const lv_area_t * dest_area,
void * src_buf, lv_coord_t src_stride, const lv_area_t * src_area);
static void lv_draw_vglite_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc);
static void lv_draw_vglite_line(lv_draw_ctx_t * draw_ctx, const lv_draw_line_dsc_t * dsc, const lv_point_t * point1,
@ -111,6 +115,7 @@ void lv_draw_vglite_ctx_init(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx)
vglite_draw_ctx->base_draw.draw_img_decoded = lv_draw_vglite_img_decoded;
vglite_draw_ctx->blend = lv_draw_vglite_blend;
vglite_draw_ctx->base_draw.wait_for_finish = lv_draw_vglite_wait_for_finish;
vglite_draw_ctx->base_draw.buffer_copy = lv_draw_vglite_buffer_copy;
}
void lv_draw_vglite_ctx_deinit(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx)
@ -166,11 +171,9 @@ static void lv_draw_vglite_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blen
}
lv_area_t blend_area;
/*Let's get the blend area which is the intersection of the area to draw and the clip area*/
if(!_lv_area_intersect(&blend_area, dsc->blend_area, draw_ctx->clip_area))
return; /*Fully clipped, nothing to do*/
/*Make the blend area relative to the buffer*/
lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
bool done = false;
@ -185,9 +188,6 @@ static void lv_draw_vglite_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blen
VG_LITE_LOG_TRACE("VG-Lite fill failed. Fallback.");
}
else {
lv_color_t * dest_buf = draw_ctx->buf;
lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area);
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);
@ -195,8 +195,15 @@ static void lv_draw_vglite_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blen
src_area.y2 = src_area.y1 + lv_area_get_height(dsc->blend_area) - 1;
lv_coord_t src_stride = lv_area_get_width(dsc->blend_area);
done = (lv_gpu_nxp_vglite_blit(dest_buf, &blend_area, dest_stride,
src_buf, &src_area, src_stride, dsc->opa) == LV_RES_OK);
#if VG_LITE_BLIT_SPLIT_ENABLED
lv_color_t * dest_buf = draw_ctx->buf;
lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area);
done = (lv_gpu_nxp_vglite_blit_split(dest_buf, &blend_area, dest_stride,
src_buf, &src_area, src_stride, dsc->opa) == LV_RES_OK);
#else
done = (lv_gpu_nxp_vglite_blit(&blend_area, src_buf, &src_area, src_stride, dsc->opa) == LV_RES_OK);
#endif
if(!done)
VG_LITE_LOG_TRACE("VG-Lite blit failed. Fallback.");
@ -224,13 +231,21 @@ static void lv_draw_vglite_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_i
return;
}
lv_area_t blend_area;
/*Let's get the blend area which is the intersection of the area to draw and the clip area*/
if(!_lv_area_intersect(&blend_area, coords, draw_ctx->clip_area))
return; /*Fully clipped, nothing to do*/
lv_area_t rel_coords;
lv_area_copy(&rel_coords, coords);
lv_area_move(&rel_coords, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
/*Make the blend area relative to the buffer*/
lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
lv_area_t rel_clip_area;
lv_area_copy(&rel_clip_area, draw_ctx->clip_area);
lv_area_move(&rel_clip_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
lv_area_t blend_area;
bool has_transform = dsc->angle != 0 || dsc->zoom != LV_IMG_ZOOM_NONE;
if(has_transform)
lv_area_copy(&blend_area, &rel_coords);
else if(!_lv_area_intersect(&blend_area, &rel_coords, &rel_clip_area))
return; /*Fully clipped, nothing to do*/
bool has_mask = lv_draw_mask_is_any(&blend_area);
bool has_recolor = (dsc->recolor_opa != LV_OPA_TRANSP);
@ -242,9 +257,6 @@ static void lv_draw_vglite_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_i
&& !lv_img_cf_has_alpha(cf)
#endif
) {
lv_color_t * dest_buf = draw_ctx->buf;
lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area);
lv_area_t src_area;
src_area.x1 = blend_area.x1 - (coords->x1 - draw_ctx->buf_area->x1);
src_area.y1 = blend_area.y1 - (coords->y1 - draw_ctx->buf_area->y1);
@ -252,17 +264,48 @@ static void lv_draw_vglite_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_i
src_area.y2 = src_area.y1 + lv_area_get_height(coords) - 1;
lv_coord_t src_stride = lv_area_get_width(coords);
done = (lv_gpu_nxp_vglite_blit_transform(dest_buf, &blend_area, dest_stride,
src_buf, &src_area, src_stride, dsc) == LV_RES_OK);
#if VG_LITE_BLIT_SPLIT_ENABLED
lv_color_t * dest_buf = draw_ctx->buf;
lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area);
if(has_transform)
/* VG-Lite blit split with transformation is not supported! */
done = false;
else
done = (lv_gpu_nxp_vglite_blit_split(dest_buf, &blend_area, dest_stride,
src_buf, &src_area, src_stride, dsc->opa) == LV_RES_OK);
#else
if(has_transform)
done = (lv_gpu_nxp_vglite_blit_transform(&blend_area, &rel_clip_area,
src_buf, &src_area, src_stride, dsc) == LV_RES_OK);
else
done = (lv_gpu_nxp_vglite_blit(&blend_area, src_buf, &src_area, src_stride, dsc->opa) == LV_RES_OK);
#endif
if(!done)
VG_LITE_LOG_TRACE("VG-Lite blit transform failed. Fallback.");
VG_LITE_LOG_TRACE("VG-Lite blit %sfailed. Fallback.", has_transform ? "transform " : "");
}
if(!done)
lv_draw_sw_img_decoded(draw_ctx, dsc, coords, map_p, cf);
}
static void lv_draw_vglite_buffer_copy(lv_draw_ctx_t * draw_ctx,
void * dest_buf, lv_coord_t dest_stride, const lv_area_t * dest_area,
void * src_buf, lv_coord_t src_stride, const lv_area_t * src_area)
{
bool done = false;
if(lv_area_get_size(dest_area) >= LV_GPU_NXP_VG_LITE_SIZE_LIMIT) {
done = lv_gpu_nxp_vglite_buffer_copy(dest_buf, dest_area, dest_stride, src_buf, src_area, src_stride);
if(!done)
VG_LITE_LOG_TRACE("VG-Lite buffer copy failed. Fallback.");
}
if(!done)
lv_draw_sw_buffer_copy(draw_ctx, dest_buf, dest_stride, dest_area, src_buf, src_stride, src_area);
}
static void lv_draw_vglite_line(lv_draw_ctx_t * draw_ctx, const lv_draw_line_dsc_t * dsc, const lv_point_t * point1,
const lv_point_t * point2)
{
@ -284,21 +327,19 @@ static void lv_draw_vglite_line(lv_draw_ctx_t * draw_ctx, const lv_draw_line_dsc
rel_clip_area.y1 = LV_MIN(point1->y, point2->y) - dsc->width / 2;
rel_clip_area.y2 = LV_MAX(point1->y, point2->y) + dsc->width / 2;
bool is_common;
is_common = _lv_area_intersect(&rel_clip_area, &rel_clip_area, draw_ctx->clip_area);
if(!is_common)
return;
lv_area_t clipped_coords;
if(!_lv_area_intersect(&clipped_coords, &rel_clip_area, draw_ctx->clip_area))
return; /*Fully clipped, nothing to do*/
/* Make coordinates relative to the draw buffer */
lv_area_move(&rel_clip_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
lv_point_t rel_point1 = { point1->x - draw_ctx->buf_area->x1, point1->y - draw_ctx->buf_area->y1 };
lv_point_t rel_point2 = { point2->x - draw_ctx->buf_area->x1, point2->y - draw_ctx->buf_area->y1 };
bool done = false;
bool mask_any = lv_draw_mask_is_any(&rel_clip_area);
bool has_mask = lv_draw_mask_is_any(&rel_clip_area);
if(!mask_any) {
if(!has_mask) {
done = (lv_gpu_nxp_vglite_draw_line(&rel_point1, &rel_point2, &rel_clip_area, dsc) == LV_RES_OK);
if(!done)
VG_LITE_LOG_TRACE("VG-Lite draw line failed. Fallback.");
@ -369,8 +410,6 @@ static lv_res_t lv_draw_vglite_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_d
rel_coords.x2 -= (dsc->border_side & LV_BORDER_SIDE_RIGHT) ? 1 : 0;
rel_coords.y2 -= (dsc->border_side & LV_BORDER_SIDE_BOTTOM) ? 1 : 0;
}
/* Make coordinates relative to draw buffer */
lv_area_move(&rel_coords, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
lv_area_t rel_clip_area;
@ -379,9 +418,9 @@ static lv_res_t lv_draw_vglite_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_d
lv_area_t clipped_coords;
if(!_lv_area_intersect(&clipped_coords, &rel_coords, &rel_clip_area))
return LV_RES_INV;
return LV_RES_OK; /*Fully clipped, nothing to do*/
bool mask_any = lv_draw_mask_is_any(&rel_coords);
bool has_mask = lv_draw_mask_is_any(&rel_coords);
lv_grad_dir_t grad_dir = dsc->bg_grad.dir;
lv_color_t bg_color = (grad_dir == (lv_grad_dir_t)LV_GRAD_DIR_NONE) ?
dsc->bg_color : dsc->bg_grad.stops[0].color;
@ -394,7 +433,7 @@ static lv_res_t lv_draw_vglite_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_d
*
* Complex case: gradient or radius but no mask.
*/
if(!mask_any && ((dsc->radius != 0) || (grad_dir != (lv_grad_dir_t)LV_GRAD_DIR_NONE))) {
if(!has_mask && ((dsc->radius != 0) || (grad_dir != (lv_grad_dir_t)LV_GRAD_DIR_NONE))) {
lv_res_t res = lv_gpu_nxp_vglite_draw_bg(&rel_coords, &rel_clip_area, dsc);
if(res != LV_RES_OK)
VG_LITE_LOG_TRACE("VG-Lite draw bg failed. Fallback.");
@ -426,13 +465,16 @@ static lv_res_t lv_draw_vglite_border(lv_draw_ctx_t * draw_ctx, const lv_draw_re
rel_coords.y1 = coords->y1 + ceil(border_width / 2.0f);
rel_coords.y2 = coords->y2 - floor(border_width / 2.0f);
/* Make coordinates relative to the draw buffer */
lv_area_move(&rel_coords, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
lv_area_t rel_clip_area;
lv_area_copy(&rel_clip_area, draw_ctx->clip_area);
lv_area_move(&rel_clip_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
lv_area_t clipped_coords;
if(!_lv_area_intersect(&clipped_coords, &rel_coords, &rel_clip_area))
return LV_RES_OK; /*Fully clipped, nothing to do*/
lv_res_t res = lv_gpu_nxp_vglite_draw_border_generic(&rel_coords, &rel_clip_area, dsc, true);
if(res != LV_RES_OK)
VG_LITE_LOG_TRACE("VG-Lite draw border failed. Fallback.");
@ -456,13 +498,16 @@ static lv_res_t lv_draw_vglite_outline(lv_draw_ctx_t * draw_ctx, const lv_draw_r
rel_coords.y1 = coords->y1 - outline_pad - floor(dsc->outline_width / 2.0f);
rel_coords.y2 = coords->y2 + outline_pad + ceil(dsc->outline_width / 2.0f);
/* Make coordinates relative to the draw buffer */
lv_area_move(&rel_coords, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
lv_area_t rel_clip_area;
lv_area_copy(&rel_clip_area, draw_ctx->clip_area);
lv_area_move(&rel_clip_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
lv_area_t clipped_coords;
if(!_lv_area_intersect(&clipped_coords, &rel_coords, &rel_clip_area))
return LV_RES_OK; /*Fully clipped, nothing to do*/
lv_res_t res = lv_gpu_nxp_vglite_draw_border_generic(&rel_coords, &rel_clip_area, dsc, false);
if(res != LV_RES_OK)
VG_LITE_LOG_TRACE("VG-Lite draw outline failed. Fallback.");
@ -488,17 +533,21 @@ static void lv_draw_vglite_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t
return;
}
/* Make coordinates relative to the draw buffer */
lv_point_t rel_center = {center->x - draw_ctx->buf_area->x1, center->y - draw_ctx->buf_area->y1};
lv_area_t rel_clip_area;
lv_area_copy(&rel_clip_area, draw_ctx->clip_area);
lv_area_move(&rel_clip_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
done = (lv_gpu_nxp_vglite_draw_arc(&rel_center, (int32_t)radius, (int32_t)start_angle, (int32_t)end_angle,
&rel_clip_area, dsc) == LV_RES_OK);
if(!done)
VG_LITE_LOG_TRACE("VG-Lite draw arc failed. Fallback.");
bool has_mask = lv_draw_mask_is_any(&rel_clip_area);
if(!has_mask) {
done = (lv_gpu_nxp_vglite_draw_arc(&rel_center, (int32_t)radius, (int32_t)start_angle, (int32_t)end_angle,
&rel_clip_area, dsc) == LV_RES_OK);
if(!done)
VG_LITE_LOG_TRACE("VG-Lite draw arc failed. Fallback.");
}
#endif/*LV_DRAW_COMPLEX*/
if(!done)

View File

@ -216,6 +216,8 @@ lv_res_t lv_gpu_nxp_vglite_draw_arc(const lv_point_t * center, int32_t radius, i
vg_lite_matrix_t matrix;
vg_lite_identity(&matrix);
lv_vglite_set_scissor(clip_area);
/*** Draw arc ***/
err = vg_lite_draw(vgbuf, &path, VG_LITE_FILL_NON_ZERO, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol);
VG_LITE_ERR_RETURN_INV(err, "Draw arc failed.");
@ -223,6 +225,8 @@ lv_res_t lv_gpu_nxp_vglite_draw_arc(const lv_point_t * center, int32_t radius, i
if(lv_vglite_run() != LV_RES_OK)
VG_LITE_RETURN_INV("Run failed.");
lv_vglite_disable_scissor();
err = vg_lite_clear_path(&path);
VG_LITE_ERR_RETURN_INV(err, "Clear path failed.");

View File

@ -35,6 +35,7 @@
#if LV_USE_GPU_NXP_VG_LITE
#include "lv_vglite_buf.h"
#include "lv_vglite_utils.h"
/*********************
* DEFINES
@ -43,21 +44,6 @@
/** Stride in px required by VG-Lite HW*/
#define LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX 16U
/**
* Enable BLIT quality degradation workaround for RT595,
* recommended for screen's dimension > 352 pixels.
*/
#define RT595_BLIT_WRKRND_ENABLED 1
/* Internal compound symbol */
#if (defined(CPU_MIMXRT595SFFOB) || defined(CPU_MIMXRT595SFFOB_cm33) || \
defined(CPU_MIMXRT595SFFOC) || defined(CPU_MIMXRT595SFFOC_cm33)) && \
RT595_BLIT_WRKRND_ENABLED
#define VG_LITE_BLIT_SPLIT_ENABLED 1
#else
#define VG_LITE_BLIT_SPLIT_ENABLED 0
#endif
#if VG_LITE_BLIT_SPLIT_ENABLED
/**
* BLIT split threshold - BLITs with width or height higher than this value will be done
@ -75,16 +61,15 @@
**********************/
/**
* Blit single image, with optional opacity.
* Blit image, with optional opacity.
*
* @param[in] dest_area Area with relative coordinates of destination buffer
* @param[in] src_area Source area with relative coordinates of source buffer
* @param[in] opa Opacity
*
* @retval LV_RES_OK Transfer complete
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
*/
static lv_res_t lv_vglite_blit_single(const lv_area_t * dest_area, const lv_area_t * src_area, lv_opa_t opa);
static lv_res_t lv_vglite_blit(const lv_area_t * src_area, lv_opa_t opa);
/**
* Check source memory and stride alignment.
@ -113,7 +98,6 @@ static inline void lv_vglite_set_translation_matrix(const lv_area_t * dest_area)
static inline void lv_vglite_set_transformation_matrix(const lv_area_t * dest_area, const lv_draw_img_dsc_t * dsc);
#if VG_LITE_BLIT_SPLIT_ENABLED
/**
* Move buffer pointer as close as possible to area, but with respect to alignment requirements. X-axis only.
*
@ -148,7 +132,7 @@ static void align_y(lv_area_t * area, lv_color_t ** buf, lv_coord_t stride);
static lv_res_t lv_vglite_blit_split(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride,
const lv_color_t * src_buf, lv_area_t * src_area, lv_coord_t src_stride,
lv_opa_t opa);
#endif
#endif /*VG_LITE_BLIT_SPLIT_ENABLED*/
/**********************
* STATIC VARIABLES
@ -223,17 +207,14 @@ lv_res_t lv_gpu_nxp_vglite_fill(const lv_area_t * dest_area, lv_color_t color, l
return LV_RES_OK;
}
lv_res_t lv_gpu_nxp_vglite_blit(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride,
const lv_color_t * src_buf, lv_area_t * src_area, lv_coord_t src_stride,
lv_opa_t opa)
#if VG_LITE_BLIT_SPLIT_ENABLED
lv_res_t lv_gpu_nxp_vglite_blit_split(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride,
const lv_color_t * src_buf, lv_area_t * src_area, lv_coord_t src_stride,
lv_opa_t opa)
{
/* Set vgmatrix. */
lv_vglite_set_translation_matrix(dest_area);
/* Set src_vgbuf structure. */
lv_vglite_set_src_buf(src_buf, src_area, src_stride);
#if VG_LITE_BLIT_SPLIT_ENABLED
lv_color_t * orig_dest_buf = dest_buf;
lv_res_t rv = lv_vglite_blit_split(dest_buf, dest_area, dest_stride, src_buf, src_area, src_stride, opa);
@ -242,45 +223,112 @@ lv_res_t lv_gpu_nxp_vglite_blit(lv_color_t * dest_buf, lv_area_t * dest_area, lv
lv_vglite_set_dest_buf_ptr(orig_dest_buf);
return rv;
}
#else
LV_UNUSED(dest_buf);
LV_UNUSED(dest_stride);
lv_res_t lv_gpu_nxp_vglite_blit(const lv_area_t * dest_area,
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
lv_opa_t opa)
{
if(check_src_alignment(src_buf, src_stride) != LV_RES_OK)
VG_LITE_RETURN_INV("Check src alignment failed.");
return lv_vglite_blit_single(dest_area, src_area, opa);
#endif
}
lv_res_t lv_gpu_nxp_vglite_blit_transform(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride,
const lv_color_t * src_buf, lv_area_t * src_area, lv_coord_t src_stride,
const lv_draw_img_dsc_t * dsc)
{
/* Set vgmatrix. */
lv_vglite_set_transformation_matrix(dest_area, dsc);
/* Set src_vgbuf structure. */
lv_vglite_set_src_buf(src_buf, src_area, src_stride);
#if VG_LITE_BLIT_SPLIT_ENABLED
lv_color_t * orig_dest_buf = dest_buf;
/* Set scissor. */
lv_vglite_set_scissor(dest_area);
lv_res_t rv = lv_vglite_blit_split(dest_buf, dest_area, dest_stride, src_buf, src_area, src_stride, dsc->opa);
/* Set vgmatrix. */
lv_vglite_set_translation_matrix(dest_area);
/* Restore the original dest_vgbuf memory address. */
lv_vglite_set_dest_buf_ptr(orig_dest_buf);
/* Start blit. */
lv_res_t rv = lv_vglite_blit(src_area, opa);
/* Disable scissor. */
lv_vglite_disable_scissor();
return rv;
#else
LV_UNUSED(dest_buf);
LV_UNUSED(dest_stride);
}
lv_res_t lv_gpu_nxp_vglite_blit_transform(const lv_area_t * dest_area, const lv_area_t * clip_area,
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
const lv_draw_img_dsc_t * dsc)
{
lv_res_t rv = LV_RES_INV;
if(check_src_alignment(src_buf, src_stride) != LV_RES_OK)
VG_LITE_RETURN_INV("Check src alignment failed.");
return lv_vglite_blit_single(dest_area, src_area, dsc->opa);
#endif
/* Set src_vgbuf structure. */
lv_vglite_set_src_buf(src_buf, src_area, src_stride);
/* Set scissor */
lv_vglite_set_scissor(clip_area);
/* Set vgmatrix. */
lv_vglite_set_transformation_matrix(dest_area, dsc);
/* Start blit. */
rv = lv_vglite_blit(src_area, dsc->opa);
/* Disable scissor. */
lv_vglite_disable_scissor();
return rv;
}
#endif /*VG_LITE_BLIT_SPLIT_ENABLED*/
lv_res_t lv_gpu_nxp_vglite_buffer_copy(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride)
{
vg_lite_error_t err = VG_LITE_SUCCESS;
if(check_src_alignment(src_buf, src_stride) != LV_RES_OK)
VG_LITE_RETURN_INV("Check src alignment failed.");
vg_lite_buffer_t src_vgbuf;
/* Set src_vgbuf structure. */
lv_vglite_set_buf(&src_vgbuf, src_buf, src_area, src_stride);
vg_lite_buffer_t dest_vgbuf;
/* Set dest_vgbuf structure. */
lv_vglite_set_buf(&dest_vgbuf, dest_buf, dest_area, dest_stride);
uint32_t rect[] = {
(uint32_t)src_area->x1, /* start x */
(uint32_t)src_area->y1, /* start y */
(uint32_t)lv_area_get_width(src_area), /* width */
(uint32_t)lv_area_get_height(src_area) /* height */
};
/* Set scissor. */
lv_vglite_set_scissor(dest_area);
/* Set vgmatrix. */
lv_vglite_set_translation_matrix(dest_area);
err = vg_lite_blit_rect(&dest_vgbuf, &src_vgbuf, rect, &vgmatrix,
VG_LITE_BLEND_NONE, 0xFFFFFFFFU, VG_LITE_FILTER_POINT);
if(err != VG_LITE_SUCCESS) {
LV_LOG_ERROR("Blit rectangle failed.");
/* Disable scissor. */
lv_vglite_disable_scissor();
return LV_RES_INV;
}
if(lv_vglite_run() != LV_RES_OK) {
LV_LOG_ERROR("Run failed.");
/* Disable scissor. */
lv_vglite_disable_scissor();
return LV_RES_INV;
}
/* Disable scissor. */
lv_vglite_disable_scissor();
return LV_RES_OK;
}
/**********************
@ -320,10 +368,17 @@ static lv_res_t lv_vglite_blit_split(lv_color_t * dest_buf, lv_area_t * dest_are
lv_vglite_set_dest_buf_ptr(dest_buf);
lv_vglite_set_src_buf_ptr(src_buf);
/* Set scissor */
lv_vglite_set_scissor(dest_area);
/* Set vgmatrix. */
lv_vglite_set_translation_matrix(dest_area);
rv = lv_vglite_blit_single(dest_area, src_area, opa);
/* Start blit. */
rv = lv_vglite_blit(src_area, opa);
/* Disable scissor. */
lv_vglite_disable_scissor();
VG_LITE_LOG_TRACE("Single "
"Area: ([%d,%d], [%d,%d]) -> ([%d,%d], [%d,%d]) | "
@ -426,14 +481,21 @@ static lv_res_t lv_vglite_blit_split(lv_color_t * dest_buf, lv_area_t * dest_are
if(check_src_alignment(tile_src_buf, src_stride) != LV_RES_OK)
VG_LITE_RETURN_INV("Check src alignment failed.");
/* Set vgmatrix. */
lv_vglite_set_translation_matrix(&tile_dest_area);
/* Set new dest_vgbuf and src_vgbuf memory addresses. */
lv_vglite_set_dest_buf_ptr(tile_dest_buf);
lv_vglite_set_src_buf_ptr(tile_src_buf);
rv = lv_vglite_blit_single(&tile_dest_area, &tile_src_area, opa);
/* Set scissor */
lv_vglite_set_scissor(&tile_dest_area);
/* Set vgmatrix. */
lv_vglite_set_translation_matrix(&tile_dest_area);
/* Start blit. */
rv = lv_vglite_blit(&tile_src_area, opa);
/* Disable scissor. */
lv_vglite_disable_scissor();
VG_LITE_LOG_TRACE("Tile [%d, %d] "
"Area: ([%d,%d], [%d,%d]) -> ([%d,%d], [%d,%d]) | "
@ -455,9 +517,9 @@ static lv_res_t lv_vglite_blit_split(lv_color_t * dest_buf, lv_area_t * dest_are
return rv;
}
#endif /* VG_LITE_BLIT_SPLIT_ENABLED */
#endif /*VG_LITE_BLIT_SPLIT_ENABLED*/
static lv_res_t lv_vglite_blit_single(const lv_area_t * dest_area, const lv_area_t * src_area, lv_opa_t opa)
static lv_res_t lv_vglite_blit(const lv_area_t * src_area, lv_opa_t opa)
{
vg_lite_error_t err = VG_LITE_SUCCESS;
vg_lite_buffer_t * dst_vgbuf = lv_vglite_get_dest_buf();
@ -489,30 +551,11 @@ static lv_res_t lv_vglite_blit_single(const lv_area_t * dest_area, const lv_area
src_vgbuf->transparency_mode = VG_LITE_IMAGE_TRANSPARENT;
}
bool scissoring = lv_area_get_width(dest_area) < lv_area_get_width(src_area) ||
lv_area_get_height(dest_area) < lv_area_get_height(src_area);
if(scissoring) {
vg_lite_enable_scissor();
vg_lite_set_scissor((int32_t)dest_area->x1, (int32_t)dest_area->y1,
(int32_t)lv_area_get_width(dest_area),
(int32_t)lv_area_get_height(dest_area));
}
err = vg_lite_blit_rect(dst_vgbuf, src_vgbuf, rect, &vgmatrix, blend, color, VG_LITE_FILTER_POINT);
if(err != VG_LITE_SUCCESS) {
if(scissoring)
vg_lite_disable_scissor();
VG_LITE_RETURN_INV("Blit rectangle failed.");
}
VG_LITE_ERR_RETURN_INV(err, "Blit rectangle failed.");
if(lv_vglite_run() != LV_RES_OK) {
if(scissoring)
vg_lite_disable_scissor();
if(lv_vglite_run() != LV_RES_OK)
VG_LITE_RETURN_INV("Run failed.");
}
if(scissoring)
vg_lite_disable_scissor();
return LV_RES_OK;
}
@ -546,16 +589,14 @@ static inline void lv_vglite_set_transformation_matrix(const lv_area_t * dest_ar
bool has_scale = (dsc->zoom != LV_IMG_ZOOM_NONE);
bool has_rotation = (dsc->angle != 0);
if(has_scale || has_rotation) {
vg_lite_translate(dsc->pivot.x, dsc->pivot.y, &vgmatrix);
if(has_rotation)
vg_lite_rotate(dsc->angle / 10.0f, &vgmatrix); /* angle is 1/10 degree */
if(has_scale) {
vg_lite_float_t scale = 1.0f * dsc->zoom / LV_IMG_ZOOM_NONE;
vg_lite_scale(scale, scale, &vgmatrix);
}
vg_lite_translate(0.0f - dsc->pivot.x, 0.0f - dsc->pivot.y, &vgmatrix);
vg_lite_translate(dsc->pivot.x, dsc->pivot.y, &vgmatrix);
if(has_rotation)
vg_lite_rotate(dsc->angle / 10.0f, &vgmatrix); /* angle is 1/10 degree */
if(has_scale) {
vg_lite_float_t scale = 1.0f * dsc->zoom / LV_IMG_ZOOM_NONE;
vg_lite_scale(scale, scale, &vgmatrix);
}
vg_lite_translate(0.0f - dsc->pivot.x, 0.0f - dsc->pivot.y, &vgmatrix);
}
#if VG_LITE_BLIT_SPLIT_ENABLED

View File

@ -47,6 +47,21 @@ extern "C" {
* DEFINES
*********************/
/**
* Enable BLIT quality degradation workaround for RT595,
* recommended for screen's dimension > 352 pixels.
*/
#define RT595_BLIT_WRKRND_ENABLED 1
/* Internal compound symbol */
#if (defined(CPU_MIMXRT595SFFOB) || defined(CPU_MIMXRT595SFFOB_cm33) || \
defined(CPU_MIMXRT595SFFOC) || defined(CPU_MIMXRT595SFFOC_cm33)) && \
RT595_BLIT_WRKRND_ENABLED
#define VG_LITE_BLIT_SPLIT_ENABLED 1
#else
#define VG_LITE_BLIT_SPLIT_ENABLED 0
#endif
/**********************
* TYPEDEFS
**********************/
@ -67,6 +82,7 @@ extern "C" {
*/
lv_res_t lv_gpu_nxp_vglite_fill(const lv_area_t * dest_area, lv_color_t color, lv_opa_t opa);
#if VG_LITE_BLIT_SPLIT_ENABLED
/**
* BLock Image Transfer - copy rectangular image from src_buf to dst_buf with effects.
* By default, image is copied directly, with optional opacity.
@ -82,17 +98,33 @@ lv_res_t lv_gpu_nxp_vglite_fill(const lv_area_t * dest_area, lv_color_t color, l
* @retval LV_RES_OK Transfer complete
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
*/
lv_res_t lv_gpu_nxp_vglite_blit(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride,
const lv_color_t * src_buf, lv_area_t * src_area, lv_coord_t src_stride,
lv_res_t lv_gpu_nxp_vglite_blit_split(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride,
const lv_color_t * src_buf, lv_area_t * src_area, lv_coord_t src_stride,
lv_opa_t opa);
#else
/**
* BLock Image Transfer - copy rectangular image from src_buf to dst_buf with effects.
* By default, image is copied directly, with optional opacity.
*
* @param[in] dest_stride Stride of destination buffer in pixels
* @param[in] src_buf Source buffer
* @param[in] src_area Source area with relative coordinates of source buffer
* @param[in] src_stride Stride of source buffer in pixels
* @param[in] opa Opacity
*
* @retval LV_RES_OK Transfer complete
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
*/
lv_res_t lv_gpu_nxp_vglite_blit(const lv_area_t * dest_area,
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
lv_opa_t opa);
/**
* BLock Image Transfer - copy rectangular image from src_buf to dst_buf with transformation.
* By default, image is copied directly, with optional opacity.
*
* @param[in/out] dest_buf Destination buffer
* @param[in] dest_area Area with relative coordinates of destination buffer
* @param[in] dest_stride Stride of destination buffer in pixels
* @param[in] clip_area Clip area with relative coordinates of destination buffer
* @param[in] src_buf Source buffer
* @param[in] src_area Source area with relative coordinates of source buffer
* @param[in] src_stride Stride of source buffer in pixels
@ -101,10 +133,28 @@ lv_res_t lv_gpu_nxp_vglite_blit(lv_color_t * dest_buf, lv_area_t * dest_area, lv
* @retval LV_RES_OK Transfer complete
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
*/
lv_res_t lv_gpu_nxp_vglite_blit_transform(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride,
const lv_color_t * src_buf, lv_area_t * src_area, lv_coord_t src_stride,
lv_res_t lv_gpu_nxp_vglite_blit_transform(const lv_area_t * dest_area, const lv_area_t * clip_area,
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
const lv_draw_img_dsc_t * dsc);
#endif /*VG_LITE_BLIT_SPLIT_ENABLED*/
/**
* BLock Image Transfer - simple copy of rectangular image from source to destination.
*
* @param[in] dest_buf Destination buffer
* @param[in] dest_area Area with relative coordinates of destination buffer
* @param[in] dest_stride Stride of destination buffer in pixels
* @param[in] src_buf Source buffer
* @param[in] src_area Source area with relative coordinates of source buffer
* @param[in] src_stride Stride of source buffer in pixels
*
* @retval LV_RES_OK Transfer complete
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
*/
lv_res_t lv_gpu_nxp_vglite_buffer_copy(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride);
/**********************
* MACROS
**********************/

View File

@ -119,12 +119,16 @@ lv_res_t lv_gpu_nxp_vglite_draw_line(const lv_point_t * point1, const lv_point_t
err = vg_lite_update_stroke(&path);
VG_LITE_ERR_RETURN_INV(err, "Update stroke failed.");
lv_vglite_set_scissor(clip_area);
err = vg_lite_draw(vgbuf, &path, VG_LITE_FILL_NON_ZERO, &matrix, vglite_blend_mode, vgcol);
VG_LITE_ERR_RETURN_INV(err, "Draw line failed.");
if(lv_vglite_run() != LV_RES_OK)
VG_LITE_RETURN_INV("Run failed.");
lv_vglite_disable_scissor();
err = vg_lite_clear_path(&path);
VG_LITE_ERR_RETURN_INV(err, "Clear path failed.");

View File

@ -166,6 +166,8 @@ lv_res_t lv_gpu_nxp_vglite_draw_bg(const lv_area_t * coords, const lv_area_t * c
if(lv_vglite_premult_and_swizzle(&vgcol, bg_col32, dsc->bg_opa, color_format) != LV_RES_OK)
VG_LITE_RETURN_INV("Premultiplication and swizzle failed.");
lv_vglite_set_scissor(clip_area);
/*** Draw rectangle ***/
if(dsc->bg_grad.dir == (lv_grad_dir_t)LV_GRAD_DIR_NONE) {
err = vg_lite_draw(vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol);
@ -178,6 +180,8 @@ lv_res_t lv_gpu_nxp_vglite_draw_bg(const lv_area_t * coords, const lv_area_t * c
if(lv_vglite_run() != LV_RES_OK)
VG_LITE_RETURN_INV("Run failed.");
lv_vglite_disable_scissor();
err = vg_lite_clear_path(&path);
VG_LITE_ERR_RETURN_INV(err, "Clear path failed.");
@ -263,12 +267,16 @@ lv_res_t lv_gpu_nxp_vglite_draw_border_generic(const lv_area_t * coords, const l
err = vg_lite_update_stroke(&path);
VG_LITE_ERR_RETURN_INV(err, "Update stroke failed.");
lv_vglite_set_scissor(clip_area);
err = vg_lite_draw(vgbuf, &path, VG_LITE_FILL_NON_ZERO, &matrix, vglite_blend_mode, vgcol);
VG_LITE_ERR_RETURN_INV(err, "Draw border failed.");
if(lv_vglite_run() != LV_RES_OK)
VG_LITE_RETURN_INV("Run failed.");
lv_vglite_disable_scissor();
err = vg_lite_clear_path(&path);
VG_LITE_ERR_RETURN_INV(err, "Clear path failed.");
@ -276,6 +284,10 @@ lv_res_t lv_gpu_nxp_vglite_draw_border_generic(const lv_area_t * coords, const l
}
/**********************
* STATIC FUNCTIONS
**********************/
static void lv_vglite_create_rect_path_data(int32_t * path_data, uint32_t * path_data_size,
lv_coord_t radius,
const lv_area_t * coords)
@ -444,8 +456,4 @@ static void lv_vglite_create_rect_path_data(int32_t * path_data, uint32_t * path
*path_data_size = pidx * sizeof(int32_t);
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /*LV_USE_GPU_NXP_VG_LITE*/

View File

@ -57,8 +57,6 @@
static inline void lv_vglite_set_dest_buf(const lv_color_t * buf, const lv_area_t * area, lv_coord_t stride);
static inline void lv_vglite_set_buf_ptr(vg_lite_buffer_t * vgbuf, const lv_color_t * buf);
static inline void lv_vglite_set_buf(vg_lite_buffer_t * vgbuf, const lv_color_t * buf,
const lv_area_t * area, lv_coord_t stride);
/**********************
* STATIC VARIABLES
@ -106,23 +104,8 @@ void lv_vglite_set_src_buf(const lv_color_t * buf, const lv_area_t * area, lv_co
lv_vglite_set_buf(&src_vgbuf, buf, area, stride);
}
/**********************
* STATIC FUNCTIONS
**********************/
static inline void lv_vglite_set_dest_buf(const lv_color_t * buf, const lv_area_t * area, lv_coord_t stride)
{
lv_vglite_set_buf(&dest_vgbuf, buf, area, stride);
}
static inline void lv_vglite_set_buf_ptr(vg_lite_buffer_t * vgbuf, const lv_color_t * buf)
{
vgbuf->memory = (void *)buf;
vgbuf->address = (uint32_t)vgbuf->memory;
}
static inline void lv_vglite_set_buf(vg_lite_buffer_t * vgbuf, const lv_color_t * buf,
const lv_area_t * area, lv_coord_t stride)
void lv_vglite_set_buf(vg_lite_buffer_t * vgbuf, const lv_color_t * buf,
const lv_area_t * area, lv_coord_t stride)
{
vgbuf->format = VG_LITE_PX_FMT;
vgbuf->tiled = VG_LITE_LINEAR;
@ -140,4 +123,19 @@ static inline void lv_vglite_set_buf(vg_lite_buffer_t * vgbuf, const lv_color_t
vgbuf->handle = NULL;
}
/**********************
* STATIC FUNCTIONS
**********************/
static inline void lv_vglite_set_dest_buf(const lv_color_t * buf, const lv_area_t * area, lv_coord_t stride)
{
lv_vglite_set_buf(&dest_vgbuf, buf, area, stride);
}
static inline void lv_vglite_set_buf_ptr(vg_lite_buffer_t * vgbuf, const lv_color_t * buf)
{
vgbuf->memory = (void *)buf;
vgbuf->address = (uint32_t)vgbuf->memory;
}
#endif /*LV_USE_GPU_NXP_VG_LITE*/

View File

@ -100,6 +100,17 @@ void lv_vglite_set_src_buf_ptr(const lv_color_t * buf);
*/
void lv_vglite_set_src_buf(const lv_color_t * buf, const lv_area_t * area, lv_coord_t stride);
/**
* Set vglite buffer.
*
* @param[in] vgbuf Address of the VGLite buffer object
* @param[in] buf Address of the memory for the VGLite buffer
* @param[in] area buffer area (for width and height)
* @param[in] stride buffer stride
*/
void lv_vglite_set_buf(vg_lite_buffer_t * vgbuf, const lv_color_t * buf,
const lv_area_t * area, lv_coord_t stride);
/**********************
* MACROS
**********************/

View File

@ -71,6 +71,23 @@ extern "C" {
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**
* Enable scissor and set the clipping box.
*
* @param[in] clip_area Clip area with relative coordinates of destination buffer
*/
static inline void lv_vglite_set_scissor(const lv_area_t * clip_area);
/**
* Disable scissor.
*/
static inline void lv_vglite_disable_scissor(void);
/**********************
* GLOBAL PROTOTYPES
**********************/
@ -157,6 +174,23 @@ lv_res_t lv_vglite_run(void);
}while(0)
#endif /*LV_GPU_NXP_VG_LITE_LOG_TRACES*/
/**********************
* STATIC FUNCTIONS
**********************/
static inline void lv_vglite_set_scissor(const lv_area_t * clip_area)
{
vg_lite_enable_scissor();
vg_lite_set_scissor((int32_t)clip_area->x1, (int32_t)clip_area->y1,
(int32_t)lv_area_get_width(clip_area),
(int32_t)lv_area_get_height(clip_area));
}
static inline void lv_vglite_disable_scissor(void)
{
vg_lite_disable_scissor();
}
#endif /*LV_USE_GPU_NXP_VG_LITE*/
#ifdef __cplusplus

View File

@ -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

View File

@ -0,0 +1,742 @@
/**
* @file lv_gpu_d2_ra6m3.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_gpu_d2_ra6m3.h"
#include "../../core/lv_refr.h"
#include <math.h>
#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 */

View File

@ -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

View File

@ -104,7 +104,9 @@ void lv_draw_sdl_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * ds
}
lv_coord_t w = lv_area_get_width(&draw_area), h = lv_area_get_height(&draw_area);
SDL_Texture * texture = lv_draw_sdl_composite_texture_obtain(ctx, LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_STREAM1, w, h);
bool texture_cached = false;
SDL_Texture * texture = lv_draw_sdl_composite_texture_obtain(ctx, LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_STREAM1, w, h,
&texture_cached);
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
dump_masks(texture, &draw_area, mask_ids, mask_ids_count, cap_ids[0] != LV_MASK_ID_INV ? cap_ids : NULL);
@ -135,6 +137,11 @@ void lv_draw_sdl_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * ds
SDL_SetTextureColorMod(texture, color.r, color.g, color.b);
SDL_SetTextureAlphaMod(texture, dsc->opa);
SDL_RenderCopy(ctx->renderer, texture, &srcrect, &dstrect);
if(!texture_cached) {
LV_LOG_WARN("Texture is not cached, this will impact performance.");
SDL_DestroyTexture(texture);
}
}
/**********************

View File

@ -86,7 +86,8 @@ bool lv_draw_sdl_composite_begin(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coor
LV_ASSERT(internals->mask == NULL && internals->composition == NULL && internals->target_backup == NULL);
lv_coord_t w = lv_area_get_width(apply_area), h = lv_area_get_height(apply_area);
internals->composition = lv_draw_sdl_composite_texture_obtain(ctx, LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_TARGET0, w, h);
internals->composition = lv_draw_sdl_composite_texture_obtain(ctx, LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_TARGET0, w, h,
&internals->composition_cached);
/* Don't need to worry about integral overflow */
lv_coord_t ofs_x = (lv_coord_t) - apply_area->x1, ofs_y = (lv_coord_t) - apply_area->y1;
/* Offset draw area to start with (0,0) of coords */
@ -174,19 +175,23 @@ void lv_draw_sdl_composite_end(lv_draw_sdl_ctx_t * ctx, const lv_area_t * apply_
break;
}
SDL_RenderCopy(ctx->renderer, internals->composition, &src_rect, &dst_rect);
if(!internals->composition_cached) {
LV_LOG_WARN("Texture is not cached, this will impact performance.");
SDL_DestroyTexture(internals->composition);
}
}
internals->mask = internals->composition = internals->target_backup = NULL;
}
SDL_Texture * lv_draw_sdl_composite_texture_obtain(lv_draw_sdl_ctx_t * ctx, lv_draw_sdl_composite_texture_id_t id,
lv_coord_t w, lv_coord_t h)
lv_coord_t w, lv_coord_t h, bool * texture_in_cache)
{
lv_point_t * tex_size = NULL;
composite_key_t mask_key = mask_key_create(id);
SDL_Texture * result = lv_draw_sdl_texture_cache_get_with_userdata(ctx, &mask_key, sizeof(composite_key_t), NULL,
(void **) &tex_size);
if(!result || tex_size->x < w || tex_size->y < h) {
if(result == NULL || tex_size->x < w || tex_size->y < h) {
lv_coord_t size = next_pow_of_2(LV_MAX(w, h));
int access = SDL_TEXTUREACCESS_STREAMING;
if(id >= LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_TRANSFORM0) {
@ -198,8 +203,19 @@ SDL_Texture * lv_draw_sdl_composite_texture_obtain(lv_draw_sdl_ctx_t * ctx, lv_d
result = SDL_CreateTexture(ctx->renderer, LV_DRAW_SDL_TEXTURE_FORMAT, access, size, size);
tex_size = lv_mem_alloc(sizeof(lv_point_t));
tex_size->x = tex_size->y = size;
lv_draw_sdl_texture_cache_put_advanced(ctx, &mask_key, sizeof(composite_key_t), result, tex_size, lv_mem_free, 0);
bool in_cache = lv_draw_sdl_texture_cache_put_advanced(ctx, &mask_key, sizeof(composite_key_t), result,
tex_size, lv_mem_free, 0);
if(!in_cache) {
lv_mem_free(tex_size);
}
if(texture_in_cache != NULL) {
*texture_in_cache = in_cache;
}
}
else if(texture_in_cache != NULL) {
*texture_in_cache = true;
}
return result;
}

View File

@ -45,6 +45,7 @@ typedef enum lv_draw_sdl_composite_texture_id_t {
/**
* Begin drawing with mask. Render target will be switched to a temporary texture,
* and drawing coordinates may get clipped or translated
* @param ctx Drawing context
* @param coords_in Original coordinates
* @param clip_in Original clip area
* @param extension Useful for shadows or outlines, can be NULL
@ -59,8 +60,18 @@ bool lv_draw_sdl_composite_begin(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coor
void lv_draw_sdl_composite_end(lv_draw_sdl_ctx_t * ctx, const lv_area_t * apply_area, lv_blend_mode_t blend_mode);
/**
*
* @param ctx Drawing context
* @param id Texture ID
* @param w Maximum width needed
* @param h Maximum height needed
* @param texture_in_cache output to query if the texture is in cache. If it's not in cache, you'll need to destroy it
* by yourself
* @return Obtained texture
*/
SDL_Texture * lv_draw_sdl_composite_texture_obtain(lv_draw_sdl_ctx_t * ctx, lv_draw_sdl_composite_texture_id_t id,
lv_coord_t w, lv_coord_t h);
lv_coord_t w, lv_coord_t h, bool * texture_in_cache);
/**********************
* MACROS

View File

@ -72,7 +72,8 @@ static void draw_img_rounded(lv_draw_sdl_ctx_t * ctx, SDL_Texture * texture, con
lv_coord_t radius);
static SDL_Texture * img_rounded_frag_obtain(lv_draw_sdl_ctx_t * ctx, SDL_Texture * texture,
const lv_draw_sdl_img_header_t * header, int w, int h, lv_coord_t radius);
const lv_draw_sdl_img_header_t * header, int w, int h, lv_coord_t radius,
bool * in_cache);
static lv_draw_img_rounded_key_t rounded_key_create(const SDL_Texture * texture, lv_coord_t w, lv_coord_t h,
lv_coord_t radius);
@ -106,11 +107,16 @@ lv_res_t lv_draw_sdl_img_core(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t
lv_draw_sdl_img_header_t * header = NULL;
SDL_Texture * texture = lv_draw_sdl_texture_cache_get_with_userdata(ctx, key, key_size, &texture_found,
(void **) &header);
bool texture_in_cache = false;
if(!texture_found) {
lv_draw_sdl_img_load_texture(ctx, key, key_size, src, draw_dsc->frame_id, &texture, &header);
lv_draw_sdl_img_load_texture(ctx, key, key_size, src, draw_dsc->frame_id, &texture, &header,
&texture_in_cache);
}
else {
texture_in_cache = true;
}
SDL_free(key);
if(!texture) {
if(!texture || !header) {
return LV_RES_INV;
}
@ -148,6 +154,14 @@ lv_res_t lv_draw_sdl_img_core(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t
lv_draw_sdl_composite_end(ctx, &apply_area, draw_dsc->blend_mode);
if(!texture_in_cache) {
LV_LOG_WARN("Texture is not cached, this will impact performance.");
if(!header->managed) {
SDL_DestroyTexture(texture);
}
lv_mem_free(header);
}
return LV_RES_OK;
}
@ -185,7 +199,7 @@ static void calc_draw_part(SDL_Texture * texture, const lv_draw_sdl_img_header_t
bool lv_draw_sdl_img_load_texture(lv_draw_sdl_ctx_t * ctx, lv_draw_sdl_cache_key_head_img_t * key, size_t key_size,
const void * src, int32_t frame_id, SDL_Texture ** texture,
lv_draw_sdl_img_header_t ** header)
lv_draw_sdl_img_header_t ** header, bool * texture_in_cache)
{
_lv_img_cache_entry_t * cdsc = _lv_img_cache_open(src, lv_color_white(), frame_id);
lv_draw_sdl_cache_flag_t tex_flags = 0;
@ -210,16 +224,18 @@ bool lv_draw_sdl_img_load_texture(lv_draw_sdl_ctx_t * ctx, lv_draw_sdl_cache_key
#endif
}
if(texture && cdsc) {
*header = SDL_malloc(sizeof(lv_draw_sdl_img_header_t));
*header = lv_mem_alloc(sizeof(lv_draw_sdl_img_header_t));
SDL_memcpy(&(*header)->base, &cdsc->dec_dsc.header, sizeof(lv_img_header_t));
(*header)->rect = rect;
lv_draw_sdl_texture_cache_put_advanced(ctx, key, key_size, *texture, *header, SDL_free, tex_flags);
(*header)->managed = (tex_flags & LV_DRAW_SDL_CACHE_FLAG_MANAGED) != 0;
*texture_in_cache = lv_draw_sdl_texture_cache_put_advanced(ctx, key, key_size, *texture, *header, SDL_free,
tex_flags);
return true;
}
else {
lv_draw_sdl_texture_cache_put(ctx, key, key_size, NULL);
*texture_in_cache = lv_draw_sdl_texture_cache_put(ctx, key, key_size, NULL);
return false;
}
return true;
}
/**********************
@ -320,7 +336,8 @@ static void draw_img_rounded(lv_draw_sdl_ctx_t * ctx, SDL_Texture * texture, con
{
const int w = lv_area_get_width(coords), h = lv_area_get_height(coords);
lv_coord_t real_radius = LV_MIN3(radius, w, h);
SDL_Texture * frag = img_rounded_frag_obtain(ctx, texture, header, w, h, real_radius);
bool frag_in_cache = false;
SDL_Texture * frag = img_rounded_frag_obtain(ctx, texture, header, w, h, real_radius, &frag_in_cache);
apply_recolor_opa(frag, draw_dsc);
lv_draw_sdl_rect_bg_frag_draw_corners(ctx, frag, real_radius, coords, clip, true);
@ -360,6 +377,11 @@ static void draw_img_rounded(lv_draw_sdl_ctx_t * ctx, SDL_Texture * texture, con
SDL_RenderCopy(ctx->renderer, texture, &src_rect, &dst_rect);
}
SDL_RenderSetClipRect(ctx->renderer, NULL);
if(!frag_in_cache) {
LV_LOG_WARN("Texture is not cached, this will impact performance.");
SDL_DestroyTexture(frag);
}
}
static void apply_recolor_opa(SDL_Texture * texture, const lv_draw_img_dsc_t * draw_dsc)
@ -377,15 +399,18 @@ static void apply_recolor_opa(SDL_Texture * texture, const lv_draw_img_dsc_t * d
}
static SDL_Texture * img_rounded_frag_obtain(lv_draw_sdl_ctx_t * ctx, SDL_Texture * texture,
const lv_draw_sdl_img_header_t * header, int w, int h, lv_coord_t radius)
const lv_draw_sdl_img_header_t * header, int w, int h, lv_coord_t radius,
bool * in_cache)
{
lv_draw_img_rounded_key_t key = rounded_key_create(texture, w, h, radius);
SDL_Texture * mask_frag = lv_draw_sdl_rect_bg_frag_obtain(ctx, radius);
bool mask_frag_in_cache = false;
SDL_Texture * mask_frag = lv_draw_sdl_rect_bg_frag_obtain(ctx, radius, &mask_frag_in_cache);
SDL_Texture * img_frag = lv_draw_sdl_texture_cache_get(ctx, &key, sizeof(key), NULL);
if(img_frag == NULL) {
const lv_coord_t full_frag_size = radius * 2 + 3;
img_frag = SDL_CreateTexture(ctx->renderer, LV_DRAW_SDL_TEXTURE_FORMAT, SDL_TEXTUREACCESS_TARGET,
full_frag_size, full_frag_size);
SDL_assert(img_frag);
SDL_SetTextureBlendMode(img_frag, SDL_BLENDMODE_BLEND);
SDL_Texture * old_target = SDL_GetRenderTarget(ctx->renderer);
SDL_SetRenderTarget(ctx->renderer, img_frag);
@ -395,7 +420,7 @@ static SDL_Texture * img_rounded_frag_obtain(lv_draw_sdl_ctx_t * ctx, SDL_Textur
SDL_RenderFillRect(ctx->renderer, NULL);
SDL_SetRenderDrawBlendMode(ctx->renderer, SDL_BLENDMODE_BLEND);
lv_area_t coords = {0, 0, w - 1, h - 1}, clip;
lv_area_t coords = {0, 0, w - 1, h - 1};
lv_area_t frag_coords = {0, 0, full_frag_size - 1, full_frag_size - 1};
lv_draw_sdl_rect_bg_frag_draw_corners(ctx, mask_frag, radius, &frag_coords, NULL, false);
@ -446,7 +471,14 @@ static SDL_Texture * img_rounded_frag_obtain(lv_draw_sdl_ctx_t * ctx, SDL_Textur
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
SDL_SetRenderTarget(ctx->renderer, old_target);
lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), img_frag);
*in_cache = lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), img_frag);
}
else {
*in_cache = true;
}
if(!mask_frag_in_cache) {
LV_LOG_WARN("Texture is not cached, this will impact performance.");
SDL_DestroyTexture(mask_frag);
}
return img_frag;
}

View File

@ -35,6 +35,7 @@ extern "C" {
typedef struct lv_draw_sdl_img_header_t {
lv_img_header_t base;
SDL_Rect rect;
bool managed;
} lv_draw_sdl_img_header_t;
/**********************
@ -56,9 +57,22 @@ typedef struct lv_draw_sdl_img_header_t {
/*=====================
* Other functions
*====================*/
/**
*
* @param ctx Drawing context
* @param key Texture cache key
* @param key_size Size of texture cache key
* @param src Image source pointer
* @param frame_id Frame ID for animated image
* @param texture Texture for render
* @param header Header also holds sdl image info
* @param texture_in_cache Whether the texture has been put in the cache. Please note for managed texture,
* this will be false too. So you'll need to check header.managed too.
* @return Whether the image has been loaded successfully
*/
bool lv_draw_sdl_img_load_texture(lv_draw_sdl_ctx_t * ctx, lv_draw_sdl_cache_key_head_img_t * key, size_t key_size,
const void * src, int32_t frame_id, SDL_Texture ** texture,
lv_draw_sdl_img_header_t ** header);
lv_draw_sdl_img_header_t ** header, bool * texture_in_cache);
/**********************
* MACROS
**********************/

View File

@ -54,7 +54,7 @@ static lv_font_glyph_key_t font_key_glyph_create(const lv_font_t * font_p, uint3
* GLOBAL FUNCTIONS
**********************/
void lv_draw_sdl_draw_letter(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t * dsc, const lv_point_t * pos_p,
void lv_draw_sdl_draw_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_area_t * clip_area = draw_ctx->clip_area;
@ -117,6 +117,7 @@ void lv_draw_sdl_draw_letter(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t
lv_font_glyph_key_t glyph_key = font_key_glyph_create(font_p, letter);
bool glyph_found = false;
SDL_Texture * texture = lv_draw_sdl_texture_cache_get(ctx, &glyph_key, sizeof(glyph_key), &glyph_found);
bool in_cache = false;
if(!glyph_found) {
if(g.resolved_font) {
font_p = g.resolved_font;
@ -128,7 +129,10 @@ void lv_draw_sdl_draw_letter(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t
texture = SDL_CreateTextureFromSurface(renderer, mask);
SDL_FreeSurface(mask);
lv_mem_free(buf);
lv_draw_sdl_texture_cache_put(ctx, &glyph_key, sizeof(glyph_key), texture);
in_cache = lv_draw_sdl_texture_cache_put(ctx, &glyph_key, sizeof(glyph_key), texture);
}
else {
in_cache = true;
}
if(!texture) {
return;
@ -142,6 +146,10 @@ void lv_draw_sdl_draw_letter(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t
/*If the letter is completely out of mask don't draw it*/
if(!_lv_area_intersect(&draw_area, &t_letter, &t_clip)) {
if(!in_cache) {
LV_LOG_WARN("Texture is not cached, this will impact performance.");
SDL_DestroyTexture(texture);
}
return;
}
SDL_Rect srcrect, dstrect;
@ -156,6 +164,11 @@ void lv_draw_sdl_draw_letter(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t
SDL_RenderCopy(renderer, texture, &srcrect, &dstrect);
lv_draw_sdl_composite_end(ctx, &apply_area, dsc->blend_mode);
if(!in_cache) {
LV_LOG_WARN("Texture is not cached, this will impact performance.");
SDL_DestroyTexture(texture);
}
}
/**********************

View File

@ -58,7 +58,8 @@ lv_draw_layer_ctx_t * lv_draw_sdl_layer_init(lv_draw_ctx_t * draw_ctx, lv_draw_l
enum lv_draw_sdl_composite_texture_id_t texture_id = LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_TRANSFORM0 +
ctx->internals->transform_count;
transform_ctx->target = lv_draw_sdl_composite_texture_obtain(ctx, texture_id, target_w, target_h);
transform_ctx->target = lv_draw_sdl_composite_texture_obtain(ctx, texture_id, target_w, target_h,
&transform_ctx->target_in_cache);
transform_ctx->target_rect.x = 0;
transform_ctx->target_rect.y = 0;
transform_ctx->target_rect.w = target_w;
@ -117,6 +118,11 @@ void lv_draw_sdl_layer_blend(lv_draw_ctx_t * draw_ctx, lv_draw_layer_ctx_t * lay
void lv_draw_sdl_layer_destroy(lv_draw_ctx_t * draw_ctx, lv_draw_layer_ctx_t * layer_ctx)
{
lv_draw_sdl_ctx_t * ctx = (lv_draw_sdl_ctx_t *) draw_ctx;
lv_draw_sdl_layer_ctx_t * transform_ctx = (lv_draw_sdl_layer_ctx_t *) layer_ctx;
if(!transform_ctx->target_in_cache && transform_ctx->target != NULL) {
LV_LOG_WARN("Texture is not cached, this will impact performance.");
SDL_DestroyTexture(transform_ctx->target);
}
ctx->internals->transform_count -= 1;
}

View File

@ -28,6 +28,7 @@ typedef struct _lv_draw_sdl_layer_ctx_t {
SDL_Texture * orig_target;
SDL_Texture * target;
SDL_Rect target_rect;
bool target_in_cache;
lv_draw_layer_flags_t flags;
} lv_draw_sdl_layer_ctx_t;
/**********************

View File

@ -53,7 +53,7 @@ static SDL_Texture * line_texture_create(lv_draw_sdl_ctx_t * sdl_ctx, const lv_d
* GLOBAL FUNCTIONS
**********************/
void lv_draw_sdl_draw_line(lv_draw_ctx_t * draw_ctx, const lv_draw_line_dsc_t * dsc, const lv_point_t * point1,
const lv_point_t * point2)
const lv_point_t * point2, bool * in_cache)
{
lv_draw_sdl_ctx_t * sdl_ctx = (lv_draw_sdl_ctx_t *) draw_ctx;
SDL_Renderer * renderer = sdl_ctx->renderer;
@ -68,7 +68,7 @@ void lv_draw_sdl_draw_line(lv_draw_ctx_t * draw_ctx, const lv_draw_line_dsc_t *
SDL_Texture * texture = lv_draw_sdl_texture_cache_get(sdl_ctx, &key, sizeof(key), NULL);
if(!texture) {
texture = line_texture_create(sdl_ctx, dsc, (lv_coord_t) length);
lv_draw_sdl_texture_cache_put(sdl_ctx, &key, sizeof(key), texture);
*in_cache = lv_draw_sdl_texture_cache_put(sdl_ctx, &key, sizeof(key), texture);
}
lv_area_t coords = {x1, y1, x2, y2};

View File

@ -77,7 +77,9 @@ void lv_draw_sdl_polygon(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dr
int16_t mask_id = lv_draw_mask_add(&polygon_param, NULL);
lv_coord_t w = lv_area_get_width(&draw_area), h = lv_area_get_height(&draw_area);
SDL_Texture * texture = lv_draw_sdl_composite_texture_obtain(ctx, LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_STREAM1, w, h);
bool texture_in_cache = false;
SDL_Texture * texture = lv_draw_sdl_composite_texture_obtain(ctx, LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_STREAM1, w, h,
&texture_in_cache);
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
dump_masks(texture, &draw_area);
@ -91,6 +93,10 @@ void lv_draw_sdl_polygon(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dr
SDL_SetTextureColorMod(texture, color.r, color.g, color.b);
SDL_SetTextureAlphaMod(texture, draw_dsc->bg_opa);
SDL_RenderCopy(ctx->renderer, texture, &srcrect, &dstrect);
if(!texture_in_cache) {
LV_LOG_WARN("Texture is not cached, this will impact performance.");
SDL_DestroyTexture(texture);
}
}
/**********************

View File

@ -35,6 +35,7 @@ typedef struct lv_draw_sdl_context_internals_t {
lv_lru_t * texture_cache;
SDL_Texture * mask;
SDL_Texture * composition;
bool composition_cached;
SDL_Texture * target_backup;
uint8_t transform_count;
} lv_draw_sdl_context_internals_t;

View File

@ -175,7 +175,7 @@ void lv_draw_sdl_draw_rect(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t *
lv_draw_sdl_composite_end(ctx, &apply_area, dsc->blend_mode);
}
SDL_Texture * lv_draw_sdl_rect_bg_frag_obtain(lv_draw_sdl_ctx_t * ctx, lv_coord_t radius)
SDL_Texture * lv_draw_sdl_rect_bg_frag_obtain(lv_draw_sdl_ctx_t * ctx, lv_coord_t radius, bool * in_cache)
{
lv_draw_rect_bg_key_t key = rect_bg_key_create(radius, radius);
SDL_Texture * texture = lv_draw_sdl_texture_cache_get(ctx, &key, sizeof(key), NULL);
@ -188,13 +188,16 @@ SDL_Texture * lv_draw_sdl_rect_bg_frag_obtain(lv_draw_sdl_ctx_t * ctx, lv_coord_
texture = lv_draw_sdl_mask_dump_texture(ctx->renderer, &coords_frag, &mask_id, 1);
SDL_assert(texture != NULL);
lv_draw_mask_remove_id(mask_id);
lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), texture);
*in_cache = lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), texture);
}
else {
*in_cache = true;
}
return texture;
}
SDL_Texture * lv_draw_sdl_rect_grad_frag_obtain(lv_draw_sdl_ctx_t * ctx, const lv_grad_dsc_t * grad, lv_coord_t w,
lv_coord_t h, lv_coord_t radius)
lv_coord_t h, lv_coord_t radius, bool * in_cache)
{
lv_draw_rect_grad_frag_key_t key = rect_grad_frag_key_create(grad, w, h, radius);
SDL_Texture * texture = lv_draw_sdl_texture_cache_get(ctx, &key, sizeof(key), NULL);
@ -240,12 +243,15 @@ SDL_Texture * lv_draw_sdl_rect_grad_frag_obtain(lv_draw_sdl_ctx_t * ctx, const l
draw_bg_grad_simple(ctx, &blend_coords, &draw_area, grad, true);
SDL_SetRenderTarget(ctx->renderer, target_backup);
lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), texture);
*in_cache = lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), texture);
}
else {
*in_cache = true;
}
return texture;
}
SDL_Texture * lv_draw_sdl_rect_grad_strip_obtain(lv_draw_sdl_ctx_t * ctx, const lv_grad_dsc_t * grad)
SDL_Texture * lv_draw_sdl_rect_grad_strip_obtain(lv_draw_sdl_ctx_t * ctx, const lv_grad_dsc_t * grad, bool * in_cache)
{
lv_draw_rect_grad_strip_key_t key = rect_grad_strip_key_create(grad);
SDL_Texture * texture = lv_draw_sdl_texture_cache_get(ctx, &key, sizeof(key), NULL);
@ -265,7 +271,10 @@ SDL_Texture * lv_draw_sdl_rect_grad_strip_obtain(lv_draw_sdl_ctx_t * ctx, const
texture = SDL_CreateTextureFromSurface(ctx->renderer, surface);
SDL_assert(texture != NULL);
SDL_FreeSurface(surface);
lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), texture);
*in_cache = lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), texture);
}
else {
*in_cache = true;
}
return texture;
}
@ -388,7 +397,8 @@ static void draw_bg_color(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, con
/*A small texture with a quarter of the rect is enough*/
lv_coord_t bg_w = lv_area_get_width(coords), bg_h = lv_area_get_height(coords);
lv_coord_t real_radius = LV_MIN3(bg_w / 2, bg_h / 2, radius);
SDL_Texture * texture = lv_draw_sdl_rect_bg_frag_obtain(ctx, real_radius);
bool texture_in_cache = false;
SDL_Texture * texture = lv_draw_sdl_rect_bg_frag_obtain(ctx, real_radius, &texture_in_cache);
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
SDL_SetTextureAlphaMod(texture, dsc->bg_opa);
@ -396,6 +406,11 @@ static void draw_bg_color(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, con
lv_draw_sdl_rect_bg_frag_draw_corners(ctx, texture, real_radius, coords, draw_area, false);
frag_render_borders(ctx->renderer, texture, real_radius, coords, draw_area, false);
frag_render_center(ctx->renderer, texture, real_radius, coords, draw_area, false);
if(!texture_in_cache) {
LV_LOG_WARN("Texture is not cached, this will impact performance.");
SDL_DestroyTexture(texture);
}
}
static void draw_bg_grad_simple(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const lv_area_t * draw_area,
@ -427,7 +442,8 @@ static void draw_bg_grad_simple(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coord
}
}
SDL_Texture * grad_texture = lv_draw_sdl_rect_grad_strip_obtain(ctx, grad);
bool grad_texture_in_cache = false;
SDL_Texture * grad_texture = lv_draw_sdl_rect_grad_strip_obtain(ctx, grad, &grad_texture_in_cache);
if(blend_mod) {
SDL_SetTextureBlendMode(grad_texture, SDL_BLENDMODE_MOD);
}
@ -436,6 +452,11 @@ static void draw_bg_grad_simple(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coord
}
SDL_RenderCopy(ctx->renderer, grad_texture, &srcrect, &dstrect);
if(!grad_texture_in_cache) {
LV_LOG_WARN("Texture is not cached, this will impact performance.");
SDL_DestroyTexture(grad_texture);
}
}
static void draw_bg_grad_radius(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const lv_area_t * draw_area,
@ -445,7 +466,9 @@ static void draw_bg_grad_radius(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coord
/*A small texture with a quarter of the rect is enough*/
lv_coord_t bg_w = lv_area_get_width(coords), bg_h = lv_area_get_height(coords);
lv_coord_t real_radius = LV_MIN3(bg_w / 2, bg_h / 2, radius);
SDL_Texture * grad_texture = lv_draw_sdl_rect_grad_frag_obtain(ctx, &dsc->bg_grad, bg_w, bg_h, radius);
bool grad_texture_in_cache = false;
SDL_Texture * grad_texture = lv_draw_sdl_rect_grad_frag_obtain(ctx, &dsc->bg_grad, bg_w, bg_h, radius,
&grad_texture_in_cache);
SDL_SetTextureBlendMode(grad_texture, SDL_BLENDMODE_BLEND);
lv_draw_sdl_rect_bg_frag_draw_corners(ctx, grad_texture, real_radius, coords, draw_area, true);
@ -497,6 +520,11 @@ static void draw_bg_grad_radius(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coord
_lv_area_intersect(&part_area, &part_coords, draw_area);
draw_bg_grad_simple(ctx, coords, &part_area, &dsc->bg_grad, false);
}
if(!grad_texture_in_cache) {
LV_LOG_WARN("Texture is not cached, this will impact performance.");
SDL_DestroyTexture(grad_texture);
}
}
static void draw_bg_img(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const lv_area_t * draw_area,
@ -632,6 +660,7 @@ static void draw_shadow(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const
lv_draw_rect_shadow_key_t key = rect_shadow_key_create(radius, frag_size, sw);
SDL_Texture * texture = lv_draw_sdl_texture_cache_get(ctx, &key, sizeof(key), NULL);
bool texture_in_cache = false;
if(texture == NULL) {
lv_area_t mask_area = {blur_growth, blur_growth}, mask_area_blurred = {0, 0};
lv_area_set_width(&mask_area, frag_size * 2);
@ -650,7 +679,10 @@ static void draw_shadow(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const
lv_mem_buf_release(mask_buf);
lv_draw_mask_remove_id(mask_id);
SDL_assert(texture);
lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), texture);
texture_in_cache = lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), texture);
}
else {
texture_in_cache = true;
}
SDL_Color shadow_color;
@ -662,6 +694,11 @@ static void draw_shadow(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const
lv_draw_sdl_rect_bg_frag_draw_corners(ctx, texture, blur_frag_size, &shadow_area, clip, false);
frag_render_borders(ctx->renderer, texture, blur_frag_size, &shadow_area, clip, false);
frag_render_center(ctx->renderer, texture, blur_frag_size, &shadow_area, clip, false);
if(!texture_in_cache) {
LV_LOG_WARN("Texture is not cached, this will impact performance.");
SDL_DestroyTexture(texture);
}
}
@ -743,6 +780,7 @@ static void draw_border_generic(lv_draw_sdl_ctx_t * ctx, const lv_area_t * outer
lv_coord_t max_side = LV_MAX4(key.offsets.x1, key.offsets.y1, -key.offsets.x2, -key.offsets.y2);
lv_coord_t frag_size = LV_MAX(radius, max_side);
SDL_Texture * texture = lv_draw_sdl_texture_cache_get(ctx, &key, sizeof(key), NULL);
bool texture_in_cache;
if(texture == NULL) {
/* Create a mask texture with size of (frag_size * 2 + FRAG_SPACING) */
const lv_area_t frag_area = {0, 0, frag_size * 2 + FRAG_SPACING - 1, frag_size * 2 + FRAG_SPACING - 1};
@ -769,7 +807,10 @@ static void draw_border_generic(lv_draw_sdl_ctx_t * ctx, const lv_area_t * outer
lv_draw_mask_remove_id(mask_ids[1]);
lv_draw_mask_remove_id(mask_ids[0]);
SDL_assert(texture);
lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), texture);
texture_in_cache = lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), texture);
}
else {
texture_in_cache = true;
}
SDL_Rect outer_rect;
@ -783,6 +824,11 @@ static void draw_border_generic(lv_draw_sdl_ctx_t * ctx, const lv_area_t * outer
lv_draw_sdl_rect_bg_frag_draw_corners(ctx, texture, frag_size, outer_area, clip, true);
frag_render_borders(renderer, texture, frag_size, outer_area, clip, true);
if(!texture_in_cache) {
LV_LOG_WARN("Texture is not cached, this will impact performance.");
SDL_DestroyTexture(texture);
}
}
static void frag_render_borders(SDL_Renderer * renderer, SDL_Texture * frag, lv_coord_t frag_size,

View File

@ -57,12 +57,36 @@ typedef struct lv_draw_sdl_rect_header_t {
* Other functions
*====================*/
SDL_Texture * lv_draw_sdl_rect_bg_frag_obtain(lv_draw_sdl_ctx_t * ctx, lv_coord_t radius);
/**
*
* @param ctx Drawing context
* @param radius Corner radius of the rectangle
* @param in_cache Whether the texture has been put in the cache
* @return Background fragment texture
*/
SDL_Texture * lv_draw_sdl_rect_bg_frag_obtain(lv_draw_sdl_ctx_t * ctx, lv_coord_t radius, bool * in_cache);
/**
*
* @param ctx Drawing context
* @param grad Gradient info
* @param w Width of the rectangle
* @param h Height of the rectangle
* @param radius Corner radius of the rectangle
* @param in_cache Whether the texture has been put in the cache
* @return Gradient fragment texture
*/
SDL_Texture * lv_draw_sdl_rect_grad_frag_obtain(lv_draw_sdl_ctx_t * ctx, const lv_grad_dsc_t * grad, lv_coord_t w,
lv_coord_t h, lv_coord_t radius);
lv_coord_t h, lv_coord_t radius, bool * in_cache);
SDL_Texture * lv_draw_sdl_rect_grad_strip_obtain(lv_draw_sdl_ctx_t * ctx, const lv_grad_dsc_t * grad);
/**
*
* @param ctx Drawing context
* @param grad Gradient info
* @param in_cache Whether the texture has been put in the cache
* @return Gradient strip texture
*/
SDL_Texture * lv_draw_sdl_rect_grad_strip_obtain(lv_draw_sdl_ctx_t * ctx, const lv_grad_dsc_t * grad, bool * in_cache);
void lv_draw_sdl_rect_bg_frag_draw_corners(lv_draw_sdl_ctx_t * ctx, SDL_Texture * frag, lv_coord_t frag_size,
const lv_area_t * coords, const lv_area_t * clip, bool full);

View File

@ -81,12 +81,12 @@ SDL_Texture * lv_draw_sdl_texture_cache_get_with_userdata(lv_draw_sdl_ctx_t * ct
return value->texture;
}
void lv_draw_sdl_texture_cache_put(lv_draw_sdl_ctx_t * ctx, const void * key, size_t key_length, SDL_Texture * texture)
bool lv_draw_sdl_texture_cache_put(lv_draw_sdl_ctx_t * ctx, const void * key, size_t key_length, SDL_Texture * texture)
{
lv_draw_sdl_texture_cache_put_advanced(ctx, key, key_length, texture, NULL, NULL, 0);
return lv_draw_sdl_texture_cache_put_advanced(ctx, key, key_length, texture, NULL, NULL, 0);
}
void lv_draw_sdl_texture_cache_put_advanced(lv_draw_sdl_ctx_t * ctx, const void * key, size_t key_length,
bool lv_draw_sdl_texture_cache_put_advanced(lv_draw_sdl_ctx_t * ctx, const void * key, size_t key_length,
SDL_Texture * texture, void * userdata, void userdata_free(void *),
lv_draw_sdl_cache_flag_t flags)
{
@ -97,22 +97,20 @@ void lv_draw_sdl_texture_cache_put_advanced(lv_draw_sdl_ctx_t * ctx, const void
value->userdata_free = userdata_free;
value->flags = flags;
if(!texture) {
lv_lru_set(lru, key, key_length, value, 1);
return;
return lv_lru_set(lru, key, key_length, value, 1) == LV_LRU_OK;
}
if(flags & LV_DRAW_SDL_CACHE_FLAG_MANAGED) {
/* Managed texture doesn't count into cache size */
LV_LOG_INFO("cache texture %p", texture);
lv_lru_set(lru, key, key_length, value, 1);
return;
return lv_lru_set(lru, key, key_length, value, 1) == LV_LRU_OK;
}
Uint32 format;
int access, width, height;
if(SDL_QueryTexture(texture, &format, &access, &width, &height) != 0) {
return;
return false;
}
LV_LOG_INFO("cache texture %p, %d*%d@%dbpp", texture, width, height, SDL_BITSPERPIXEL(format));
lv_lru_set(lru, key, key_length, value, width * height * SDL_BITSPERPIXEL(format) / 8);
return lv_lru_set(lru, key, key_length, value, width * height * SDL_BITSPERPIXEL(format) / 8) == LV_LRU_OK;
}
lv_draw_sdl_cache_key_head_img_t * lv_draw_sdl_texture_img_key_create(const void * src, int32_t frame_id, size_t * size)

View File

@ -82,9 +82,15 @@ SDL_Texture * lv_draw_sdl_texture_cache_get(lv_draw_sdl_ctx_t * ctx, const void
SDL_Texture * lv_draw_sdl_texture_cache_get_with_userdata(lv_draw_sdl_ctx_t * ctx, const void * key, size_t key_length,
bool * found, void ** userdata);
void lv_draw_sdl_texture_cache_put(lv_draw_sdl_ctx_t * ctx, const void * key, size_t key_length, SDL_Texture * texture);
/**
* @return Whether the texture has been put in the cache
*/
bool lv_draw_sdl_texture_cache_put(lv_draw_sdl_ctx_t * ctx, const void * key, size_t key_length, SDL_Texture * texture);
void lv_draw_sdl_texture_cache_put_advanced(lv_draw_sdl_ctx_t * ctx, const void * key, size_t key_length,
/**
* @return Whether the texture has been put in the cache
*/
bool lv_draw_sdl_texture_cache_put_advanced(lv_draw_sdl_ctx_t * ctx, const void * key, size_t key_length,
SDL_Texture * texture, void * userdata, void userdata_free(void *),
lv_draw_sdl_cache_flag_t flags);

View File

@ -34,6 +34,41 @@
#error "Cannot use DMA2D with LV_COLOR_DEPTH other than 16 or 32"
#endif
/**********************
* STATIC PROTOTYPES
**********************/
static void lv_draw_stm32_dma2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc);
static void lv_draw_stm32_dma2d_buffer_copy(lv_draw_ctx_t * draw_ctx,
void * dest_buf, lv_coord_t dest_stride, const lv_area_t * dest_area,
void * src_buf, lv_coord_t src_stride, const lv_area_t * src_area);
static void lv_draw_stm32_dma2d_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * img_dsc,
const lv_area_t * coords, const uint8_t * src_buf, lv_img_cf_t color_format);
static dma2d_color_format_t lv_color_format_to_dma2d_color_format(lv_img_cf_t color_format);
static lv_point_t lv_area_get_offset(const lv_area_t * area1, const lv_area_t * area2);
LV_STM32_DMA2D_STATIC void lv_gpu_stm32_dma2d_wait_cb(lv_draw_ctx_t * draw_ctx);
LV_STM32_DMA2D_STATIC lv_res_t lv_draw_stm32_dma2d_img(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * img_dsc,
const lv_area_t * src_area, const void * src);
LV_STM32_DMA2D_STATIC void _lv_draw_stm32_dma2d_blend_fill(const lv_color_t * dst_buf, lv_coord_t dst_stride,
const lv_area_t * draw_area, lv_color_t color, lv_opa_t opa);
LV_STM32_DMA2D_STATIC void _lv_draw_stm32_dma2d_blend_map(const lv_color_t * dest_buf, lv_coord_t dest_stride,
const lv_area_t * draw_area, const void * src_buf, lv_coord_t src_stride, const lv_point_t * src_offset, lv_opa_t opa,
dma2d_color_format_t src_color_format, bool ignore_src_alpha);
LV_STM32_DMA2D_STATIC void _lv_draw_stm32_dma2d_blend_paint(const lv_color_t * dst_buf, lv_coord_t dst_stride,
const lv_area_t * draw_area, const lv_opa_t * mask_buf, lv_coord_t mask_stride, const lv_point_t * mask_offset,
lv_color_t color, lv_opa_t opa);
LV_STM32_DMA2D_STATIC void _lv_draw_stm32_dma2d_copy_buffer(const lv_color_t * dest_buf, lv_coord_t dest_stride,
const lv_area_t * draw_area, const lv_color_t * src_buf, lv_coord_t src_stride, const lv_point_t * src_offset);
LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dma2d_await_dma_transfer_finish(lv_disp_drv_t * disp_drv);
LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dma2d_start_dma_transfer(void);
LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dma2d_invalidate_cache(uint32_t address, lv_coord_t offset,
lv_coord_t width, lv_coord_t height, uint8_t pixel_size);
LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dma2d_clean_cache(uint32_t address, lv_coord_t offset, lv_coord_t width,
lv_coord_t height, uint8_t pixel_size);
LV_STM32_DMA2D_STATIC bool _lv_gpu_stm32_dwt_init(void);
LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dwt_reset(void);
LV_STM32_DMA2D_STATIC uint32_t _lv_gpu_stm32_dwt_get_us(void);
static bool isDma2dInProgess = false; // indicates whether DMA2D transfer *initiated here* is in progress
/**
@ -276,9 +311,8 @@ static dma2d_color_format_t lv_color_format_to_dma2d_color_format(lv_img_cf_t co
}
}
static lv_res_t lv_draw_stm32_dma2d_img(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * img_dsc,
const lv_area_t * src_area,
const void * src)
LV_STM32_DMA2D_STATIC lv_res_t lv_draw_stm32_dma2d_img(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * img_dsc,
const lv_area_t * src_area, const void * src)
{
//if(lv_img_src_get_type(src) != LV_IMG_SRC_VARIABLE) return LV_RES_INV;
return LV_RES_INV;
@ -315,7 +349,7 @@ static lv_res_t lv_draw_stm32_dma2d_img(lv_draw_ctx_t * draw_ctx, const lv_draw_
return LV_RES_OK;
}
static void lv_gpu_stm32_dma2d_wait_cb(lv_draw_ctx_t * draw_ctx)
LV_STM32_DMA2D_STATIC void lv_gpu_stm32_dma2d_wait_cb(lv_draw_ctx_t * draw_ctx)
{
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
_lv_gpu_stm32_dma2d_await_dma_transfer_finish(disp->driver);

View File

@ -53,40 +53,6 @@ struct _lv_disp_drv_t;
void lv_draw_stm32_dma2d_init(void);
void lv_draw_stm32_dma2d_ctx_init(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx);
void lv_draw_stm32_dma2d_ctx_deinit(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx);
static void lv_draw_stm32_dma2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc);
static void lv_draw_stm32_dma2d_buffer_copy(lv_draw_ctx_t * draw_ctx,
void * dest_buf, lv_coord_t dest_stride, const lv_area_t * dest_area,
void * src_buf, lv_coord_t src_stride, const lv_area_t * src_area);
static lv_res_t lv_draw_stm32_dma2d_img(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * img_dsc,
const lv_area_t * src_area, const void * src);
static void lv_gpu_stm32_dma2d_wait_cb(lv_draw_ctx_t * draw_ctx);
static void lv_draw_stm32_dma2d_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * img_dsc,
const lv_area_t * coords, const uint8_t * src_buf, lv_img_cf_t color_format);
static dma2d_color_format_t lv_color_format_to_dma2d_color_format(lv_img_cf_t color_format);
static lv_point_t lv_area_get_offset(const lv_area_t * area1, const lv_area_t * area2);
/**********************
* STATIC PROTOTYPES
**********************/
LV_STM32_DMA2D_STATIC void _lv_draw_stm32_dma2d_blend_fill(const lv_color_t * dst_buf, lv_coord_t dst_stride,
const lv_area_t * draw_area, lv_color_t color, lv_opa_t opa);
LV_STM32_DMA2D_STATIC void _lv_draw_stm32_dma2d_blend_map(const lv_color_t * dest_buf, lv_coord_t dest_stride,
const lv_area_t * draw_area, const void * src_buf, lv_coord_t src_stride, const lv_point_t * src_offset, lv_opa_t opa,
dma2d_color_format_t src_color_format, bool ignore_src_alpha);
LV_STM32_DMA2D_STATIC void _lv_draw_stm32_dma2d_blend_paint(const lv_color_t * dst_buf, lv_coord_t dst_stride,
const lv_area_t * draw_area, const lv_opa_t * mask_buf, lv_coord_t mask_stride, const lv_point_t * mask_offset,
lv_color_t color, lv_opa_t opa);
LV_STM32_DMA2D_STATIC void _lv_draw_stm32_dma2d_copy_buffer(const lv_color_t * dest_buf, lv_coord_t dest_stride,
const lv_area_t * draw_area, const lv_color_t * src_buf, lv_coord_t src_stride, const lv_point_t * src_offset);
LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dma2d_await_dma_transfer_finish(lv_disp_drv_t * disp_drv);
LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dma2d_start_dma_transfer(void);
LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dma2d_invalidate_cache(uint32_t address, lv_coord_t offset,
lv_coord_t width, lv_coord_t height, uint8_t pixel_size);
LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dma2d_clean_cache(uint32_t address, lv_coord_t offset, lv_coord_t width,
lv_coord_t height, uint8_t pixel_size);
LV_STM32_DMA2D_STATIC bool _lv_gpu_stm32_dwt_init(void);
LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dwt_reset(void);
LV_STM32_DMA2D_STATIC uint32_t _lv_gpu_stm32_dwt_get_us(void);
/**********************
* MACROS

View File

@ -430,7 +430,7 @@ static inline void set_px_argb_blend(uint8_t * buf, lv_color_t color, lv_opa_t o
/*Set the result color*/
#if LV_COLOR_DEPTH == 8
buf[0] = res_color.full;
buf[0] = last_res_color.full;
#elif LV_COLOR_DEPTH == 16
buf[0] = last_res_color.full & 0xff;
buf[1] = last_res_color.full >> 8;

View File

@ -97,6 +97,7 @@ void lv_flex_init(void)
LV_STYLE_FLEX_MAIN_PLACE = lv_style_register_prop(LV_STYLE_PROP_LAYOUT_REFR);
LV_STYLE_FLEX_CROSS_PLACE = lv_style_register_prop(LV_STYLE_PROP_LAYOUT_REFR);
LV_STYLE_FLEX_TRACK_PLACE = lv_style_register_prop(LV_STYLE_PROP_LAYOUT_REFR);
LV_STYLE_FLEX_GROW = lv_style_register_prop(LV_STYLE_PROP_LAYOUT_REFR);
}
void lv_obj_set_flex_flow(lv_obj_t * obj, lv_flex_flow_t flow)

View File

@ -103,13 +103,33 @@ static lv_res_t decoder_info(struct _lv_img_decoder_t * decoder, const void * sr
else if(src_type == LV_IMG_SRC_VARIABLE) {
const lv_img_dsc_t * img_dsc = src;
const uint32_t data_size = img_dsc->data_size;
const uint32_t * size = ((uint32_t *)img_dsc->data) + 4;
const uint8_t magic[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a};
if(data_size < sizeof(magic)) return LV_RES_INV;
if(memcmp(magic, img_dsc->data, sizeof(magic))) return LV_RES_INV;
header->always_zero = 0;
header->cf = img_dsc->header.cf; /*Save the color format*/
header->w = img_dsc->header.w; /*Save the color width*/
header->h = img_dsc->header.h; /*Save the color height*/
if(img_dsc->header.cf) {
header->cf = img_dsc->header.cf; /*Save the color format*/
}
else {
header->cf = LV_IMG_CF_TRUE_COLOR_ALPHA;
}
if(img_dsc->header.w) {
header->w = img_dsc->header.w; /*Save the image width*/
}
else {
header->w = (lv_coord_t)((size[0] & 0xff000000) >> 24) + ((size[0] & 0x00ff0000) >> 8);
}
if(img_dsc->header.h) {
header->h = img_dsc->header.h; /*Save the color height*/
}
else {
header->h = (lv_coord_t)((size[1] & 0xff000000) >> 24) + ((size[1] & 0x00ff0000) >> 8);
}
return LV_RES_OK;
}
@ -142,13 +162,13 @@ static lv_res_t decoder_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t *
error = lodepng_load_file(&png_data, &png_data_size, fn); /*Load the file*/
if(error) {
LV_LOG_WARN("error %u: %s\n", error, lodepng_error_text(error));
LV_LOG_WARN("error %" LV_PRIu32 ": %s\n", error, lodepng_error_text(error));
return LV_RES_INV;
}
/*Decode the PNG image*/
uint32_t png_width; /*Will be the width of the decoded image*/
uint32_t png_height; /*Will be the width of the decoded image*/
unsigned png_width; /*Will be the width of the decoded image*/
unsigned png_height; /*Will be the width of the decoded image*/
/*Decode the loaded image in ARGB8888 */
error = lodepng_decode32(&img_data, &png_width, &png_height, png_data, png_data_size);
@ -157,7 +177,7 @@ static lv_res_t decoder_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t *
if(img_data != NULL) {
lv_mem_free(img_data);
}
LV_LOG_WARN("error %u: %s\n", error, lodepng_error_text(error));
LV_LOG_WARN("error %" LV_PRIu32 ": %s\n", error, lodepng_error_text(error));
return LV_RES_INV;
}
@ -170,8 +190,8 @@ static lv_res_t decoder_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t *
/*If it's a PNG file in a C array...*/
else if(dsc->src_type == LV_IMG_SRC_VARIABLE) {
const lv_img_dsc_t * img_dsc = dsc->src;
uint32_t png_width; /*No used, just required by he decoder*/
uint32_t png_height; /*No used, just required by he decoder*/
unsigned png_width; /*No used, just required by he decoder*/
unsigned png_height; /*No used, just required by he decoder*/
/*Decode the image in ARGB8888 */
error = lodepng_decode32(&img_data, &png_width, &png_height, img_dsc->data, img_dsc->data_size);

View File

@ -78,16 +78,14 @@ void lv_extra_init(void)
lv_bmp_init();
#endif
// TASMOTA Specific, the initialization is done in Tasmota code to adjust with PSRAM
// #if LV_USE_FREETYPE
// /*Init freetype library*/
// # if LV_FREETYPE_CACHE_SIZE >= 0
// lv_freetype_init(LV_FREETYPE_CACHE_FT_FACES, LV_FREETYPE_CACHE_FT_SIZES, LV_FREETYPE_CACHE_SIZE);
// # else
// lv_freetype_init(0, 0, 0);
// # endif
// #endif
#if LV_USE_FREETYPE
/*Init freetype library*/
# if LV_FREETYPE_CACHE_SIZE >= 0
lv_freetype_init(LV_FREETYPE_CACHE_FT_FACES, LV_FREETYPE_CACHE_FT_SIZES, LV_FREETYPE_CACHE_SIZE);
# else
lv_freetype_init(0, 0, 0);
# endif
#endif
}
/**********************

View File

@ -1382,8 +1382,10 @@ static void draw_y_ticks(lv_obj_t * obj, lv_draw_ctx_t * draw_ctx, lv_chart_axis
lv_chart_tick_dsc_t * t = get_tick_gsc(obj, axis);
if(t->major_cnt <= 1) return;
if(!t->label_en && !t->major_len && !t->minor_len) return;
if(t->major_cnt <= 1) return;
uint32_t total_tick_num = (t->major_cnt - 1) * (t->minor_cnt);
if(total_tick_num == 0) return;
uint8_t sec_axis = axis == LV_CHART_AXIS_PRIMARY_Y ? 0 : 1;
@ -1433,7 +1435,6 @@ static void draw_y_ticks(lv_obj_t * obj, lv_draw_ctx_t * draw_ctx, lv_chart_axis
part_draw_dsc.line_dsc = &line_dsc;
part_draw_dsc.label_dsc = &label_dsc;
uint32_t total_tick_num = (t->major_cnt - 1) * (t->minor_cnt);
for(i = 0; i <= total_tick_num; i++) {
/*draw a line at moving y position*/
p2.y = p1.y = y_ofs + (int32_t)((int32_t)(h - line_dsc.width) * i) / total_tick_num;
@ -1514,6 +1515,8 @@ static void draw_x_ticks(lv_obj_t * obj, lv_draw_ctx_t * draw_ctx, lv_chart_axis
lv_chart_tick_dsc_t * t = get_tick_gsc(obj, axis);
if(t->major_cnt <= 1) return;
if(!t->label_en && !t->major_len && !t->minor_len) return;
uint32_t total_tick_num = (t->major_cnt - 1) * (t->minor_cnt);
if(total_tick_num == 0) return;
uint32_t i;
lv_point_t p1;
@ -1571,7 +1574,6 @@ static void draw_x_ticks(lv_obj_t * obj, lv_draw_ctx_t * draw_ctx, lv_chart_axis
}
p1.y = y_ofs;
uint32_t total_tick_num = (t->major_cnt - 1) * t->minor_cnt;
for(i = 0; i <= total_tick_num; i++) { /*one extra loop - it may not exist in the list, empty label*/
bool major = false;
if(i % t->minor_cnt == 0) major = true;

View File

@ -106,6 +106,9 @@ lv_obj_t * lv_msgbox_create(lv_obj_t * parent, const char * title, const char *
}
mbox->content = lv_obj_class_create_obj(&lv_msgbox_content_class, obj);
LV_ASSERT_MALLOC(mbox->content);
if(mbox->content == NULL) return NULL;
lv_obj_class_init_obj(mbox->content);
bool has_txt = txt && strlen(txt) > 0;
if(has_txt) {

View File

@ -308,7 +308,7 @@ static void btns_value_changed_event_cb(lv_event_t * e)
lv_obj_t * tv = lv_obj_get_parent(btns);
uint32_t id = lv_btnmatrix_get_selected_btn(btns);
lv_tabview_set_act(tv, id, LV_ANIM_ON);
lv_tabview_set_act(tv, id, LV_ANIM_OFF);
}
static void cont_scroll_end_event_cb(lv_event_t * e)

View File

@ -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);

View File

@ -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

View File

@ -376,7 +376,6 @@ static bool lv_bidi_letter_is_weak(uint32_t letter)
*/
static bool lv_bidi_letter_is_rtl(uint32_t letter)
{
if(letter >= 0x5d0 && letter <= 0x5ea) return true;
if(letter == 0x202E) return true; /*Unicode of LV_BIDI_RLO*/
/*Check for Persian and Arabic characters [https://en.wikipedia.org/wiki/Arabic_script_in_Unicode]*/
@ -384,6 +383,10 @@ static bool lv_bidi_letter_is_rtl(uint32_t letter)
if(letter >= 0xFB50 && letter <= 0xFDFF) return true;
if(letter >= 0xFE70 && letter <= 0xFEFF) return true;
/*Check for Hebrew characters [https://en.wikipedia.org/wiki/Unicode_and_HTML_for_the_Hebrew_alphabet]*/
if(letter >= 0x590 && letter <= 0x5FF) return true;
if(letter >= 0xFB1D && letter <= 0xFB4F) return true;
return false;
}

View File

@ -23,7 +23,7 @@
#define MY_CLASS &lv_btnmatrix_class
#define BTN_EXTRA_CLICK_AREA_MAX (LV_DPI_DEF / 10)
#define LV_BTNMATRIX_WIDTH_MASK 0x0007
#define LV_BTNMATRIX_WIDTH_MASK 0x000F
/**********************
* TYPEDEFS
@ -520,6 +520,8 @@ static void lv_btnmatrix_event(const lv_obj_class_t * class_p, lv_event_t * e)
btnm->btn_id_sel = LV_BTNMATRIX_BTN_NONE;
}
else if(code == LV_EVENT_FOCUSED) {
if(btnm->btn_cnt == 0) return;
lv_indev_t * indev = lv_event_get_param(e);
lv_indev_type_t indev_type = lv_indev_get_type(indev);
@ -563,9 +565,15 @@ static void lv_btnmatrix_event(const lv_obj_class_t * class_p, lv_event_t * e)
else btnm->btn_id_sel++;
if(btnm->btn_id_sel >= btnm->btn_cnt) btnm->btn_id_sel = 0;
uint16_t btn_id_start = btnm->btn_id_sel;
while(button_is_hidden(btnm->ctrl_bits[btnm->btn_id_sel]) || button_is_inactive(btnm->ctrl_bits[btnm->btn_id_sel])) {
btnm->btn_id_sel++;
if(btnm->btn_id_sel >= btnm->btn_cnt) btnm->btn_id_sel = 0;
if(btnm->btn_id_sel == btn_id_start) {
btnm->btn_id_sel = LV_BTNMATRIX_BTN_NONE;
break;
}
}
}
else if(c == LV_KEY_LEFT) {
@ -574,9 +582,15 @@ static void lv_btnmatrix_event(const lv_obj_class_t * class_p, lv_event_t * e)
if(btnm->btn_id_sel == 0) btnm->btn_id_sel = btnm->btn_cnt - 1;
else if(btnm->btn_id_sel > 0) btnm->btn_id_sel--;
uint16_t btn_id_start = btnm->btn_id_sel;
while(button_is_hidden(btnm->ctrl_bits[btnm->btn_id_sel]) || button_is_inactive(btnm->ctrl_bits[btnm->btn_id_sel])) {
if(btnm->btn_id_sel > 0) btnm->btn_id_sel--;
else btnm->btn_id_sel = btnm->btn_cnt - 1;
if(btnm->btn_id_sel == btn_id_start) {
btnm->btn_id_sel = LV_BTNMATRIX_BTN_NONE;
break;
}
}
}
else if(c == LV_KEY_DOWN) {
@ -586,7 +600,10 @@ static void lv_btnmatrix_event(const lv_obj_class_t * class_p, lv_event_t * e)
btnm->btn_id_sel = 0;
while(button_is_hidden(btnm->ctrl_bits[btnm->btn_id_sel]) || button_is_inactive(btnm->ctrl_bits[btnm->btn_id_sel])) {
btnm->btn_id_sel++;
if(btnm->btn_id_sel >= btnm->btn_cnt) btnm->btn_id_sel = 0;
if(btnm->btn_id_sel >= btnm->btn_cnt) {
btnm->btn_id_sel = LV_BTNMATRIX_BTN_NONE;
break;
}
}
}
else {
@ -614,7 +631,10 @@ static void lv_btnmatrix_event(const lv_obj_class_t * class_p, lv_event_t * e)
btnm->btn_id_sel = 0;
while(button_is_hidden(btnm->ctrl_bits[btnm->btn_id_sel]) || button_is_inactive(btnm->ctrl_bits[btnm->btn_id_sel])) {
btnm->btn_id_sel++;
if(btnm->btn_id_sel >= btnm->btn_cnt) btnm->btn_id_sel = 0;
if(btnm->btn_id_sel >= btnm->btn_cnt) {
btnm->btn_id_sel = LV_BTNMATRIX_BTN_NONE;
break;
}
}
}
else {