xserver: Branch 'server-1.20-branch' - 3 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Dec 1 15:56:38 UTC 2020


 hw/xfree86/drivers/modesetting/driver.c          |   25 +++++++++-
 hw/xfree86/drivers/modesetting/drmmode_display.c |   53 +++++++++++++++--------
 hw/xfree86/drivers/modesetting/drmmode_display.h |    4 +
 present/present_wnmd.c                           |    8 ++-
 4 files changed, 66 insertions(+), 24 deletions(-)

New commits:
commit 440ed5948ba5818abf5ea5fdc5a9d98514658fd3
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Tue Dec 1 11:25:31 2020 +0100

    present/wnmd: Translate update region to screen space
    
    The region as passed in is in the source pixmap's coordinate space, so
    intersecting it with the clipList (which is in screen space) resulted in
    disappointment.
    
    Fixes Firefox popups such as the hamburger menu when using the EGL
    backend.
    
    v2:
    * Drop vblank->x/y_off from RegionTranslate call, since they're always
      0 here (present_wnmd_check_flip rejects flips for x/y_off != 0).
    
    Reported-by: Robert Mader <robert.mader at posteo.de>
    Tested-by: Robert Mader <robert.mader at posteo.de>
    Reviewed-by: Olivier Fourdan <ofourdan at redhat.com>
    Tested-by: Joakim Tjernlund <joakim.tjernlund at infinera.com> # v1
    (cherry picked from commit 466b8b43fb355c6040cee45406860b8b8c04e948)

diff --git a/present/present_wnmd.c b/present/present_wnmd.c
index 8c31619a2..a2e00cebb 100644
--- a/present/present_wnmd.c
+++ b/present/present_wnmd.c
@@ -473,10 +473,13 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
 
             /* Set update region as damaged */
             if (vblank->update) {
-                damage = vblank->update;
+                damage = RegionDuplicate(vblank->update);
+                /* Translate update region to screen space */
+                assert(vblank->x_off == 0 && vblank->y_off == 0);
+                RegionTranslate(damage, window->drawable.x, window->drawable.y);
                 RegionIntersect(damage, damage, &window->clipList);
             } else
-                damage = &window->clipList;
+                damage = RegionDuplicate(&window->clipList);
 
             /* Try to flip - the vblank is now pending
              */
@@ -498,6 +501,7 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
 
                 /* Report damage */
                 DamageDamageRegion(&vblank->window->drawable, damage);
+                RegionDestroy(damage);
                 return;
             }
 
commit 54f9af1c61bd10e2e65cbb17069e0c9ec1f9a2c5
Author: Kishore Kadiyala <kishore.kadiyala at intel.com>
Date:   Tue Dec 1 11:13:51 2020 +0100

    modesetting: keep going if a modeset fails on EnterVT
    
    There was a time when setting a mode on a CRTC would not depend on the
    associated connector's state. If a mode had been set successfully once,
    it would mean it would work later on.
    
    This changed with the introduction of new connectors type that now
    require a link training sequence (DP, HDMI 2.0), and that means that
    some events may have happened while the X server was not master that
    would then prevent the mode from successfully be restored to its
    previous state.
    
    This patch relaxes the requirement that all modes should be restored on
    EnterVT, or the entire X-Server would go down by allowing modesets to
    fail (with some warnings). If a modeset fails, the CRTC will be
    disabled, and a RandR event will be sent for the desktop environment to
    fix the situation as well as possible.
    
    Additional patches might be needed to make sure that the user would
    never be left with all screens black in some scenarios.
    
    v2 (Martin Peres):
     - whitespace fixes
     - remove the uevent handling (it is done in a previous patch)
     - improve the commit message
     - reduce the size of the patch by not changing lines needlessly
     - return FALSE if one modeset fails in ignore mode
     - add comments/todos to explain why we do things
     - disable the CRTCs that failed the modeset
    
    Signed-off-by: Kishore Kadiyala <kishore.kadiyala at intel.com>
    Signed-off-by: Martin Peres <martin.peres at linux.intel.com>
    Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>
    Tested-by: Kishore Kadiyala <kishore.kadiyala at intel.com>
    Closes: #1010
    (cherry picked from commit efb3abddd49fb75bd6d0e31046fed43d258c93da)

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index a4d486a67..ef4a3147d 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -705,7 +705,7 @@ msBlockHandler_oneshot(ScreenPtr pScreen, void *pTimeout)
 
     msBlockHandler(pScreen, pTimeout);
 
