mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
drm/rockchip: vop2: update color-encoding selection policy for post-csc
When all layers are rgb, the post-csc input color encoding is fixed to rgb full, and the value of input_color_encoding has no actual utility. If there are any yuv planes, value of post-csc input_color_encoding selects the value of the yuv plane with the largest area. Change-Id: If624730e93a5ac03fc334890074883b9e6b828eb Signed-off-by: Algea Cao <algea.cao@rock-chips.com>
This commit is contained in:
@@ -698,7 +698,8 @@ enum vop_hdr_format {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct post_csc_convert_mode {
|
struct post_csc_convert_mode {
|
||||||
enum drm_color_encoding color_encoding;
|
enum drm_color_encoding intput_color_encoding;
|
||||||
|
enum drm_color_encoding output_color_encoding;
|
||||||
bool is_input_yuv;
|
bool is_input_yuv;
|
||||||
bool is_output_yuv;
|
bool is_output_yuv;
|
||||||
bool is_input_full_range;
|
bool is_input_full_range;
|
||||||
|
|||||||
@@ -12844,23 +12844,33 @@ static void vop3_post_csc_config(struct drm_crtc *crtc, struct post_acm *acm, st
|
|||||||
struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
|
struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
|
||||||
struct vop2 *vop2 = vp->vop2;
|
struct vop2 *vop2 = vp->vop2;
|
||||||
struct drm_plane *plane;
|
struct drm_plane *plane;
|
||||||
struct drm_plane_state *pstate;
|
struct drm_plane_state *pstate, *pstate_max = NULL;
|
||||||
|
struct vop2_plane_state *vpstate;
|
||||||
struct post_csc_coef csc_coef = {};
|
struct post_csc_coef csc_coef = {};
|
||||||
struct post_csc_convert_mode convert_mode = {};
|
struct post_csc_convert_mode convert_mode = {};
|
||||||
|
struct drm_rect *dest;
|
||||||
bool acm_enable;
|
bool acm_enable;
|
||||||
bool post_r2y_en = false;
|
bool post_r2y_en = false;
|
||||||
bool post_csc_en = false;
|
bool post_csc_en = false;
|
||||||
bool has_yuv_plane = false;
|
|
||||||
int range_type;
|
int range_type;
|
||||||
|
u64 max_yuv_plane = 0, plane_area;
|
||||||
|
enum drm_color_encoding max_yuv_plane_color_encoding = DRM_COLOR_YCBCR_BT601;
|
||||||
|
|
||||||
drm_atomic_crtc_for_each_plane(plane, crtc) {
|
drm_atomic_crtc_for_each_plane(plane, crtc) {
|
||||||
struct vop2_win *win = to_vop2_win(plane);
|
struct vop2_win *win = to_vop2_win(plane);
|
||||||
|
|
||||||
pstate = win->base.state;
|
pstate = win->base.state;
|
||||||
|
vpstate = to_vop2_plane_state(pstate);
|
||||||
|
dest = &vpstate->dest;
|
||||||
|
|
||||||
if (pstate->fb->format->is_yuv) {
|
if (pstate->fb->format->is_yuv) {
|
||||||
has_yuv_plane = true;
|
plane_area = drm_rect_width(dest) * drm_rect_height(dest);
|
||||||
break;
|
/* find yuv plane with largest area */
|
||||||
|
if (max_yuv_plane < plane_area) {
|
||||||
|
max_yuv_plane = plane_area;
|
||||||
|
max_yuv_plane_color_encoding = pstate->color_encoding;
|
||||||
|
pstate_max = pstate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12898,9 +12908,9 @@ static void vop3_post_csc_config(struct drm_crtc *crtc, struct post_acm *acm, st
|
|||||||
convert_mode.is_input_full_range = true;
|
convert_mode.is_input_full_range = true;
|
||||||
else if (vcstate->yuv_overlay)
|
else if (vcstate->yuv_overlay)
|
||||||
convert_mode.is_input_full_range = false;
|
convert_mode.is_input_full_range = false;
|
||||||
else if (has_yuv_plane)
|
else if (pstate_max)
|
||||||
convert_mode.is_input_full_range =
|
convert_mode.is_input_full_range =
|
||||||
pstate->color_range == DRM_COLOR_YCBCR_FULL_RANGE ? 1 : 0;
|
pstate_max->color_range == DRM_COLOR_YCBCR_FULL_RANGE ? 1 : 0;
|
||||||
else
|
else
|
||||||
convert_mode.is_input_full_range =
|
convert_mode.is_input_full_range =
|
||||||
vcstate->color_range == DRM_COLOR_YCBCR_FULL_RANGE ? 1 : 0;
|
vcstate->color_range == DRM_COLOR_YCBCR_FULL_RANGE ? 1 : 0;
|
||||||
@@ -12911,10 +12921,19 @@ static void vop3_post_csc_config(struct drm_crtc *crtc, struct post_acm *acm, st
|
|||||||
vcstate->post_csc_mode = vop2_convert_csc_mode(vcstate->color_encoding, vcstate->color_range, CSC_13BIT_DEPTH);
|
vcstate->post_csc_mode = vop2_convert_csc_mode(vcstate->color_encoding, vcstate->color_range, CSC_13BIT_DEPTH);
|
||||||
|
|
||||||
if (post_csc_en) {
|
if (post_csc_en) {
|
||||||
if (has_yuv_plane)
|
convert_mode.output_color_encoding = vcstate->color_encoding;
|
||||||
convert_mode.color_encoding = pstate->color_encoding;
|
/*
|
||||||
|
* When all layers are rgb, the post-csc input color encoding
|
||||||
|
* is fixed to rgb full, and the value of input_color_encoding
|
||||||
|
* has no actual utility.
|
||||||
|
* If there are any yuv planes, value of post-csc input_color_encoding
|
||||||
|
* selects the value of the yuv plane with the largest area.
|
||||||
|
*/
|
||||||
|
if (!pstate_max && !vcstate->yuv_overlay)
|
||||||
|
convert_mode.intput_color_encoding = vcstate->color_encoding;
|
||||||
else
|
else
|
||||||
convert_mode.color_encoding = vcstate->color_encoding;
|
convert_mode.intput_color_encoding = max_yuv_plane_color_encoding;
|
||||||
|
|
||||||
rockchip_calc_post_csc(csc, &csc_coef, &convert_mode);
|
rockchip_calc_post_csc(csc, &csc_coef, &convert_mode);
|
||||||
|
|
||||||
VOP_MODULE_SET(vop2, vp, csc_coe00, csc_coef.csc_coef00);
|
VOP_MODULE_SET(vop2, vp, csc_coe00, csc_coef.csc_coef00);
|
||||||
|
|||||||
@@ -1063,24 +1063,37 @@ enum color_space_type get_color_space_type(enum drm_color_encoding color_encodin
|
|||||||
return color_space_type;
|
return color_space_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int csc_get_mode_index(bool is_input_full_range, bool is_output_full_range,
|
static int csc_get_mode_index(struct post_csc_convert_mode *convert_mode)
|
||||||
bool is_input_yuv, bool is_output_yuv,
|
|
||||||
enum drm_color_encoding color_encoding)
|
|
||||||
{
|
{
|
||||||
const struct rk_csc_colorspace_info *colorspace_info;
|
const struct rk_csc_colorspace_info *colorspace_info;
|
||||||
int i;
|
int i, j;
|
||||||
enum color_space_type input_color_space, output_color_space;
|
enum color_space_type input_color_space, output_color_space;
|
||||||
|
bool is_input_full_range = convert_mode->is_input_full_range;
|
||||||
|
bool is_output_full_range = convert_mode->is_output_full_range;
|
||||||
|
bool is_input_yuv = convert_mode->is_input_yuv;
|
||||||
|
bool is_output_yuv = convert_mode->is_output_yuv;
|
||||||
|
|
||||||
input_color_space = get_color_space_type(color_encoding, is_input_yuv);
|
for (i = 0; i < 2; i++) {
|
||||||
output_color_space = get_color_space_type(color_encoding, is_output_yuv);
|
input_color_space = get_color_space_type(convert_mode->intput_color_encoding,
|
||||||
|
is_input_yuv);
|
||||||
|
output_color_space = get_color_space_type(convert_mode->output_color_encoding,
|
||||||
|
is_output_yuv);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(g_mode_csc_coef); i++) {
|
for (j = 0; j < ARRAY_SIZE(g_mode_csc_coef); j++) {
|
||||||
colorspace_info = &g_mode_csc_coef[i].st_csc_color_info;
|
colorspace_info = &g_mode_csc_coef[j].st_csc_color_info;
|
||||||
if (colorspace_info->input_color_space == input_color_space &&
|
if (colorspace_info->input_color_space == input_color_space &&
|
||||||
colorspace_info->output_color_space == output_color_space &&
|
colorspace_info->output_color_space == output_color_space &&
|
||||||
colorspace_info->in_full_range == is_input_full_range &&
|
colorspace_info->in_full_range == is_input_full_range &&
|
||||||
colorspace_info->out_full_range == is_output_full_range)
|
colorspace_info->out_full_range == is_output_full_range)
|
||||||
return i;
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If no csc matrix can be found for current input/output
|
||||||
|
* colorspace of post-csc, then csc matrix is found based
|
||||||
|
* on colorspace of post-csc output.
|
||||||
|
*/
|
||||||
|
convert_mode->intput_color_encoding = convert_mode->output_color_encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -1529,9 +1542,7 @@ int rockchip_calc_post_csc(struct post_csc *csc_cfg, struct post_csc_coef *csc_s
|
|||||||
const struct rk_csc_mode_coef *csc_mode_cfg;
|
const struct rk_csc_mode_coef *csc_mode_cfg;
|
||||||
int bit_num = PQ_CSC_SIMPLE_MAT_PARAM_FIX_BIT_WIDTH;
|
int bit_num = PQ_CSC_SIMPLE_MAT_PARAM_FIX_BIT_WIDTH;
|
||||||
|
|
||||||
ret = csc_get_mode_index(convert_mode->is_input_full_range,
|
ret = csc_get_mode_index(convert_mode);
|
||||||
convert_mode->is_output_full_range, convert_mode->is_input_yuv,
|
|
||||||
convert_mode->is_output_yuv, convert_mode->color_encoding);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
DRM_ERROR("get csc index err:\n");
|
DRM_ERROR("get csc index err:\n");
|
||||||
DRM_ERROR("input yuv %d full_range %d,output yuv %d full_range %d\n",
|
DRM_ERROR("input yuv %d full_range %d,output yuv %d full_range %d\n",
|
||||||
|
|||||||
Reference in New Issue
Block a user