diff --git a/src/others/vg_lite_tvg/vg_lite_tvg.cpp b/src/others/vg_lite_tvg/vg_lite_tvg.cpp index c9c10c03b1..0b54dd645b 100644 --- a/src/others/vg_lite_tvg/vg_lite_tvg.cpp +++ b/src/others/vg_lite_tvg/vg_lite_tvg.cpp @@ -501,6 +501,13 @@ static vg_lite_converter conv_bgra2222_to_bgr } }); +/* Used to copy images with inconsistent strides but the same color format */ +static vg_lite_converter conv_bgra8888_to_bgra8888( + [](vg_color32_t * dest, const vg_color32_t * src, vg_lite_uint32_t px_size, vg_lite_uint32_t /* color */) +{ + memcpy(dest, src, sizeof(vg_color32_t) * px_size); +}); + /********************** * MACROS **********************/ @@ -2491,13 +2498,21 @@ static Result canvas_set_target(vg_lite_ctx * ctx, vg_lite_buffer_t * target) ctx->target_px_size = target->width * target->height; void * canvas_target_buffer; + uint32_t stride = 0; + if(TVG_IS_VG_FMT_SUPPORT(target->format)) { /* if target format is supported by VG, use target buffer directly */ canvas_target_buffer = target->memory; + + /* support target stride */ + LV_ASSERT(target->stride >= target->width); + LV_ASSERT(VG_LITE_IS_ALIGNED(target->stride, sizeof(uint32_t))); + stride = target->stride / sizeof(uint32_t); } else { /* if target format is not supported by VG, use internal buffer */ canvas_target_buffer = ctx->get_temp_target_buffer(target->width, target->height); + stride = target->width; } /* Prevent repeated target setting */ @@ -2509,7 +2524,7 @@ static Result canvas_set_target(vg_lite_ctx * ctx, vg_lite_buffer_t * target) TVG_CHECK_RETURN_RESULT(ctx->canvas->target( (uint32_t *)ctx->tvg_target_buffer, - target->width, + stride, target->width, target->height, SwCanvas::ARGB8888)); @@ -2524,29 +2539,16 @@ static Result canvas_set_target(vg_lite_ctx * ctx, vg_lite_buffer_t * target) return Result::Success; } -static vg_lite_uint32_t width_to_stride(vg_lite_uint32_t w, vg_lite_buffer_format_t color_format) -{ - if(vg_lite_query_feature(gcFEATURE_BIT_VG_16PIXELS_ALIGN)) { - w = VG_LITE_ALIGN(w, 16); - } - - vg_lite_uint32_t mul, div, align; - get_format_bytes(color_format, &mul, &div, &align); - return VG_LITE_ALIGN((w * mul / div), align); -} - static bool decode_indexed_line( vg_lite_buffer_format_t color_format, const vg_lite_uint32_t * palette, int32_t x, int32_t y, - int32_t w_px, const uint8_t * in, vg_lite_uint32_t * out) + int32_t w_px, uint32_t stride, const uint8_t * in, vg_lite_uint32_t * out) { uint8_t px_size; uint16_t mask; - vg_lite_uint32_t w_byte = width_to_stride(w_px, color_format); - - in += w_byte * y; /*First pixel*/ + in += stride * y; /*First pixel*/ out += w_px * y; int8_t shift = 0; @@ -2598,17 +2600,18 @@ static Result picture_load(vg_lite_ctx * ctx, std::unique_ptr & picture vg_lite_uint32_t * image_buffer; LV_ASSERT(VG_LITE_IS_ALIGNED(source->memory, LV_VG_LITE_THORVG_BUF_ADDR_ALIGN)); -#if LV_VG_LITE_THORVG_16PIXELS_ALIGN - LV_ASSERT(VG_LITE_IS_ALIGNED(source->width, 16)); -#endif - - if(source->format == VG_LITE_BGRA8888 && source->image_mode == VG_LITE_NORMAL_IMAGE_MODE) { + /** + * Since ThorVG's picture->load does not support stride, + * reconversion is required when the stride and width do not match. + */ + if(source->format == VG_LITE_BGRA8888 + && source->image_mode == VG_LITE_NORMAL_IMAGE_MODE + && (size_t)source->stride == (size_t)(source->width * sizeof(vg_lite_uint32_t))) { image_buffer = (vg_lite_uint32_t *)source->memory; } else { vg_lite_uint32_t width = source->width; vg_lite_uint32_t height = source->height; - vg_lite_uint32_t px_size = width * height; image_buffer = ctx->get_image_buffer(width, height); vg_lite_buffer_t target; @@ -2617,7 +2620,7 @@ static Result picture_load(vg_lite_ctx * ctx, std::unique_ptr & picture target.format = VG_LITE_BGRA8888; target.width = width; target.height = height; - target.stride = width_to_stride(width, target.format); + target.stride = width * sizeof(vg_lite_uint32_t); switch(source->format) { case VG_LITE_INDEX_1: @@ -2626,7 +2629,7 @@ static Result picture_load(vg_lite_ctx * ctx, std::unique_ptr & picture case VG_LITE_INDEX_8: { const vg_lite_uint32_t * clut_colors = ctx->get_CLUT(source->format); for(vg_lite_uint32_t y = 0; y < height; y++) { - decode_indexed_line(source->format, clut_colors, 0, y, width, (uint8_t *)source->memory, image_buffer); + decode_indexed_line(source->format, clut_colors, 0, y, width, source->stride, (uint8_t *)source->memory, image_buffer); } } break; @@ -2691,7 +2694,8 @@ static Result picture_load(vg_lite_ctx * ctx, std::unique_ptr & picture #endif case VG_LITE_BGRA8888: { - memcpy(image_buffer, source->memory, px_size * sizeof(vg_color32_t)); + /* For stride conversion */ + conv_bgra8888_to_bgra8888.convert(&target, source); } break; @@ -2704,6 +2708,7 @@ static Result picture_load(vg_lite_ctx * ctx, std::unique_ptr & picture /* multiply color */ if(source->image_mode == VG_LITE_MULTIPLY_IMAGE_MODE && !VG_LITE_IS_ALPHA_FORMAT(source->format)) { vg_color32_t * dest = (vg_color32_t *)image_buffer; + vg_lite_uint32_t px_size = width * height; while(px_size--) { dest->alpha = UDIV255(dest->alpha * A(color)); dest->red = UDIV255(dest->red * B(color));