xserver: Branch 'master' - 5 commits

Adam Jackson ajax at kemper.freedesktop.org
Mon Dec 5 16:49:26 UTC 2016


 hw/xfree86/common/xf86.h            |    1 +
 hw/xfree86/common/xf86Bus.c         |   32 +++++++++++++++++++++++++++-----
 hw/xfree86/common/xf86Globals.c     |    1 +
 hw/xfree86/common/xf86pciBus.c      |    4 ++++
 hw/xfree86/common/xf86platformBus.c |   19 +++++++++++++++++++
 hw/xfree86/common/xf86platformBus.h |    6 ++++++
 randr/rrcrtc.c                      |   10 ++++++++--
 7 files changed, 66 insertions(+), 7 deletions(-)

New commits:
commit 75c4f6e412e07c5d416fa9ad8d7defd972d2baa9
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Fri Sep 30 12:29:09 2016 +0200

    xfree86: Try harder to find atleast 1 non GPU Screen
    
    If we did not find any non GPU Screens, try again ignoring the notion
    of any video devices being the primary device. This fixes Xorg exiting
    with a "no screens found" error when using virtio-vga in a
    virtual-machine and when using a device driven by simpledrm.
    
    This is a somewhat ugly solution, but it is the best I can come up with
    without major surgery to the bus and probe code.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h
index e54c811..f724688 100644
--- a/hw/xfree86/common/xf86.h
+++ b/hw/xfree86/common/xf86.h
@@ -55,6 +55,7 @@
 extern _X_EXPORT int xf86DoConfigure;
 extern _X_EXPORT int xf86DoShowOptions;
 extern _X_EXPORT Bool xf86DoConfigurePass1;
+extern _X_EXPORT Bool xf86ProbeIgnorePrimary;
 extern _X_EXPORT Bool xorgHWAccess;
 
 extern _X_EXPORT DevPrivateKeyRec xf86ScreenKeyRec;
diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c
index a3a9898..9836803 100644
--- a/hw/xfree86/common/xf86Bus.c
+++ b/hw/xfree86/common/xf86Bus.c
@@ -117,14 +117,34 @@ xf86BusConfig(void)
     int i, j;
 
     /*
-     * Now call each of the Probe functions.  Each successful probe will
-     * result in an extra entry added to the xf86Screens[] list for each
-     * instance of the hardware found.
+     * 3 step probe to (hopefully) ensure that we always find at least 1
+     * (non GPU) screen:
+     *
+     * 1. Call each drivers probe function normally,
+     *    Each successful probe will result in an extra entry added to the
+     *    xf86Screens[] list for each instance of the hardware found.
      */
     for (i = 0; i < xf86NumDrivers; i++) {
         xf86CallDriverProbe(xf86DriverList[i], FALSE);
     }
 
+    /*
+     * 2. If no Screens were found, call each drivers probe function with
+     *    ignorePrimary = TRUE, to ensure that we do actually get a
+     *    Screen if there is atleast one supported video card.
+     */
+    if (xf86NumScreens == 0) {
+        xf86ProbeIgnorePrimary = TRUE;
+        for (i = 0; i < xf86NumDrivers && xf86NumScreens == 0; i++) {
+            xf86CallDriverProbe(xf86DriverList[i], FALSE);
+        }
+        xf86ProbeIgnorePrimary = FALSE;
+    }
+
+    /*
+     * 3. Call xf86platformAddGPUDevices() to add any additional video cards as
+     *    GPUScreens (GPUScreens are only supported by platformBus drivers).
+     */
     for (i = 0; i < xf86NumDrivers; i++) {
         xf86platformAddGPUDevices(xf86DriverList[i]);
     }
diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c
index 07cfabf..e962b75 100644
--- a/hw/xfree86/common/xf86Globals.c
+++ b/hw/xfree86/common/xf86Globals.c
@@ -152,6 +152,7 @@ XF86ConfigPtr xf86configptr = NULL;
 Bool xf86Resetting = FALSE;
 Bool xf86Initialising = FALSE;
 Bool xf86DoConfigure = FALSE;
+Bool xf86ProbeIgnorePrimary = FALSE;
 Bool xf86DoShowOptions = FALSE;
 DriverPtr *xf86DriverList = NULL;
 int xf86NumDrivers = 0;
diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c
index 8158c2b..9adfee5 100644
--- a/hw/xfree86/common/xf86pciBus.c
+++ b/hw/xfree86/common/xf86pciBus.c
@@ -352,6 +352,10 @@ xf86ComparePciBusString(const char *busID, int bus, int device, int func)
 Bool
 xf86IsPrimaryPci(struct pci_device *pPci)
 {
+    /* Add max. 1 screen for the IgnorePrimary fallback path */
+    if (xf86ProbeIgnorePrimary && xf86NumScreens == 0)
+        return TRUE;
+
     if (primaryBus.type == BUS_PCI)
         return pPci == primaryBus.id.pci;
 #ifdef XSERVER_PLATFORM_BUS
diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c
index 8dd0d5d..063e81c 100644
--- a/hw/xfree86/common/xf86platformBus.c
+++ b/hw/xfree86/common/xf86platformBus.c
@@ -114,6 +114,10 @@ xf86_find_platform_device_by_devnum(int major, int minor)
 static Bool
 xf86IsPrimaryPlatform(struct xf86_platform_device *plat)
 {
+    /* Add max. 1 screen for the IgnorePrimary fallback path */
+    if (xf86ProbeIgnorePrimary && xf86NumScreens == 0)
+        return TRUE;
+
     if (primaryBus.type == BUS_PLATFORM)
         return plat == primaryBus.id.plat;
 #ifdef XSERVER_LIBPCIACCESS
commit 7121b03d324fccf687d49b63c53da7c8d93038c9
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Fri Sep 30 11:59:04 2016 +0200

    xfree86: Make adding unclaimed devices as GPU devices a separate step
    
    This is primarily a preparation patch for fixing the xserver exiting with
    a "no screens found" error even though there are supported video cards,
    due to the server not recognizing any card as the primary card.
    
    This also fixes the (mostly theoretical) case of a platformBus capable
    driver adding a device as GPUscreen before a driver which only supports
    the old PCI probe method gets a chance to claim it as a normal screen.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c
index 27c6b1b..a3a9898 100644
--- a/hw/xfree86/common/xf86Bus.c
+++ b/hw/xfree86/common/xf86Bus.c
@@ -125,6 +125,10 @@ xf86BusConfig(void)
         xf86CallDriverProbe(xf86DriverList[i], FALSE);
     }
 
+    for (i = 0; i < xf86NumDrivers; i++) {
+        xf86platformAddGPUDevices(xf86DriverList[i]);
+    }
+
     /* If nothing was detected, return now */
     if (xf86NumScreens == 0) {
         xf86Msg(X_ERROR, "No devices detected.\n");
diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c
index 39fb1dd..8dd0d5d 100644
--- a/hw/xfree86/common/xf86platformBus.c
+++ b/hw/xfree86/common/xf86platformBus.c
@@ -475,6 +475,21 @@ xf86platformProbeDev(DriverPtr drvp)
                                         isGPUDevice(devList[i]) ? PLATFORM_PROBE_GPU_SCREEN : 0);
     }
 
