mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-27 11:57:48 +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
|
* 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;
|
ctx->target_px_size = target->width * target->height;
|
||||||
|
|
||||||
void * canvas_target_buffer;
|
void * canvas_target_buffer;
|
||||||
|
uint32_t stride = 0;
|
||||||
|
|
||||||
if(TVG_IS_VG_FMT_SUPPORT(target->format)) {
|
if(TVG_IS_VG_FMT_SUPPORT(target->format)) {
|
||||||
/* if target format is supported by VG, use target buffer directly */
|
/* if target format is supported by VG, use target buffer directly */
|
||||||
canvas_target_buffer = target->memory;
|
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 {
|
else {
|
||||||
/* if target format is not supported by VG, use internal buffer */
|
/* if target format is not supported by VG, use internal buffer */
|
||||||
canvas_target_buffer = ctx->get_temp_target_buffer(target->width, target->height);
|
canvas_target_buffer = ctx->get_temp_target_buffer(target->width, target->height);
|
||||||
|
stride = target->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prevent repeated target setting */
|
/* 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(
|
TVG_CHECK_RETURN_RESULT(ctx->canvas->target(
|
||||||
(uint32_t *)ctx->tvg_target_buffer,
|
(uint32_t *)ctx->tvg_target_buffer,
|
||||||
target->width,
|
stride,
|
||||||
target->width,
|
target->width,
|
||||||
target->height,
|
target->height,
|
||||||
SwCanvas::ARGB8888));
|
SwCanvas::ARGB8888));
|
||||||
@@ -2524,29 +2539,16 @@ static Result canvas_set_target(vg_lite_ctx * ctx, vg_lite_buffer_t * target)
|
|||||||
return Result::Success;
|
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(
|
static bool decode_indexed_line(
|
||||||
vg_lite_buffer_format_t color_format,
|
vg_lite_buffer_format_t color_format,
|
||||||
const vg_lite_uint32_t * palette,
|
const vg_lite_uint32_t * palette,
|
||||||
int32_t x, int32_t y,
|
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;
|
uint8_t px_size;
|
||||||
uint16_t mask;
|
uint16_t mask;
|
||||||
|
|
||||||
vg_lite_uint32_t w_byte = width_to_stride(w_px, color_format);
|
in += stride * y; /*First pixel*/
|
||||||
|
|
||||||
in += w_byte * y; /*First pixel*/
|
|
||||||
out += w_px * y;
|
out += w_px * y;
|
||||||
|
|
||||||
int8_t shift = 0;
|
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;
|
vg_lite_uint32_t * image_buffer;
|
||||||
LV_ASSERT(VG_LITE_IS_ALIGNED(source->memory, LV_VG_LITE_THORVG_BUF_ADDR_ALIGN));
|
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));
|
* Since ThorVG's picture->load does not support stride,
|
||||||
#endif
|
* 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) {
|
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;
|
image_buffer = (vg_lite_uint32_t *)source->memory;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
vg_lite_uint32_t width = source->width;
|
vg_lite_uint32_t width = source->width;
|
||||||
vg_lite_uint32_t height = source->height;
|
vg_lite_uint32_t height = source->height;
|
||||||
vg_lite_uint32_t px_size = width * height;
|
|
||||||
image_buffer = ctx->get_image_buffer(width, height);
|
image_buffer = ctx->get_image_buffer(width, height);
|
||||||
|
|
||||||
vg_lite_buffer_t target;
|
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.format = VG_LITE_BGRA8888;
|
||||||
target.width = width;
|
target.width = width;
|
||||||
target.height = height;
|
target.height = height;
|
||||||
target.stride = width_to_stride(width, target.format);
|
target.stride = width * sizeof(vg_lite_uint32_t);
|
||||||
|
|
||||||
switch(source->format) {
|
switch(source->format) {
|
||||||
case VG_LITE_INDEX_1:
|
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: {
|
case VG_LITE_INDEX_8: {
|
||||||
const vg_lite_uint32_t * clut_colors = ctx->get_CLUT(source->format);
|
const vg_lite_uint32_t * clut_colors = ctx->get_CLUT(source->format);
|
||||||
for(vg_lite_uint32_t y = 0; y < height; y++) {
|
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;
|
break;
|
||||||
@@ -2691,7 +2694,8 @@ static Result picture_load(vg_lite_ctx * ctx, std::unique_ptr<Picture> & picture
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
case VG_LITE_BGRA8888: {
|
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;
|
break;
|
||||||
|
|
||||||
@@ -2704,6 +2708,7 @@ static Result picture_load(vg_lite_ctx * ctx, std::unique_ptr<Picture> & picture
|
|||||||
/* multiply color */
|
/* multiply color */
|
||||||
if(source->image_mode == VG_LITE_MULTIPLY_IMAGE_MODE && !VG_LITE_IS_ALPHA_FORMAT(source->format)) {
|
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_color32_t * dest = (vg_color32_t *)image_buffer;
|
||||||
|
vg_lite_uint32_t px_size = width * height;
|
||||||
while(px_size--) {
|
while(px_size--) {
|
||||||
dest->alpha = UDIV255(dest->alpha * A(color));
|
dest->alpha = UDIV255(dest->alpha * A(color));
|
||||||
dest->red = UDIV255(dest->red * B(color));
|
dest->red = UDIV255(dest->red * B(color));
|
||||||
|
|||||||
Reference in New Issue
Block a user