diff options
author | Ilia Mirkin <imirkin@alum.mit.edu> | 2019-05-26 01:41:49 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-10-01 09:26:12 +0300 |
commit | 91ae87240166eee37fb9e3648a4ff8815e9cb3e0 (patch) | |
tree | 41c839b26e154e0c7701cb8335a0ccd49340d420 /drivers/gpu/drm/nouveau | |
parent | 3717f4a49b34810f8926e523a478c961a426f724 (diff) | |
download | linux-91ae87240166eee37fb9e3648a4ff8815e9cb3e0.tar.xz |
drm/nouveau/disp/nv50-: fix center/aspect-corrected scaling
[ Upstream commit 533f4752407543f488a9118d817b8c504352b6fb ]
Previously center scaling would get scaling applied to it (when it was
only supposed to center the image), and aspect-corrected scaling did not
always correctly pick whether to reduce width or height for a particular
combination of inputs/outputs.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=110660
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r-- | drivers/gpu/drm/nouveau/dispnv50/head.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c index d81a99bb2ac3..b041ffb3af27 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head.c @@ -169,14 +169,34 @@ nv50_head_atomic_check_view(struct nv50_head_atom *armh, */ switch (mode) { case DRM_MODE_SCALE_CENTER: - asyh->view.oW = min((u16)umode->hdisplay, asyh->view.oW); - asyh->view.oH = min((u16)umode_vdisplay, asyh->view.oH); - /* fall-through */ + /* NOTE: This will cause scaling when the input is + * larger than the output. + */ + asyh->view.oW = min(asyh->view.iW, asyh->view.oW); + asyh->view.oH = min(asyh->view.iH, asyh->view.oH); + break; case DRM_MODE_SCALE_ASPECT: - if (asyh->view.oH < asyh->view.oW) { + /* Determine whether the scaling should be on width or on + * height. This is done by comparing the aspect ratios of the + * sizes. If the output AR is larger than input AR, that means + * we want to change the width (letterboxed on the + * left/right), otherwise on the height (letterboxed on the + * top/bottom). + * + * E.g. 4:3 (1.333) AR image displayed on a 16:10 (1.6) AR + * screen will have letterboxes on the left/right. However a + * 16:9 (1.777) AR image on that same screen will have + * letterboxes on the top/bottom. + * + * inputAR = iW / iH; outputAR = oW / oH + * outputAR > inputAR is equivalent to oW * iH > iW * oH + */ + if (asyh->view.oW * asyh->view.iH > asyh->view.iW * asyh->view.oH) { + /* Recompute output width, i.e. left/right letterbox */ u32 r = (asyh->view.iW << 19) / asyh->view.iH; asyh->view.oW = ((asyh->view.oH * r) + (r / 2)) >> 19; } else { + /* Recompute output height, i.e. top/bottom letterbox */ u32 r = (asyh->view.iH << 19) / asyh->view.iW; asyh->view.oH = ((asyh->view.oW * r) + (r / 2)) >> 19; } |