-    drmmode_set_desired_modes(pScrn, &ms->drmmode, TRUE);
+    drmmode_set_desired_modes(pScrn, &ms->drmmode, TRUE, FALSE);
 }
 
 static void
@@ -1348,7 +1348,7 @@ CreateScreenResources(ScreenPtr pScreen)
     ret = pScreen->CreateScreenResources(pScreen);
     pScreen->CreateScreenResources = CreateScreenResources;
 
-    if (!drmmode_set_desired_modes(pScrn, &ms->drmmode, pScrn->is_gpu))
+    if (!drmmode_set_desired_modes(pScrn, &ms->drmmode, pScrn->is_gpu, FALSE))
         return FALSE;
 
     if (!drmmode_glamor_handle_new_screen_pixmap(&ms->drmmode))
@@ -1822,8 +1822,23 @@ EnterVT(ScrnInfoPtr pScrn)
 
     drmmode_update_kms_state(&ms->drmmode);
 
-    if (!drmmode_set_desired_modes(pScrn, &ms->drmmode, TRUE))
-        return FALSE;
+    /* allow not all modes to be set successfully since some events might have
+     * happened while not being master that could prevent the previous
+     * configuration from being re-applied.
+     */
+    if (!drmmode_set_desired_modes(pScrn, &ms->drmmode, TRUE, TRUE)) {
+        xf86DisableUnusedFunctions(pScrn);
+
+        /* TODO: check that at least one screen is on, to allow the user to fix
+         * their setup if all modeset failed...
+         */
+
+        /* Tell the desktop environment that something changed, so that they
+         * can hopefully correct the situation
+         */
+        RRSetChanged(xf86ScrnToScreen(pScrn));
+        RRTellChanged(xf86ScrnToScreen(pScrn));
+    }
 
     return TRUE;
 }
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 646bacecb..88992f521 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -3457,9 +3457,11 @@ drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y)
 }
 
 Bool
-drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, Bool set_hw)
+drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, Bool set_hw,
+                          Bool ign_err)
 {
     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+    Bool success = TRUE;
     int c;
 
     for (c = 0; c < config->num_crtc; c++) {
@@ -3507,8 +3509,17 @@ drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, Bool set_hw)
         if (set_hw) {
             if (!crtc->funcs->
                 set_mode_major(crtc, &crtc->desiredMode, crtc->desiredRotation,
-                               crtc->desiredX, crtc->desiredY))
-                return FALSE;
+                               crtc->desiredX, crtc->desiredY)) {
+                if (!ign_err)
+                    return FALSE;
+                else {
+                    success = FALSE;
+                    crtc->enabled = FALSE;
+                    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                               "Failed to set the desired mode on connector %s\n",
+                               output->name);
+                }
+            }
         } else {
             crtc->mode = crtc->desiredMode;
             crtc->rotation = crtc->desiredRotation;
@@ -3522,7 +3533,7 @@ drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, Bool set_hw)
     /* Validate leases on VT re-entry */
     drmmode_validate_leases(pScrn);
 
-    return TRUE;
+    return success;
 }
 
 static void
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index 6ef8ab9e4..59d79e9a0 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -278,7 +278,8 @@ void drmmode_DisableSharedPixmapFlipping(xf86CrtcPtr crtc, drmmode_ptr drmmode);
 extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp);
 extern Bool drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
 void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y);
-extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, Bool set_hw);
+extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode,
+                                      Bool set_hw, Bool ign_err);
 extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn);
 
 extern void drmmode_update_kms_state(drmmode_ptr drmmode);
commit bd0f53725b581e4698f5f3ec366a9507bd2556e2
Author: Martin Peres <martin.peres at linux.intel.com>
Date:   Tue Dec 1 11:10:34 2020 +0100

    modesetting: check the kms state on EnterVT
    
    Normally, we would receive a uevent coming from Linux's DRM subsystem,
    which would trigger the check for disappearing/appearing resources.
    However, this event is not received when X is not master (another VT
    is selected), and so the userspace / desktop environment would not be
    notified about the changes that happened while X wasn't master.
    
    To fix the issue, this patch forces a refresh on EnterVT by splitting
    the kms-checking code from the uevent handling into its own (exported)
    function called drmmode_update_kms_state. This function is then called
    from both the uevent-handling function, and on EnterVT right before
    restoring the modes.
    
    Signed-off-by: Martin Peres <martin.peres at linux.intel.com>
    Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>
    Acked-by: Kishore Kadiyala <kishore.kadiyala at intel.com>
    Tested-by: Kishore Kadiyala <kishore.kadiyala at intel.com>
    (cherry picked from commit 293cf660c95d7ba36510bcc4114d7fd5c5f3801c)

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 2aaea5f7d..a4d486a67 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -1820,6 +1820,8 @@ EnterVT(ScrnInfoPtr pScrn)
 
     SetMaster(pScrn);
 
+    drmmode_update_kms_state(&ms->drmmode);
+
     if (!drmmode_set_desired_modes(pScrn, &ms->drmmode, TRUE))
         return FALSE;
 
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 9dd8c5573..646bacecb 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -3607,30 +3607,19 @@ drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn)
     return TRUE;
 }
 
-#ifdef CONFIG_UDEV_KMS
-
 #define DRM_MODE_LINK_STATUS_GOOD       0
 #define DRM_MODE_LINK_STATUS_BAD        1
 
-static void
-drmmode_handle_uevents(int fd, void *closure)
+void
+drmmode_update_kms_state(drmmode_ptr drmmode)
 {
-    drmmode_ptr drmmode = closure;
     ScrnInfoPtr scrn = drmmode->scrn;
-    struct udev_device *dev;
     drmModeResPtr mode_res;
     xf86CrtcConfigPtr  config = XF86_CRTC_CONFIG_PTR(scrn);
     int i, j;
     Bool found = FALSE;
     Bool changed = FALSE;
 
-    while ((dev = udev_monitor_receive_device(drmmode->uevent_monitor))) {
-        udev_device_unref(dev);
-        found = TRUE;
-    }
-    if (!found)
-        return;
-
     /* Try to re-set the mode on all the connectors with a BAD link-state:
      * This may happen if a link degrades and a new modeset is necessary, using
      * different link-training parameters. If the kernel found that the current
@@ -3745,6 +3734,25 @@ out:
 #undef DRM_MODE_LINK_STATUS_BAD
 #undef DRM_MODE_LINK_STATUS_GOOD
 
+#ifdef CONFIG_UDEV_KMS
+
+static void
+drmmode_handle_uevents(int fd, void *closure)
+{
+    drmmode_ptr drmmode = closure;
+    struct udev_device *dev;
+    Bool found = FALSE;
+
+    while ((dev = udev_monitor_receive_device(drmmode->uevent_monitor))) {
+        udev_device_unref(dev);
+        found = TRUE;
+    }
+    if (!found)
+        return;
+
+    drmmode_update_kms_state(drmmode);
+}
+
 #endif
 
 void
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index 4142607fb..6ef8ab9e4 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -281,6 +281,7 @@ void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y);
 extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, Bool set_hw);
 extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn);
 
+extern void drmmode_update_kms_state(drmmode_ptr drmmode);
 extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode);
 extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode);
 


More information about the xorg-commit mailing list