[PATCH 19/25] drm/amd/display: correct image viewport calculation

Bhawanpreet Lakha Bhawanpreet.Lakha at amd.com
Tue Jul 31 19:51:47 UTC 2018


From: Martin Tsai <Martin.Tsai at amd.com>

[why]
We didn't transfer the camera/video viewport coordinate
when doing rotation and mirror.

[how]
To correct the viewport coordinate in calculate_viewport().

Change-Id: I46f4c1fb2d3dc976e5164de373a5c58f0c8fb43a
Signed-off-by: Martin Tsai <Martin.Tsai at amd.com>
Reviewed-by: Charlene Liu <Charlene.Liu at amd.com>
Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 49 +++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 0db6651bc15b..21b5c4cb6f74 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -469,6 +469,18 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx)
 			pipe_ctx->bottom_pipe->plane_state == pipe_ctx->plane_state;
 	bool sec_split = pipe_ctx->top_pipe &&
 			pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state;
+	bool flip_vert_scan_dir = false, flip_horz_scan_dir = false;
+
+	/*
+	 * Need to calculate the scan direction for viewport to properly determine offset
+	 */
+	if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_180) {
+		flip_vert_scan_dir = true;
+		flip_horz_scan_dir = true;
+	} else if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_90)
+		flip_vert_scan_dir = true;
+	else if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270)
+		flip_horz_scan_dir = true;
 
 	if (stream->view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE ||
 		stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM) {
@@ -512,6 +524,34 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx)
 	data->viewport.height = clip.height *
 			surf_src.height / plane_state->dst_rect.height;
 
+	/* To transfer the x, y to correct coordinate on mirror image (camera).
+	 * deg  0 : transfer x,
+	 * deg 90 : don't need to transfer,
+	 * deg180 : transfer y,
+	 * deg270 : transfer x and y.
+	 * To transfer the x, y to correct coordinate on non-mirror image (video).
+	 * deg  0 : don't need to transfer,
+	 * 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 */
 	data->viewport_c.x = data->viewport.x / vpc_div;
 	data->viewport_c.y = data->viewport.y / vpc_div;
@@ -707,6 +747,15 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct rect *r
 		rect_swap_helper(&src);
 		rect_swap_helper(&data->viewport_c);
 		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;
 
-- 
2.14.1



More information about the amd-gfx mailing list