+    return foundScreen;
+}
+
+int
+xf86platformAddGPUDevices(DriverPtr drvp)
+{
+    Bool foundScreen = FALSE;
+    GDevPtr *devList;
+    int j;
+
+    if (!drvp->platformProbe)
+        return FALSE;
+
+    xf86MatchDevice(drvp->driverName, &devList);
+
     /* if autoaddgpu devices is enabled then go find any unclaimed platform
      * devices and add them as GPU screens */
     if (xf86Info.autoAddGPU) {
diff --git a/hw/xfree86/common/xf86platformBus.h b/hw/xfree86/common/xf86platformBus.h
index a7335b9..0f5c0ef 100644
--- a/hw/xfree86/common/xf86platformBus.h
+++ b/hw/xfree86/common/xf86platformBus.h
@@ -41,6 +41,7 @@ struct xf86_platform_device {
 #ifdef XSERVER_PLATFORM_BUS
 int xf86platformProbe(void);
 int xf86platformProbeDev(DriverPtr drvp);
+int xf86platformAddGPUDevices(DriverPtr drvp);
 
 extern int xf86_num_platform_devices;
 extern struct xf86_platform_device *xf86_platform_devices;
@@ -156,6 +157,11 @@ xf86PlatformMatchDriver(char *matches[], int nmatches);
 
 extern void xf86platformVTProbe(void);
 extern void xf86platformPrimary(void);
+
+#else
+
+static inline int xf86platformAddGPUDevices(DriverPtr drvp) { return FALSE; }
+
 #endif
 
 #endif
commit b72d161cad15bec9dd082d30521c5383be526c56
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Tue Sep 27 14:30:10 2016 +0200

    xfree86: Remove redundant ServerIsNotSeat0 check from xf86CallDriverProbe
    
    If foundScreen is TRUE, then all the code below the removed if
    will not execute until we reach the return foundScreen; at the
    end, so this entire if block is redundant.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c
index 5b93940..27c6b1b 100644
--- a/hw/xfree86/common/xf86Bus.c
+++ b/hw/xfree86/common/xf86Bus.c
@@ -82,8 +82,6 @@ xf86CallDriverProbe(DriverPtr drv, Bool detect_only)
     if (!xf86DoConfigure && drv->platformProbe != NULL) {
         foundScreen = xf86platformProbeDev(drv);
     }
-    if (ServerIsNotSeat0() && foundScreen)
-        return foundScreen;
 #endif
 
 #ifdef XSERVER_LIBPCIACCESS
commit a46afee84d45fbff4e4dad9376afc95bbcc31d7c
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Tue Nov 22 14:53:20 2016 +0100

    randr: rrCheckPixmapBounding: do not shrink the screen_pixmap
    
    The purpose of rrCheckPixmapBounding is to make sure that the
    screen_pixmap is *large* enough for the slave-output which crtc is
    being configured.
    
    However until now rrCheckPixmapBounding would also shrink the
    screen_pixmap in certain scenarios leading to various problems.
    
    For example: Take a laptop with its internalscreen on a slave-output and
    currently disabled and an external monitor at 1920x1080+0+0.
    Now lets say that we want to drive the external monitor at its native
    resolution of 2560x1440 and have the internal screen mirror the top left
    part of the external monitor, so we run:
    
      $ xrandr --output eDP --mode 1920x1080 --pos 0x0 --output HDMI \
      --mode 2560x1440 --pos 0x0
    
    Here xrandr utility first calls RRSetScreenSize to 2560x1440, then it
    calls RRSetCrtc 1920x1080+0+0 on the eDP, since this is a slave output,
    rrCheckPixmapBounding gets called and resizes the screen_pixmap to
    1920x1080, undoing the RRSetScreenSize. Then RRSetCrtc 2560x1440+0+0
    gets called on the HDMI, depending on crtc->transforms this will
    either result in a BadValue error from ProcRRSetCrtcConfig; or
    it will succeed, but the monitor ends up running at 2560x1440
    while showing a 1920x1080 screen_pixmap + black borders on the right
    and bottom. Neither of which is what we want.
    
    This commit removes the troublesome shrinking behavior, fixing this.
    
    Note:
    
    1) One could argue that this will leave us with a too large screen_pixmap
    in some cases, but rrCheckPixmapBounding only gets called for slave
    outputs, so xrandr clients already must manually shrink the screen_pixmap
    after disabling crtcs in normal setups.
    
    2) An alternative approach would be to also call rrCheckPixmapBounding
    on RRSetCrtc on normal (non-slave) outputs, but that would result in
    2 unnecessary resizes of the screen_pixmap in the above example, which
    seems undesirable.
    
    Cc: Nikhil Mahale <nmahale at nvidia.com>
    Cc: Dave Airlie <airlied at redhat.com>
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Dave Airlie <airlied at redhat.com>

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index ac853ea..d1a51f0 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -689,6 +689,12 @@ rrCheckPixmapBounding(ScreenPtr pScreen,
     new_width = newsize->x2;
     new_height = newsize->y2;
 
+    if (new_width < screen_pixmap->drawable.width)
+        new_width = screen_pixmap->drawable.width;
+
+    if (new_height < screen_pixmap->drawable.height)
+        new_height = screen_pixmap->drawable.height;
+
     if (new_width == screen_pixmap->drawable.width &&
         new_height == screen_pixmap->drawable.height) {
     } else {
commit 3b624aa9a9df86dc7d48149e0f18ca223b4355f1
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Tue Nov 22 14:48:14 2016 +0100

    randr: rrCheckPixmapBounding: Do not substract crtc non 0 x,y from screen size
    
    The purpose of rrCheckPixmapBounding is to make sure that the
    screen_pixmap is large enough for the slave-output which crtc is
    being configured.
    
    This should include crtc->x and crtc->y, otherwise the crtc might
    still end up scanning out an area outside of the screen-pixmap.
    
    For example: Take a laptop with an external monitor on a slave-output at
    1920x1080+0+0 and its internal-screen at 3840x2160+1920+0 and in
    gnome-settings-daemon move the external monitor to be on the ri ght of
    the internal screen rather then on the left. First g-s-d will do a
    RRSetScreenSize to 5760*2160 (which is a nop), then it calls RRSetCrtc
    to move the slave output to 1920x1080+3840+0, since this is a slave
    output, rrCheckPixmapBounding gets called, since the 2 crtcs now overlap
    the code before this commit would shrinks the screen_pixmap to 3180*2160.
    Then g-s-d calls RRSetCrtc to move the internal screen to 3180*2160+0+0.
    
    And we end up with the slave-output configured to scan-out an area
    which completely falls outside of the screen-pixmap (and end up with
    a black display on the external monitor).
    
    This commit fixes this by not substracting the x1 and y1 coordinates
    of the union-ed region when determining the new screen_pixmap size.
    
    Cc: Nikhil Mahale <nmahale at nvidia.com>
    Cc: Dave Airlie <airlied at redhat.com>
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Dave Airlie <airlied at redhat.com>

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 5d404e8..ac853ea 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -686,8 +686,8 @@ rrCheckPixmapBounding(ScreenPtr pScreen,
     }
 
     newsize = RegionExtents(&total_region);
-    new_width = newsize->x2 - newsize->x1;
-    new_height = newsize->y2 - newsize->y1;
+    new_width = newsize->x2;
+    new_height = newsize->y2;
 
     if (new_width == screen_pixmap->drawable.width &&
         new_height == screen_pixmap->drawable.height) {


More information about the xorg-commit mailing list