From 8dc23791d1d8822fe8fd8491e7d6364c6ebb7523 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 30 Apr 2016 12:42:44 +0100 Subject: [PATCH] sna: Resize screen for XVidMode changes XVidMode has a custom entry point on the pScrn that is routed through to xf86 which has to match the requested mode against the available on the CompatOutput (and not the Primary!) and then tries to find matching modes on the other outputs. But xf86SetSingleMode() doesn't resize the screen afterwards, leaving the framebuffer as is. This prevents the XVidMode clients from being able to flip at the new mode as their Windows do not match the Screen size. References: https://bugs.freedesktop.org/show_bug.cgi?id=95200 Signed-off-by: Chris Wilson --- src/sna/sna.h | 1 + src/sna/sna_display.c | 32 ++++++++++++++++++++++++++++++++ src/sna/sna_driver.c | 9 ++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/sna/sna.h b/src/sna/sna.h index 664308f..ba79450 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -448,6 +448,7 @@ extern void sna_mode_discover(struct sna *sna, bool tell); extern void sna_mode_check(struct sna *sna); extern bool sna_mode_disable(struct sna *sna); extern void sna_mode_enable(struct sna *sna); +extern bool sna_mode_fit(struct sna *sna, int width, int height); extern void sna_mode_reset(struct sna *sna); extern int sna_mode_wakeup(struct sna *sna); extern void sna_mode_redisplay(struct sna *sna); diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index 759659d..3d87f35 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -5394,6 +5394,38 @@ sna_mode_resize(ScrnInfoPtr scrn, int width, int height) return TRUE; } +bool sna_mode_fit(struct sna *sna, int width, int height) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); + int total_width = 0, total_height = 0; + int i; + + for (i = 0; i < sna->mode.num_real_crtc; i++) { + xf86CrtcPtr crtc = config->crtc[i]; + + assert(to_sna_crtc(crtc)); + if (to_sna_crtc(crtc)->bo == NULL) + continue; + + if (crtc->bounds.x2 > total_width) + total_width = crtc->bounds.x2; + + if (crtc->bounds.y2 > total_height) + total_height = crtc->bounds.y2; + } + + if (total_width <= width && total_height <= height) { + ScreenPtr screen = xf86ScrnToScreen(sna->scrn); + rrScrPrivPtr rp = rrGetScrPriv(screen); + if (rp) + return rp->rrScreenSetSize(screen, width, height, + DEFAULT_DPI*width, + DEFAULT_DPI*height); + } + + return false; +} + /* cursor handling */ static void rotate_coord(Rotation rotation, int size, diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c index b245594..28157a7 100644 --- a/src/sna/sna_driver.c +++ b/src/sna/sna_driver.c @@ -1234,8 +1234,15 @@ static Bool sna_enter_vt(VT_FUNC_ARGS_DECL) static Bool sna_switch_mode(SWITCH_MODE_ARGS_DECL) { SCRN_INFO_PTR(arg); + DBG(("%s\n", __FUNCTION__)); - return xf86SetSingleMode(scrn, mode, RR_Rotate_0); + + if (!xf86SetSingleMode(scrn, mode, RR_Rotate_0)) + return FALSE; + + sna_mode_fit(to_sna(scrn), mode->HDisplay, mode->VDisplay); + + return TRUE; } static ModeStatus -- 2.8.1