mirror of
https://github.com/lvgl/lvgl.git
synced 2026-09-23 03:35:30 +08:00
feat(dma2d) avoid code duplication regarding image and fill handling (#10182)
Signed-off-by: Alain Volmat <alain.volmat@foss.st.com> Co-authored-by: Alain Volmat <alain.volmat@foss.st.com>
This commit is contained in:
co-authored by
Alain Volmat
parent
80fc7c4fa7
commit
77b321d3ae
@@ -345,47 +345,30 @@ static int32_t dispatch_cb(lv_draw_unit_t * draw_unit, lv_layer_t * layer)
|
||||
t->draw_unit = draw_unit;
|
||||
draw_dma2d_unit->task_act = t;
|
||||
|
||||
/* Abort rapidly if nothing to do */
|
||||
lv_area_t clipped_coords;
|
||||
if(!lv_area_intersect(&clipped_coords, &t->area, &t->clip_area)) {
|
||||
draw_dma2d_unit->task_act->state = LV_DRAW_TASK_STATE_FINISHED;
|
||||
draw_dma2d_unit->task_act = NULL;
|
||||
|
||||
lv_draw_dispatch_request();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(t->type == LV_DRAW_TASK_TYPE_FILL) {
|
||||
lv_draw_fill_dsc_t * dsc = t->draw_dsc;
|
||||
const lv_area_t * coords = &t->area;
|
||||
lv_area_t clipped_coords;
|
||||
if(!lv_area_intersect(&clipped_coords, coords, &t->clip_area)) {
|
||||
return LV_DRAW_UNIT_IDLE;
|
||||
}
|
||||
|
||||
void * dest = lv_draw_layer_go_to_xy(layer,
|
||||
clipped_coords.x1 - layer->buf_area.x1,
|
||||
clipped_coords.y1 - layer->buf_area.y1);
|
||||
|
||||
if(dsc->opa >= LV_OPA_MAX) {
|
||||
lv_draw_dma2d_opaque_fill(t,
|
||||
dest,
|
||||
lv_area_get_width(&clipped_coords),
|
||||
lv_area_get_height(&clipped_coords),
|
||||
lv_draw_buf_width_to_stride(lv_area_get_width(&layer->buf_area), dsc->base.layer->color_format));
|
||||
}
|
||||
else {
|
||||
lv_draw_dma2d_fill(t,
|
||||
dest,
|
||||
lv_area_get_width(&clipped_coords),
|
||||
lv_area_get_height(&clipped_coords),
|
||||
lv_draw_buf_width_to_stride(lv_area_get_width(&layer->buf_area), dsc->base.layer->color_format));
|
||||
}
|
||||
lv_draw_dma2d_fill(t, dest,
|
||||
lv_area_get_width(&clipped_coords),
|
||||
lv_area_get_height(&clipped_coords),
|
||||
lv_draw_buf_width_to_stride(lv_area_get_width(&layer->buf_area), dsc->base.layer->color_format));
|
||||
}
|
||||
else if(t->type == LV_DRAW_TASK_TYPE_IMAGE) {
|
||||
lv_draw_image_dsc_t * dsc = t->draw_dsc;
|
||||
const lv_area_t * coords = &t->area;
|
||||
lv_area_t clipped_coords;
|
||||
if(!lv_area_intersect(&clipped_coords, coords, &t->clip_area)) {
|
||||
return LV_DRAW_UNIT_IDLE;
|
||||
}
|
||||
|
||||
if(dsc->opa >= LV_OPA_MAX) {
|
||||
lv_draw_dma2d_opaque_image(t, dsc, &t->area);
|
||||
}
|
||||
else {
|
||||
lv_draw_dma2d_image(t, dsc, &t->area);
|
||||
}
|
||||
lv_draw_dma2d_image(t, t->draw_dsc, &t->area);
|
||||
}
|
||||
|
||||
lv_draw_dispatch_request();
|
||||
|
||||
@@ -34,44 +34,9 @@
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_dma2d_opaque_fill(lv_draw_task_t * t, void * first_pixel, int32_t w, int32_t h, int32_t stride)
|
||||
{
|
||||
lv_draw_fill_dsc_t * dsc = t->draw_dsc;
|
||||
lv_color_format_t cf = dsc->base.layer->color_format;
|
||||
|
||||
lv_draw_dma2d_output_cf_t output_cf = lv_draw_dma2d_cf_to_dma2d_output_cf(cf);
|
||||
uint32_t cf_size = LV_COLOR_FORMAT_GET_SIZE(cf);
|
||||
uint32_t reg_to_mem_color = lv_draw_dma2d_color_to_dma2d_color(output_cf, dsc->color);
|
||||
|
||||
#if LV_DRAW_DMA2D_CACHE
|
||||
lv_draw_dma2d_cache_area_t cache_area = {
|
||||
.first_byte = first_pixel,
|
||||
.width_bytes = w * cf_size,
|
||||
.height = h,
|
||||
.stride = stride
|
||||
};
|
||||
lv_draw_dma2d_unit_t * u = (lv_draw_dma2d_unit_t *) t->draw_unit;
|
||||
lv_memcpy(&u->writing_area, &cache_area, sizeof(lv_draw_dma2d_cache_area_t));
|
||||
#endif
|
||||
|
||||
lv_draw_dma2d_configuration_t conf = {
|
||||
.mode = LV_DRAW_DMA2D_MODE_REGISTER_TO_MEMORY,
|
||||
.w = w,
|
||||
.h = h,
|
||||
|
||||
.output_address = first_pixel,
|
||||
.output_offset = (stride / cf_size) - w,
|
||||
.output_cf = output_cf,
|
||||
|
||||
.reg_to_mem_mode_color = reg_to_mem_color
|
||||
};
|
||||
lv_draw_dma2d_configure_and_start_transfer(&conf);
|
||||
}
|
||||
|
||||
void lv_draw_dma2d_fill(lv_draw_task_t * t, void * first_pixel, int32_t w, int32_t h, int32_t stride)
|
||||
{
|
||||
lv_draw_fill_dsc_t * dsc = t->draw_dsc;
|
||||
lv_color_t color = dsc->color;
|
||||
lv_color_format_t cf = dsc->base.layer->color_format;
|
||||
lv_opa_t opa = dsc->opa;
|
||||
|
||||
@@ -88,39 +53,47 @@ void lv_draw_dma2d_fill(lv_draw_task_t * t, void * first_pixel, int32_t w, int32
|
||||
lv_draw_dma2d_unit_t * u = (lv_draw_dma2d_unit_t *) t->draw_unit;
|
||||
lv_memcpy(&u->writing_area, &cache_area, sizeof(lv_draw_dma2d_cache_area_t));
|
||||
|
||||
/* make sure the background area DMA2D is blending is up-to-date in main memory */
|
||||
lv_draw_dma2d_clean_cache(&cache_area);
|
||||
if(dsc->opa < LV_OPA_MAX) {
|
||||
/* make sure the background area DMA2D is blending is up-to-date in main memory */
|
||||
lv_draw_dma2d_clean_cache(&cache_area);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t output_offset = (stride / cf_size) - w;
|
||||
|
||||
lv_draw_dma2d_configuration_t conf = {
|
||||
.mode = LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY_WITH_BLENDING,
|
||||
.mode = LV_DRAW_DMA2D_MODE_REGISTER_TO_MEMORY,
|
||||
.w = w,
|
||||
.h = h,
|
||||
|
||||
.output_address = first_pixel,
|
||||
.output_offset = output_offset,
|
||||
.output_cf = output_cf,
|
||||
|
||||
.fg_color = lv_color_to_u32(color),
|
||||
.fg_address = first_pixel,
|
||||
.fg_offset = output_offset,
|
||||
.fg_alpha_mode = LV_DRAW_DMA2D_ALPHA_MODE_REPLACE_ALPHA_CHANNEL,
|
||||
.fg_alpha = opa,
|
||||
.fg_cf = LV_DRAW_DMA2D_FGBG_CF_A8,
|
||||
|
||||
.bg_address = first_pixel,
|
||||
.bg_offset = output_offset,
|
||||
.bg_alpha_mode = LV_DRAW_DMA2D_ALPHA_MODE_NO_MODIFY_IMAGE_ALPHA_CHANNEL,
|
||||
.bg_alpha = opa,
|
||||
.bg_cf = (lv_draw_dma2d_fgbg_cf_t) output_cf
|
||||
};
|
||||
|
||||
/* Background alpha channel should be treated as 0xFF if the cf is XRGB */
|
||||
if(cf == LV_COLOR_FORMAT_XRGB8888) {
|
||||
conf.bg_alpha_mode = LV_DRAW_DMA2D_ALPHA_MODE_REPLACE_ALPHA_CHANNEL;
|
||||
conf.bg_alpha = 0xff;
|
||||
if(dsc->opa >= LV_OPA_MAX) {
|
||||
conf.reg_to_mem_mode_color = lv_draw_dma2d_color_to_dma2d_color(output_cf, dsc->color);
|
||||
}
|
||||
else {
|
||||
conf.mode = LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY_WITH_BLENDING;
|
||||
conf.fg_color = lv_color_to_u32(dsc->color);
|
||||
conf.fg_address = first_pixel;
|
||||
conf.fg_offset = output_offset;
|
||||
conf.fg_alpha_mode = LV_DRAW_DMA2D_ALPHA_MODE_REPLACE_ALPHA_CHANNEL;
|
||||
conf.fg_alpha = opa;
|
||||
conf.fg_cf = LV_DRAW_DMA2D_FGBG_CF_A8;
|
||||
|
||||
conf.bg_address = first_pixel;
|
||||
conf.bg_offset = output_offset;
|
||||
conf.bg_alpha_mode = LV_DRAW_DMA2D_ALPHA_MODE_NO_MODIFY_IMAGE_ALPHA_CHANNEL;
|
||||
conf.bg_alpha = opa;
|
||||
conf.bg_cf = (lv_draw_dma2d_fgbg_cf_t) output_cf;
|
||||
|
||||
/* Background alpha channel should be treated as 0xFF if the cf is XRGB */
|
||||
if(cf == LV_COLOR_FORMAT_XRGB8888) {
|
||||
conf.bg_alpha_mode = LV_DRAW_DMA2D_ALPHA_MODE_REPLACE_ALPHA_CHANNEL;
|
||||
conf.bg_alpha = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
lv_draw_dma2d_configure_and_start_transfer(&conf);
|
||||
|
||||
@@ -26,10 +26,6 @@
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void lv_draw_dma2d_opaque_image_core(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc,
|
||||
const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup,
|
||||
const lv_area_t * img_coords, const lv_area_t * clipped_img_area);
|
||||
|
||||
static void lv_draw_dma2d_image_core(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc,
|
||||
const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup,
|
||||
const lv_area_t * img_coords, const lv_area_t * clipped_img_area);
|
||||
@@ -46,17 +42,6 @@ static void lv_draw_dma2d_image_core(lv_draw_task_t * t, const lv_draw_image_dsc
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_dma2d_opaque_image(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
if(!draw_dsc->tile) {
|
||||
lv_draw_image_normal_helper(t, draw_dsc, coords, lv_draw_dma2d_opaque_image_core, NULL);
|
||||
}
|
||||
else {
|
||||
lv_draw_image_tiled_helper(t, draw_dsc, coords, lv_draw_dma2d_opaque_image_core, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void lv_draw_dma2d_image(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
@@ -72,102 +57,6 @@ void lv_draw_dma2d_image(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_ds
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void lv_draw_dma2d_opaque_image_core(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc,
|
||||
const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup,
|
||||
const lv_area_t * img_coords, const lv_area_t * clipped_img_area)
|
||||
{
|
||||
LV_UNUSED(sup);
|
||||
LV_UNUSED(img_coords);
|
||||
|
||||
lv_layer_t * layer = t->target_layer;
|
||||
|
||||
void * dest_first_pixel = lv_draw_layer_go_to_xy(layer,
|
||||
clipped_img_area->x1 - layer->buf_area.x1,
|
||||
clipped_img_area->y1 - layer->buf_area.y1);
|
||||
int32_t dest_stride = lv_draw_buf_width_to_stride(lv_area_get_width(&layer->buf_area), layer->color_format);
|
||||
|
||||
int32_t w = lv_area_get_width(clipped_img_area);
|
||||
int32_t h = lv_area_get_height(clipped_img_area);
|
||||
|
||||
lv_color_format_t output_cf = layer->color_format;
|
||||
uint32_t output_cf_size = lv_color_format_get_size(output_cf);
|
||||
lv_draw_dma2d_output_cf_t output_cf_dma2d = lv_draw_dma2d_cf_to_dma2d_output_cf(output_cf);
|
||||
|
||||
const lv_draw_buf_t * decoded = decoder_dsc->decoded;
|
||||
const uint8_t * src_buf = decoded->data;
|
||||
uint32_t image_stride = decoded->header.stride;
|
||||
lv_color_format_t image_cf = decoded->header.cf;
|
||||
lv_draw_dma2d_fgbg_cf_t image_cf_dma2d = (lv_draw_dma2d_fgbg_cf_t) lv_draw_dma2d_cf_to_dma2d_output_cf(image_cf);
|
||||
uint32_t image_cf_size = LV_COLOR_FORMAT_GET_SIZE(image_cf);
|
||||
if(image_stride == 0) image_stride = image_cf_size * decoded->header.w;
|
||||
|
||||
#if LV_DRAW_DMA2D_CACHE
|
||||
lv_draw_dma2d_cache_area_t dest_area = {
|
||||
.first_byte = dest_first_pixel,
|
||||
.width_bytes = w * output_cf_size,
|
||||
.height = h,
|
||||
.stride = dest_stride
|
||||
};
|
||||
lv_draw_dma2d_unit_t * u = (lv_draw_dma2d_unit_t *) t->draw_unit;
|
||||
lv_memcpy(&u->writing_area, &dest_area, sizeof(lv_draw_dma2d_cache_area_t));
|
||||
if(lv_color_format_has_alpha(image_cf)) {
|
||||
/* make sure the background area DMA2D is blending is up-to-date in main memory */
|
||||
lv_draw_dma2d_clean_cache(&dest_area);
|
||||
}
|
||||
#endif
|
||||
|
||||
const void * image_first_byte = src_buf
|
||||
+ (image_stride * (clipped_img_area->y1 - draw_dsc->image_area.y1))
|
||||
+ (image_cf_size * (clipped_img_area->x1 - draw_dsc->image_area.x1));
|
||||
|
||||
#if LV_DRAW_DMA2D_CACHE
|
||||
lv_draw_dma2d_cache_area_t src_area = {
|
||||
.first_byte = image_first_byte,
|
||||
.width_bytes = w * image_cf_size,
|
||||
.height = h,
|
||||
.stride = image_stride
|
||||
};
|
||||
/* make sure the image area is up-to-date in main memory for DMA2D */
|
||||
lv_draw_dma2d_clean_cache(&src_area);
|
||||
#endif
|
||||
|
||||
uint32_t output_offset = (dest_stride / output_cf_size) - w;
|
||||
lv_draw_dma2d_configuration_t conf = {
|
||||
.mode = LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY_WITH_PFC,
|
||||
.w = w,
|
||||
.h = h,
|
||||
|
||||
.output_address = dest_first_pixel,
|
||||
.output_offset = output_offset,
|
||||
.output_cf = output_cf_dma2d,
|
||||
|
||||
.fg_address = image_first_byte,
|
||||
.fg_offset = (image_stride / image_cf_size) - w,
|
||||
.fg_cf = image_cf_dma2d
|
||||
};
|
||||
|
||||
/* only process the background if the image might be transparent */
|
||||
if(lv_color_format_has_alpha(image_cf)) {
|
||||
conf.mode = LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY_WITH_BLENDING;
|
||||
|
||||
conf.bg_address = dest_first_pixel;
|
||||
conf.bg_offset = output_offset;
|
||||
conf.bg_cf = output_cf_dma2d;
|
||||
}
|
||||
|
||||
/* Alpha channel should be treated as 0xFF if the cf is XRGB */
|
||||
if(image_cf == LV_COLOR_FORMAT_XRGB8888) {
|
||||
conf.fg_alpha_mode = LV_DRAW_DMA2D_ALPHA_MODE_REPLACE_ALPHA_CHANNEL;
|
||||
conf.fg_alpha = 0xff;
|
||||
}
|
||||
if(output_cf == LV_COLOR_FORMAT_XRGB8888) {
|
||||
conf.bg_alpha_mode = LV_DRAW_DMA2D_ALPHA_MODE_REPLACE_ALPHA_CHANNEL;
|
||||
conf.bg_alpha = 0xff;
|
||||
}
|
||||
|
||||
lv_draw_dma2d_configure_and_start_transfer(&conf);
|
||||
}
|
||||
|
||||
static void lv_draw_dma2d_image_core(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc,
|
||||
const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup,
|
||||
const lv_area_t * img_coords, const lv_area_t * clipped_img_area)
|
||||
@@ -247,9 +136,20 @@ static void lv_draw_dma2d_image_core(lv_draw_task_t * t, const lv_draw_image_dsc
|
||||
.bg_cf = output_cf_dma2d,
|
||||
};
|
||||
|
||||
if(opa >= LV_OPA_MAX) {
|
||||
/* only process the background if the image might be transparent */
|
||||
if(lv_color_format_has_alpha(image_cf)) {
|
||||
conf.mode = LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY_WITH_BLENDING;
|
||||
}
|
||||
else {
|
||||
conf.mode = LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY_WITH_PFC;
|
||||
}
|
||||
}
|
||||
|
||||
/* Alpha channel should be treated as 0xFF if the cf is XRGB */
|
||||
if(image_cf == LV_COLOR_FORMAT_XRGB8888) {
|
||||
conf.fg_alpha_mode = LV_DRAW_DMA2D_ALPHA_MODE_REPLACE_ALPHA_CHANNEL;
|
||||
conf.fg_alpha = 0xff;
|
||||
}
|
||||
if(output_cf == LV_COLOR_FORMAT_XRGB8888) {
|
||||
conf.bg_alpha_mode = LV_DRAW_DMA2D_ALPHA_MODE_REPLACE_ALPHA_CHANNEL;
|
||||
|
||||
@@ -128,10 +128,7 @@ typedef struct {
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_draw_dma2d_opaque_fill(lv_draw_task_t * t, void * first_pixel, int32_t w, int32_t h, int32_t stride);
|
||||
void lv_draw_dma2d_fill(lv_draw_task_t * t, void * first_pixel, int32_t w, int32_t h, int32_t stride);
|
||||
void lv_draw_dma2d_opaque_image(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc,
|
||||
const lv_area_t * coords);
|
||||
void lv_draw_dma2d_image(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc,
|
||||
const lv_area_t * coords);
|
||||
lv_draw_dma2d_output_cf_t lv_draw_dma2d_cf_to_dma2d_output_cf(lv_color_format_t cf);
|
||||
|
||||
Reference in New Issue
Block a user