bdf207e
From a17f2aee7e46b4f0e4214fbbac5e1b1d12057dbe Mon Sep 17 00:00:00 2001
bdf207e
From: Hans De Goede <hdegoede@redhat.com>
bdf207e
Date: Tue, 22 Nov 2016 15:28:52 +0100
bdf207e
Subject: [PATCH xserver 2/2] randr: rrCheckPixmapBounding: do not shrink the
bdf207e
 screen_pixmap
bdf207e
bdf207e
The purpose of rrCheckPixmapBounding is to make sure that the
bdf207e
screen_pixmap is *large* enough for the slave-output which crtc is
bdf207e
being configured.
bdf207e
bdf207e
However until now rrCheckPixmapBounding would also shrink the
bdf207e
screen_pixmap in certain scenarios leading to various problems.
bdf207e
bdf207e
For example: Take a laptop with its internalscreen on a slave-output and
bdf207e
currently disabled and an external monitor at 1920x1080+0+0.
bdf207e
Now lets say that we want to drive the external monitor at its native
bdf207e
resolution of 2560x1440 and have the internal screen mirror the top left
bdf207e
part of the external monitor, so we run:
bdf207e
bdf207e
  $ xrandr --output eDP --mode 1920x1080 --pos 0x0 --output HDMI \
bdf207e
  --mode 2560x1440 --pos 0x0
bdf207e
bdf207e
Here xrandr utility first calls RRSetScreenSize to 2560x1440, then it
bdf207e
calls RRSetCrtc 1920x1080+0+0 on the eDP, since this is a slave output,
bdf207e
rrCheckPixmapBounding gets called and resizes the screen_pixmap to
bdf207e
1920x1080, undoing the RRSetScreenSize. Then RRSetCrtc 2560x1440+0+0
bdf207e
gets called on the HDMI, depending on crtc->transforms this will
bdf207e
either result in a BadValue error from ProcRRSetCrtcConfig; or
bdf207e
it will succeed, but the monitor ends up running at 2560x1440
bdf207e
while showing a 1920x1080 screen_pixmap + black borders on the right
bdf207e
and bottom. Neither of which is what we want.
bdf207e
bdf207e
This commit removes the troublesome shrinking behavior, fixing this.
bdf207e
bdf207e
Note:
bdf207e
bdf207e
1) One could argue that this will leave us with a too large screen_pixmap
bdf207e
in some cases, but rrCheckPixmapBounding only gets called for slave
bdf207e
outputs, so xrandr clients already must manually shrink the screen_pixmap
bdf207e
after disabling crtcs in normal setups.
bdf207e
bdf207e
2) An alternative approach would be to also call rrCheckPixmapBounding
bdf207e
on RRSetCrtc on normal (non-slave) outputs, but that would result in
bdf207e
2 unnecessary resizes of the screen_pixmap in the above example, which
bdf207e
seems undesirable.
bdf207e
bdf207e
Cc: Nikhil Mahale <nmahale@nvidia.com>
bdf207e
Cc: Dave Airlie <airlied@redhat.com>
bdf207e
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
bdf207e
---
bdf207e
 randr/rrcrtc.c | 6 ++++++
bdf207e
 1 file changed, 6 insertions(+)
bdf207e
bdf207e
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
bdf207e
index ac853ea..d1a51f0 100644
bdf207e
--- a/randr/rrcrtc.c
bdf207e
+++ b/randr/rrcrtc.c
bdf207e
@@ -689,6 +689,12 @@ rrCheckPixmapBounding(ScreenPtr pScreen,
bdf207e
     new_width = newsize->x2;
bdf207e
     new_height = newsize->y2;
bdf207e
 
bdf207e
+    if (new_width < screen_pixmap->drawable.width)
bdf207e
+        new_width = screen_pixmap->drawable.width;
bdf207e
+
bdf207e
+    if (new_height < screen_pixmap->drawable.height)
bdf207e
+        new_height = screen_pixmap->drawable.height;
bdf207e
+
bdf207e
     if (new_width == screen_pixmap->drawable.width &&
bdf207e
         new_height == screen_pixmap->drawable.height) {
bdf207e
     } else {
bdf207e
-- 
bdf207e
2.9.3
bdf207e