Commit 83d40659 authored by Dmytro Laktyushkin's avatar Dmytro Laktyushkin Committed by Alex Deucher

drm/amd/display: fix mirror rotation scaling math

Curretly dc will incorrectly calculate viewport when there is
rotation or mirror being applied
Signed-off-by: default avatarDmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Reviewed-by: default avatarSu Chung <Su.Chung@amd.com>
Acked-by: default avatarLeo Li <sunpeng.li@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent ba7b267a
...@@ -499,8 +499,13 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx) ...@@ -499,8 +499,13 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx)
pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state; pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state;
bool flip_vert_scan_dir = false, flip_horz_scan_dir = false; bool flip_vert_scan_dir = false, flip_horz_scan_dir = false;
/* /*
* Need to calculate the scan direction for viewport to properly determine offset * We need take horizontal mirror into account. On an unrotated surface this means
* that the viewport offset is actually the offset from the other side of source
* image so we have to subtract the right edge of the viewport from the right edge of
* the source window. Similar to mirror we need to take into account how offset is
* affected for 270/180 rotations
*/ */
if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_180) { if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_180) {
flip_vert_scan_dir = true; flip_vert_scan_dir = true;
...@@ -510,6 +515,9 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx) ...@@ -510,6 +515,9 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx)
else if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) else if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270)
flip_horz_scan_dir = true; flip_horz_scan_dir = true;
if (pipe_ctx->plane_state->horizontal_mirror)
flip_horz_scan_dir = !flip_horz_scan_dir;
if (stream->view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE || if (stream->view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE ||
stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM) { stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM) {
pri_split = false; pri_split = false;
...@@ -540,45 +548,27 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx) ...@@ -540,45 +548,27 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx)
plane_state->clip_rect.y + plane_state->clip_rect.height - clip.y ; plane_state->clip_rect.y + plane_state->clip_rect.height - clip.y ;
/* offset = surf_src.ofs + (clip.ofs - surface->dst_rect.ofs) * scl_ratio /* offset = surf_src.ofs + (clip.ofs - surface->dst_rect.ofs) * scl_ratio
* note: surf_src.ofs should be added after rotation/mirror offset direction
* adjustment since it is already in viewport space
* num_pixels = clip.num_pix * scl_ratio * num_pixels = clip.num_pix * scl_ratio
*/ */
data->viewport.x = surf_src.x + (clip.x - plane_state->dst_rect.x) * data->viewport.x = (clip.x - plane_state->dst_rect.x) *
surf_src.width / plane_state->dst_rect.width; surf_src.width / plane_state->dst_rect.width;
data->viewport.width = clip.width * data->viewport.width = clip.width *
surf_src.width / plane_state->dst_rect.width; surf_src.width / plane_state->dst_rect.width;
data->viewport.y = surf_src.y + (clip.y - plane_state->dst_rect.y) * data->viewport.y = (clip.y - plane_state->dst_rect.y) *
surf_src.height / plane_state->dst_rect.height; surf_src.height / plane_state->dst_rect.height;
data->viewport.height = clip.height * data->viewport.height = clip.height *
surf_src.height / plane_state->dst_rect.height; surf_src.height / plane_state->dst_rect.height;
/* To transfer the x, y to correct coordinate on mirror image (camera). if (flip_vert_scan_dir)
* deg 0 : transfer x, data->viewport.y = surf_src.height - data->viewport.y - data->viewport.height;
* deg 90 : don't need to transfer, if (flip_horz_scan_dir)
* deg180 : transfer y, data->viewport.x = surf_src.width - data->viewport.x - data->viewport.width;
* deg270 : transfer x and y.
* To transfer the x, y to correct coordinate on non-mirror image (video). data->viewport.x += surf_src.x;
* deg 0 : don't need to transfer, data->viewport.y += surf_src.y;
* deg 90 : transfer y,
* deg180 : transfer x and y,
* deg270 : transfer x.
*/
if (pipe_ctx->plane_state->horizontal_mirror) {
if (flip_horz_scan_dir && !flip_vert_scan_dir) {
data->viewport.y = surf_src.height - data->viewport.y - data->viewport.height;
data->viewport.x = surf_src.width - data->viewport.x - data->viewport.width;
} else if (flip_horz_scan_dir && flip_vert_scan_dir)
data->viewport.y = surf_src.height - data->viewport.y - data->viewport.height;
else {
if (!flip_horz_scan_dir && !flip_vert_scan_dir)
data->viewport.x = surf_src.width - data->viewport.x - data->viewport.width;
}
} else {
if (flip_horz_scan_dir)
data->viewport.x = surf_src.width - data->viewport.x - data->viewport.width;
if (flip_vert_scan_dir)
data->viewport.y = surf_src.height - data->viewport.y - data->viewport.height;
}
/* Round down, compensate in init */ /* Round down, compensate in init */
data->viewport_c.x = data->viewport.x / vpc_div; data->viewport_c.x = data->viewport.x / vpc_div;
...@@ -773,22 +763,15 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct rect *r ...@@ -773,22 +763,15 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct rect *r
else if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) else if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270)
flip_horz_scan_dir = true; flip_horz_scan_dir = true;
if (pipe_ctx->plane_state->horizontal_mirror)
flip_horz_scan_dir = !flip_horz_scan_dir;
if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_90 || if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_90 ||
pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) { pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) {
rect_swap_helper(&src); rect_swap_helper(&src);
rect_swap_helper(&data->viewport_c); rect_swap_helper(&data->viewport_c);
rect_swap_helper(&data->viewport); rect_swap_helper(&data->viewport);
}
if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270 &&
pipe_ctx->plane_state->horizontal_mirror) {
flip_vert_scan_dir = true;
}
if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_90 &&
pipe_ctx->plane_state->horizontal_mirror) {
flip_vert_scan_dir = false;
}
} else if (pipe_ctx->plane_state->horizontal_mirror)
flip_horz_scan_dir = !flip_horz_scan_dir;
/* /*
* Init calculated according to formula: * Init calculated according to formula:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment