mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-21 05:51:45 +08:00
fix(vg_lite_tvg): fix matrix calculation inconsistency with hardware behavior (#8666)
Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com> Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
@@ -165,15 +165,6 @@ static void draw_fill(lv_draw_vg_lite_unit_t * u,
|
||||
break;
|
||||
case LV_VECTOR_DRAW_STYLE_GRADIENT: {
|
||||
vg_lite_matrix_t grad_matrix = *matrix;
|
||||
|
||||
#if LV_USE_VG_LITE_THORVG
|
||||
/* Workaround inconsistent radial gradient matrix behavior between device and ThorVG */
|
||||
if(dsc->fill_dsc.gradient.style == LV_VECTOR_GRADIENT_STYLE_RADIAL) {
|
||||
/* Restore matrix to identity */
|
||||
vg_lite_identity(&grad_matrix);
|
||||
}
|
||||
#endif
|
||||
|
||||
vg_lite_matrix_t fill_matrix;
|
||||
lv_vg_lite_matrix(&fill_matrix, &dsc->fill_dsc.matrix);
|
||||
lv_vg_lite_matrix_multiply(&grad_matrix, &fill_matrix);
|
||||
|
||||
@@ -191,8 +191,7 @@ bool lv_vg_lite_draw_grad(
|
||||
vg_lite_linear_gradient_t * linear_grad = &grad_item->vg.linear;
|
||||
vg_lite_matrix_t * grad_mat_p = vg_lite_get_grad_matrix(linear_grad);
|
||||
LV_ASSERT_NULL(grad_mat_p);
|
||||
vg_lite_identity(grad_mat_p);
|
||||
lv_vg_lite_matrix_multiply(grad_mat_p, grad_matrix);
|
||||
*grad_mat_p = *grad_matrix;
|
||||
grad_point_to_matrix(grad_mat_p, grad->x1, grad->y1, grad->x2, grad->y2);
|
||||
|
||||
LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_draw_grad");
|
||||
|
||||
@@ -324,8 +324,8 @@ static void get_format_bytes(vg_lite_buffer_format_t format,
|
||||
vg_lite_uint32_t * bytes_align);
|
||||
|
||||
static vg_lite_fpoint_t matrix_transform_point(const vg_lite_matrix_t * matrix, const vg_lite_fpoint_t * point);
|
||||
static bool vg_lite_matrix_inverse(vg_lite_matrix_t * result, const vg_lite_matrix_t * matrix);
|
||||
static void vg_lite_matrix_multiply(vg_lite_matrix_t * matrix, const vg_lite_matrix_t * mult);
|
||||
static Result vg_lite_grad_matrix_conv(vg_lite_matrix_t * result, const vg_lite_matrix_t * grad_matrix,
|
||||
const vg_lite_matrix_t * path_matrix);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@@ -1464,10 +1464,13 @@ Empty_sequence_handler:
|
||||
TVG_CHECK_RETURN_VG_ERROR(shape->fill(fill_rule_conv(fill_rule)););
|
||||
TVG_CHECK_RETURN_VG_ERROR(shape->blend(blend_method_conv(blend)));
|
||||
|
||||
vg_lite_matrix_t grad_matrix;
|
||||
TVG_CHECK_RETURN_VG_ERROR(vg_lite_grad_matrix_conv(&grad_matrix, &grad->matrix, path_matrix));
|
||||
|
||||
auto linearGrad = LinearGradient::gen();
|
||||
TVG_CHECK_RETURN_VG_ERROR(linearGrad->linear(grad->linear_grad.X0, grad->linear_grad.Y0, grad->linear_grad.X1,
|
||||
grad->linear_grad.Y1));
|
||||
TVG_CHECK_RETURN_VG_ERROR(linearGrad->transform(matrix_conv(&grad->matrix)));
|
||||
TVG_CHECK_RETURN_VG_ERROR(linearGrad->transform(matrix_conv(&grad_matrix)));
|
||||
TVG_CHECK_RETURN_VG_ERROR(linearGrad->spread(fill_spread_conv(grad->spread_mode)));
|
||||
|
||||
tvg::Fill::ColorStop colorStops[VLC_MAX_COLOR_RAMP_STOPS];
|
||||
@@ -1919,9 +1922,7 @@ Empty_sequence_handler:
|
||||
TVG_CHECK_RETURN_VG_ERROR(shape->blend(blend_method_conv(blend)));
|
||||
|
||||
vg_lite_matrix_t grad_matrix;
|
||||
vg_lite_identity(&grad_matrix);
|
||||
vg_lite_matrix_inverse(&grad_matrix, matrix);
|
||||
vg_lite_matrix_multiply(&grad_matrix, &grad->matrix);
|
||||
TVG_CHECK_RETURN_VG_ERROR(vg_lite_grad_matrix_conv(&grad_matrix, &grad->matrix, matrix));
|
||||
|
||||
vg_lite_fpoint_t p1 = {0.0f, 0.0f};
|
||||
vg_lite_fpoint_t p2 = {1.0f, 0};
|
||||
@@ -1982,8 +1983,11 @@ Empty_sequence_handler:
|
||||
TVG_CHECK_RETURN_VG_ERROR(shape->fill(fill_rule_conv(fill_rule)););
|
||||
TVG_CHECK_RETURN_VG_ERROR(shape->blend(blend_method_conv(blend)));
|
||||
|
||||
vg_lite_matrix_t grad_matrix;
|
||||
TVG_CHECK_RETURN_VG_ERROR(vg_lite_grad_matrix_conv(&grad_matrix, &grad->matrix, path_matrix));
|
||||
|
||||
auto radialGrad = RadialGradient::gen();
|
||||
TVG_CHECK_RETURN_VG_ERROR(radialGrad->transform(matrix_conv(&grad->matrix)));
|
||||
TVG_CHECK_RETURN_VG_ERROR(radialGrad->transform(matrix_conv(&grad_matrix)));
|
||||
TVG_CHECK_RETURN_VG_ERROR(radialGrad->radial(grad->radial_grad.cx, grad->radial_grad.cy, grad->radial_grad.r));
|
||||
TVG_CHECK_RETURN_VG_ERROR(radialGrad->spread(fill_spread_conv(grad->spread_mode)));
|
||||
|
||||
@@ -2188,6 +2192,15 @@ static vg_lite_error_t vg_lite_error_conv(Result result)
|
||||
|
||||
static Matrix matrix_conv(const vg_lite_matrix_t * matrix)
|
||||
{
|
||||
static const Matrix identity = {
|
||||
1, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 1
|
||||
};
|
||||
if(!matrix) {
|
||||
return identity;
|
||||
}
|
||||
|
||||
return *(Matrix *)matrix;
|
||||
}
|
||||
|
||||
@@ -2990,4 +3003,25 @@ static void vg_lite_matrix_multiply(vg_lite_matrix_t * matrix, const vg_lite_mat
|
||||
lv_memcpy(matrix->m, &temp.m, sizeof(temp.m));
|
||||
}
|
||||
|
||||
static Result vg_lite_grad_matrix_conv(vg_lite_matrix_t * result, const vg_lite_matrix_t * grad_matrix,
|
||||
const vg_lite_matrix_t * path_matrix)
|
||||
{
|
||||
/**
|
||||
* Since Thorvg internally multiplies the path (shape) matrix with the gradient matrix to produce
|
||||
* the rendering result, and VG-Lite's gradient matrix and path matrix are completely independent,
|
||||
* requiring a previous multiplication to achieve the same rendering result,
|
||||
* for the VG-Lite emulator, it is necessary to offset the gradient matrix to obtain the user's original gradient matrix
|
||||
* to simulate hardware behavior:
|
||||
* matrix_out = path_matrix * gradient_matrix
|
||||
* =>
|
||||
* gradient_matrix = inv(path_matrix) * matrix_out
|
||||
*/
|
||||
if(!vg_lite_matrix_inverse(result, path_matrix)) {
|
||||
return Result::InvalidArguments;
|
||||
}
|
||||
|
||||
vg_lite_matrix_multiply(result, grad_matrix);
|
||||
return Result::Success;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user