diff --git a/src/draw/nxp/pxp/lv_draw_pxp.c b/src/draw/nxp/pxp/lv_draw_pxp.c index c87d996934..63b51d839d 100644 --- a/src/draw/nxp/pxp/lv_draw_pxp.c +++ b/src/draw/nxp/pxp/lv_draw_pxp.c @@ -210,11 +210,6 @@ static bool _pxp_draw_img_supported(const lv_draw_image_dsc_t * draw_dsc) { const lv_image_dsc_t * img_dsc = draw_dsc->src; - bool is_tiled = draw_dsc->tile; - /* Tiled image (repeat image) is currently not supported. */ - if(is_tiled) - return false; - bool has_recolor = (draw_dsc->recolor_opa > LV_OPA_MIN); bool has_transform = (draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE || draw_dsc->scale_y != LV_SCALE_NONE); diff --git a/src/draw/nxp/pxp/lv_draw_pxp_img.c b/src/draw/nxp/pxp/lv_draw_pxp_img.c index 320eaed2e7..2d1afccf2c 100644 --- a/src/draw/nxp/pxp/lv_draw_pxp_img.c +++ b/src/draw/nxp/pxp/lv_draw_pxp_img.c @@ -19,6 +19,8 @@ #if LV_USE_DRAW_PXP #include "lv_pxp_cfg.h" #include "lv_pxp_utils.h" +#include "../../lv_draw_image_private.h" +#include "../../lv_image_decoder_private.h" #include @@ -33,6 +35,9 @@ /********************** * STATIC PROTOTYPES **********************/ +static void _pxp_draw_core_cb(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); /* Blit w/ recolor for images w/o opa and alpha channel */ static void _pxp_blit_recolor(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t dest_stride, @@ -69,54 +74,58 @@ void lv_draw_pxp_img(lv_draw_task_t * t) if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) return; - lv_layer_t * layer = t->target_layer; - lv_draw_buf_t * draw_buf = layer->draw_buf; - const lv_image_dsc_t * img_dsc = dsc->src; - - lv_area_t rel_coords; - lv_area_copy(&rel_coords, coords); - lv_area_move(&rel_coords, -layer->buf_area.x1, -layer->buf_area.y1); - - lv_area_t rel_clip_area; - lv_area_copy(&rel_clip_area, &t->clip_area); - lv_area_move(&rel_clip_area, -layer->buf_area.x1, -layer->buf_area.y1); - - lv_area_t blend_area; - bool has_transform = (dsc->rotation != 0 || dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_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*/ - - const uint8_t * src_buf = img_dsc->data; - - lv_area_t src_area; - src_area.x1 = blend_area.x1 - (coords->x1 - layer->buf_area.x1); - src_area.y1 = blend_area.y1 - (coords->y1 - layer->buf_area.y1); - src_area.x2 = src_area.x1 + lv_area_get_width(&blend_area) - 1; - src_area.y2 = src_area.y1 + lv_area_get_height(&blend_area) - 1; - int32_t src_stride = img_dsc->header.stride; - lv_color_format_t src_cf = img_dsc->header.cf; - - uint8_t * dest_buf = draw_buf->data; - int32_t dest_stride = draw_buf->header.stride; - lv_color_format_t dest_cf = draw_buf->header.cf; - bool has_recolor = (dsc->recolor_opa > LV_OPA_MIN); - - if(has_recolor && !has_transform) - _pxp_blit_recolor(dest_buf, &blend_area, dest_stride, dest_cf, - src_buf, &src_area, src_stride, src_cf, dsc); - else if(has_transform) - _pxp_blit_transform(dest_buf, &blend_area, dest_stride, dest_cf, - src_buf, &src_area, src_stride, src_cf, dsc); + bool is_tiled = (dsc->tile != 0); + if(is_tiled) + lv_draw_image_tiled_helper(t, dsc, coords, _pxp_draw_core_cb); else - _pxp_blit(dest_buf, &blend_area, dest_stride, dest_cf, - src_buf, &src_area, src_stride, src_cf, dsc->opa); + lv_draw_image_normal_helper(t, dsc, coords, _pxp_draw_core_cb); } /********************** * STATIC FUNCTIONS **********************/ +static void _pxp_draw_core_cb(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_layer_t * layer = t->target_layer; + lv_draw_buf_t * draw_buf = layer->draw_buf; + const lv_draw_buf_t * decoded = decoder_dsc->decoded; + + lv_area_t rel_clip_area; + lv_area_copy(&rel_clip_area, clipped_img_area); + lv_area_move(&rel_clip_area, -img_coords->x1, -img_coords->y1); + + lv_area_t rel_img_coords; + lv_area_copy(&rel_img_coords, img_coords); + lv_area_move(&rel_img_coords, -img_coords->x1, -img_coords->y1); + + const uint8_t * src_buf = decoded->data; + + lv_area_t src_area; + if(!lv_area_intersect(&src_area, &rel_clip_area, &rel_img_coords)) + return; + + int32_t src_stride = draw_dsc->header.stride; + lv_color_format_t src_cf = draw_dsc->header.cf; + + uint8_t * dest_buf = draw_buf->data; + int32_t dest_stride = draw_buf->header.stride; + lv_color_format_t dest_cf = draw_buf->header.cf; + bool has_recolor = (draw_dsc->recolor_opa > LV_OPA_MIN); + bool has_transform = (draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE || + draw_dsc->scale_y != LV_SCALE_NONE); + + if(has_recolor && !has_transform) + _pxp_blit_recolor(dest_buf, clipped_img_area, dest_stride, dest_cf, + src_buf, &src_area, src_stride, src_cf, draw_dsc); + else if(has_transform) + _pxp_blit_transform(dest_buf, clipped_img_area, dest_stride, dest_cf, + src_buf, &src_area, src_stride, src_cf, draw_dsc); + else + _pxp_blit(dest_buf, clipped_img_area, dest_stride, dest_cf, + src_buf, &src_area, src_stride, src_cf, draw_dsc->opa); +} static void _pxp_blit_recolor(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t dest_stride, lv_color_format_t dest_cf, const uint8_t * src_buf, const lv_area_t * src_area, @@ -193,14 +202,6 @@ static void _pxp_blit_transform(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t dest_w = lv_area_get_width(dest_area); int32_t dest_h = lv_area_get_height(dest_area); - lv_point_t pivot = dsc->pivot; - /*The offsets are now relative to the transformation result with pivot ULC*/ - int32_t piv_offset_x = 0; - int32_t piv_offset_y = 0; - - int32_t trim_x = 0; - int32_t trim_y = 0; - bool has_rotation = (dsc->rotation != 0); bool has_scale = (dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE); uint8_t src_px_size = lv_color_format_get_size(src_cf); @@ -214,51 +215,23 @@ static void _pxp_blit_transform(uint8_t * dest_buf, const lv_area_t * dest_area, switch(dsc->rotation) { case 0: pxp_angle = kPXP_Rotate0; - piv_offset_x = 0; - piv_offset_y = 0; break; case 900: pxp_angle = kPXP_Rotate90; - piv_offset_x = pivot.x + pivot.y - src_h; - piv_offset_y = pivot.y - pivot.x; break; case 1800: pxp_angle = kPXP_Rotate180; - piv_offset_x = 2 * pivot.x - src_w; - piv_offset_y = 2 * pivot.y - src_h; break; case 2700: pxp_angle = kPXP_Rotate270; - piv_offset_x = pivot.x - pivot.y; - piv_offset_y = pivot.x + pivot.y - src_w; break; default: pxp_angle = kPXP_Rotate0; - piv_offset_x = 0; - piv_offset_y = 0; } /*PS buffer rotation and decimation does not function at the same time*/ PXP_SetRotateConfig(PXP_ID, kPXP_RotateOutputBuffer, pxp_angle, kPXP_FlipDisable); } - if(has_scale) { - float fp_scale_x = (float)dsc->scale_x / LV_SCALE_NONE; - float fp_scale_y = (float)dsc->scale_y / LV_SCALE_NONE; - int32_t int_scale_x = (int32_t)fp_scale_x; - int32_t int_scale_y = (int32_t)fp_scale_y; - - /*Any scale_factor in (k, k + 1] will result in a trim equal to k*/ - trim_x = (fp_scale_x == int_scale_x) ? int_scale_x - 1 : int_scale_x; - trim_y = (fp_scale_y == int_scale_y) ? int_scale_y - 1 : int_scale_y; - - dest_w = src_w * fp_scale_x + trim_x; - dest_h = src_h * fp_scale_y + trim_y; - - /*Final pivot offset = scale_factor * rotation_pivot_offset + scaling_pivot_offset*/ - piv_offset_x = floorf(fp_scale_x * piv_offset_x) - floorf((fp_scale_x - 1) * pivot.x); - piv_offset_y = floorf(fp_scale_y * piv_offset_y) - floorf((fp_scale_y - 1) * pivot.y); - } - /*PS buffer - source image*/ pxp_ps_buffer_config_t psBufferConfig = { .pixelFormat = pxp_get_ps_px_format(src_cf), @@ -269,7 +242,7 @@ static void _pxp_blit_transform(uint8_t * dest_buf, const lv_area_t * dest_area, .pitchBytes = src_stride }; PXP_SetProcessSurfaceBufferConfig(PXP_ID, &psBufferConfig); - PXP_SetProcessSurfacePosition(PXP_ID, 0U, 0U, dest_w - trim_x - 1U, dest_h - trim_y - 1U); + PXP_SetProcessSurfacePosition(PXP_ID, 0U, 0U, dest_w - 1U, dest_h - 1U); if(has_scale) PXP_SetProcessSurfaceScaler(PXP_ID, src_w, src_h, dest_w, dest_h); @@ -281,11 +254,11 @@ static void _pxp_blit_transform(uint8_t * dest_buf, const lv_area_t * dest_area, pxp_output_buffer_config_t outputBufferConfig = { .pixelFormat = pxp_get_out_px_format(dest_cf), .interlacedMode = kPXP_OutputProgressive, - .buffer0Addr = (uint32_t)(dest_buf + dest_stride * (dest_area->y1 + piv_offset_y) + dest_px_size * (dest_area->x1 + piv_offset_x)), + .buffer0Addr = (uint32_t)(dest_buf + dest_stride * (dest_area->y1) + dest_px_size * (dest_area->x1)), .buffer1Addr = (uint32_t)0U, .pitchBytes = dest_stride, - .width = dest_w - trim_x, - .height = dest_h - trim_y + .width = dest_w, + .height = dest_h }; PXP_SetOutputBufferConfig(PXP_ID, &outputBufferConfig);