mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-21 05:51:45 +08:00
fix(vg_lite_tvg): fix incorrect stride handling (#8648)
Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com> Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
@@ -501,6 +501,13 @@ static vg_lite_converter<vg_color32_t, vg_color_bgra2222_t> conv_bgra2222_to_bgr
|
||||
}
|
||||
});
|
||||
|
||||
/* Used to copy images with inconsistent strides but the same color format */
|
||||
static vg_lite_converter<vg_color32_t, vg_color32_t> 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> & 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> & 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> & 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> & 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> & 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));
|
||||
|
||||
Reference in New Issue
Block a user