summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
diff options
context:
space:
mode:
authorDmytro Laktyushkin2018-10-17 00:00:29 +0200
committerAlex Deucher2018-11-05 20:21:41 +0100
commit83d4065991f044def34607b654096fd5712f059f (patch)
treea2d4dd3d0923ccc665213dca61a5194098952dcd /drivers/gpu/drm/amd/display/dc/core/dc_resource.c
parentdrm/amd/display: Retiring set_display_requirements in dm_pp_smu.h - part4 (diff)
downloadkernel-qcow2-linux-83d4065991f044def34607b654096fd5712f059f.tar.gz
kernel-qcow2-linux-83d4065991f044def34607b654096fd5712f059f.tar.xz
kernel-qcow2-linux-83d4065991f044def34607b654096fd5712f059f.zip
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: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> Reviewed-by: Su Chung <Su.Chung@amd.com> Acked-by: Leo Li <sunpeng.li@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/core/dc_resource.c')
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_resource.c65
1 files changed, 24 insertions, 41 deletions
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 d68906b90399..fc65b0055167 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -499,8 +499,13 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx)
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
+ * 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) {
flip_vert_scan_dir = true;
@@ -510,6 +515,9 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx)
else if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270)
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 ||
stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM) {
pri_split = false;
@@ -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 ;
/* 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
*/
- 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;
data->viewport.width = clip.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;
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;
- }
+ if (flip_vert_scan_dir)
+ data->viewport.y = surf_src.height - data->viewport.y - data->viewport.height;
+ if (flip_horz_scan_dir)
+ data->viewport.x = surf_src.width - data->viewport.x - data->viewport.width;
+
+ data->viewport.x += surf_src.x;
+ data->viewport.y += surf_src.y;
/* Round down, compensate in init */
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
else if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270)
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 ||
pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) {
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;
+ }
/*
* Init calculated according to formula: