diff --git a/src/draw/dma2d/lv_draw_dma2d.c b/src/draw/dma2d/lv_draw_dma2d.c index f62d69d8f4..57041ad767 100644 --- a/src/draw/dma2d/lv_draw_dma2d.c +++ b/src/draw/dma2d/lv_draw_dma2d.c @@ -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(); diff --git a/src/draw/dma2d/lv_draw_dma2d_fill.c b/src/draw/dma2d/lv_draw_dma2d_fill.c index d4ecdb36c1..9fde09f541 100644 --- a/src/draw/dma2d/lv_draw_dma2d_fill.c +++ b/src/draw/dma2d/lv_draw_dma2d_fill.c @@ -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); diff --git a/src/draw/dma2d/lv_draw_dma2d_img.c b/src/draw/dma2d/lv_draw_dma2d_img.c index bf7ad34285..d80de00bc0 100644 --- a/src/draw/dma2d/lv_draw_dma2d_img.c +++ b/src/draw/dma2d/lv_draw_dma2d_img.c @@ -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; diff --git a/src/draw/dma2d/lv_draw_dma2d_private.h b/src/draw/dma2d/lv_draw_dma2d_private.h index 40373adb3f..a50fefcc6d 100644 --- a/src/draw/dma2d/lv_draw_dma2d_private.h +++ b/src/draw/dma2d/lv_draw_dma2d_private.h @@ -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);