xserver: Branch 'master' - 4 commits

Adam Jackson ajax at kemper.freedesktop.org
Mon Jan 22 22:24:25 UTC 2018


 hw/xfree86/drivers/modesetting/drmmode_display.c |  111 +++++++++++++++++------
 hw/xfree86/drivers/modesetting/vblank.c          |   50 ++++++++++
 hw/xfree86/modes/xf86Crtc.c                      |   16 ++-
 hw/xfree86/modes/xf86Crtc.h                      |    6 +
 hw/xfree86/modes/xf86Cursors.c                   |    2 
 randr/randrstr.h                                 |    4 
 randr/rrproperty.c                               |    4 
 7 files changed, 158 insertions(+), 35 deletions(-)

New commits:
commit 4d5aab66c052795c7f0381a3dfc7293c9a41e441
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Dec 21 18:54:39 2017 -0800

    xfree86: Disable cursor whenever turning off CRTC during modeset
    
    This makes sure the CRTC's cursor is hidden before we hand the CRTC
    over to some other application.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 1a401af4b..80a009e08 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -2651,6 +2651,14 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
     return success;
 }
 
+/* Turn a CRTC off, using the DPMS function and disabling the cursor */
+static void
+xf86DisableCrtc(xf86CrtcPtr crtc)
+{
+    crtc->funcs->dpms(crtc, DPMSModeOff);
+    xf86_crtc_hide_cursor(crtc);
+}
+
 /*
  * Check the CRTC we're going to map each output to vs. it's current
  * CRTC.  If they don't match, we have to disable the output and the CRTC
@@ -2706,9 +2714,9 @@ xf86PrepareCrtcs(ScrnInfoPtr scrn)
          * we need to disable it
          */
         if (desired_outputs != current_outputs || !desired_outputs)
-            (*crtc->funcs->dpms) (crtc, DPMSModeOff);
+            xf86DisableCrtc(crtc);
 #else
-        (*crtc->funcs->dpms) (crtc, DPMSModeOff);
+        xf86DisableCrtc(crtc);
 #endif
     }
 }
@@ -3004,7 +3012,7 @@ xf86DisableUnusedFunctions(ScrnInfoPtr pScrn)
         xf86CrtcPtr crtc = xf86_config->crtc[c];
 
         if (!crtc->enabled) {
-            crtc->funcs->dpms(crtc, DPMSModeOff);
+            xf86DisableCrtc(crtc);
             memset(&crtc->mode, 0, sizeof(crtc->mode));
             xf86RotateDestroy(crtc);
             crtc->active = FALSE;
@@ -3455,7 +3463,7 @@ xf86DetachAllCrtc(ScrnInfoPtr scrn)
                 RRCrtcDetachScanoutPixmap(crtc->randr_crtc);
 
             /* dpms off */
-            (*crtc->funcs->dpms) (crtc, DPMSModeOff);
+            xf86DisableCrtc(crtc);
             /* force a reset the next time its used */
             crtc->randr_crtc->mode = NULL;
             crtc->mode.HDisplay = 0;
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 215eb2a04..e6ae9cc4d 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -999,6 +999,12 @@ extern _X_EXPORT Bool
  xf86_show_cursors(ScrnInfoPtr scrn);
 
 /**
+ * Called by the driver to turn a single crtc's cursor off
+ */
+extern _X_EXPORT void
+xf86_crtc_hide_cursor(xf86CrtcPtr crtc);
+
+/**
  * Called by the driver to turn cursors off
  */
 extern _X_EXPORT void
diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c
index 26969efb2..ae2137d80 100644
--- a/hw/xfree86/modes/xf86Cursors.c
+++ b/hw/xfree86/modes/xf86Cursors.c
@@ -320,7 +320,7 @@ xf86_set_cursor_colors(ScrnInfoPtr scrn, int bg, int fg)
     }
 }
 
-static void
+void
 xf86_crtc_hide_cursor(xf86CrtcPtr crtc)
 {
     if (crtc->cursor_shown) {
commit 29f79bedf2c80241ba4b482db6ead08a5709a982
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Dec 21 18:54:37 2017 -0800

    randr: Declare incoming property values const
    
    RRChangeOutputProperty and RRConfigureOutputProperty should not modify
    their parameters, and callers may want to pass pointers to fixed data,
    so declare the value pointers as const in both cases.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/randr/randrstr.h b/randr/randrstr.h
index 95979a8c6..3f218009d 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -915,13 +915,13 @@ extern _X_EXPORT int
 
 RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
                        int format, int mode, unsigned long len,
-                       void *value, Bool sendevent, Bool pending);
+                       const void *value, Bool sendevent, Bool pending);
 
 extern _X_EXPORT int
 
 RRConfigureOutputProperty(RROutputPtr output, Atom property,
                           Bool pending, Bool range, Bool immutable,
-                          int num_values, INT32 *values);
+                          int num_values, const INT32 *values);
 extern _X_EXPORT int
  ProcRRChangeOutputProperty(ClientPtr client);
 
diff --git a/randr/rrproperty.c b/randr/rrproperty.c
index e56626cd2..6ffe91a47 100644
--- a/randr/rrproperty.c
+++ b/randr/rrproperty.c
@@ -135,7 +135,7 @@ RRDeleteOutputProperty(RROutputPtr output, Atom property)
 int
 RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
                        int format, int mode, unsigned long len,
-                       void *value, Bool sendevent, Bool pending)
+                       const void *value, Bool sendevent, Bool pending)
 {
     RRPropertyPtr prop;
     rrScrPrivPtr pScrPriv = rrGetScrPriv(output->pScreen);
@@ -324,7 +324,7 @@ RRGetOutputProperty(RROutputPtr output, Atom property, Bool pending)
 int
 RRConfigureOutputProperty(RROutputPtr output, Atom property,
                           Bool pending, Bool range, Bool immutable,
-                          int num_values, INT32 *values)
+                          int num_values, const INT32 *values)
 {
     RRPropertyPtr prop = RRQueryOutputProperty(output, property);
     Bool add = FALSE;
commit a12485ed846b852ca14d17d1e58c8b0f2399e577
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Dec 21 18:54:34 2017 -0800

    xf86-video-modesetting: Update property values at detect and uevent time
    
    We were updating the link-status property when a uevent came in, but
    we also want to update the non-desktop property, and potentially
    others as well. We also want to check at detect time in case we don't
    get a hotplug event.
    
    This patch updates every property provided by the kernel, sending
    changes to DIX so it can track things as well.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 5b8e4fa1b..9c3856378 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -1132,6 +1132,67 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res
     return 1;
 }
 
+/*
+ * Update all of the property values for an output
+ */
+static void
+drmmode_output_update_properties(xf86OutputPtr output)
+{
+    drmmode_output_private_ptr drmmode_output = output->driver_private;
+    int i, j, k;
+    int err;
+    drmModeConnectorPtr koutput;
+
+    /* Use the most recently fetched values from the kernel */
+    koutput = drmmode_output->mode_output;
+
+    if (!koutput)
+        return;
+
+    for (i = 0; i < drmmode_output->num_props; i++) {
+        drmmode_prop_ptr p = &drmmode_output->props[i];
+
+        for (j = 0; koutput && j < koutput->count_props; j++) {
+            if (koutput->props[j] == p->mode_prop->prop_id) {
+
+                /* Check to see if the property value has changed */
+                if (koutput->prop_values[j] != p->value) {
+
+                    p->value = koutput->prop_values[j];
+
+                    if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) {
+                        INT32 value = p->value;
+
+                        err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
+                                                     XA_INTEGER, 32, PropModeReplace, 1,
+                                                     &value, FALSE, TRUE);
+
+                        if (err != 0) {
+                            xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+                                       "RRChangeOutputProperty error, %d\n", err);
+                        }
+                    }
+                    else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) {
+                        for (k = 0; k < p->mode_prop->count_enums; k++)
+                            if (p->mode_prop->enums[k].value == p->value)
+                                break;
+                        if (k < p->mode_prop->count_enums) {
+                            err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
+                                                         XA_ATOM, 32, PropModeReplace, 1,
+                                                         &p->atoms[k + 1], FALSE, TRUE);
+                            if (err != 0) {
+                                xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+                                           "RRChangeOutputProperty error, %d\n", err);
+                            }
+                        }
+                    }
+                }
+                break;
+            }
+        }
+    }
+}
+
 static xf86OutputStatus
 drmmode_output_detect(xf86OutputPtr output)
 {
@@ -1147,11 +1208,14 @@ drmmode_output_detect(xf86OutputPtr output)
 
     drmmode_output->mode_output =
         drmModeGetConnector(drmmode->fd, drmmode_output->output_id);
+
     if (!drmmode_output->mode_output) {
         drmmode_output->output_id = -1;
         return XF86OutputStatusDisconnected;
     }
 
+    drmmode_output_update_properties(output);
+
     switch (drmmode_output->mode_output->connection) {
     case DRM_MODE_CONNECTED:
         status = XF86OutputStatusConnected;
@@ -2244,38 +2308,35 @@ drmmode_handle_uevents(int fd, void *closure)
      */
     for (i = 0; i < config->num_output; i++) {
         xf86OutputPtr output = config->output[i];
-        xf86CrtcPtr crtc = output->crtc;
         drmmode_output_private_ptr drmmode_output = output->driver_private;
-        uint32_t con_id, idx;
-        drmModeConnectorPtr koutput;
 
-        if (crtc == NULL || drmmode_output->mode_output == NULL)
-            continue;
+        drmmode_output_detect(output);
 
-        con_id = drmmode_output->mode_output->connector_id;
         /* Get an updated view of the properties for the current connector and
          * look for the link-status property
          */
-        koutput = drmModeGetConnectorCurrent(drmmode->fd, con_id);
-        if (!koutput)
-            continue;
-
-        idx = koutput_get_prop_idx(drmmode->fd, koutput,
-                DRM_MODE_PROP_ENUM, "link-status");
-
-        if ((idx > -1) &&
-                (koutput->prop_values[idx] == DRM_MODE_LINK_STATUS_BAD)) {
-            /* the connector got a link failure, re-set the current mode */
-            drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation,
-                                   crtc->x, crtc->y);
-
-            xf86DrvMsg(scrn->scrnIndex, X_WARNING,
-                       "hotplug event: connector %u's link-state is BAD, "
-                       "tried resetting the current mode. You may be left"
-                       "with a black screen if this fails...\n", con_id);
+        for (j = 0; j < drmmode_output->num_props; j++) {
+            drmmode_prop_ptr p = &drmmode_output->props[j];
+
+            if (!strcmp(p->mode_prop->name, "link-status")) {
+                if (p->value == DRM_MODE_LINK_STATUS_BAD) {
+                    xf86CrtcPtr crtc = output->crtc;
+                    if (!crtc)
+                        continue;
+
+                    /* the connector got a link failure, re-set the current mode */
+                    drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation,
+                                           crtc->x, crtc->y);
+
+                    xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+                               "hotplug event: connector %u's link-state is BAD, "
+                               "tried resetting the current mode. You may be left"
+                               "with a black screen if this fails...\n",
+                               drmmode_output->mode_output->connector_id);
+                }
+                break;
+            }
         }
-
-        drmModeFreeConnector(koutput);
     }
 
     mode_res = drmModeGetResources(drmmode->fd);
commit 44d5f2eb8a2f92571698adec39ac569b71da5a1b
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Dec 21 18:54:33 2017 -0800

    xf86-video-modesetting: Support new vblank kernel API [v2]
    
    drmCrtcGetSequence returns the current vblank sequence and time.
    
    drmCrtcQueueSequence queues an event for delivery at a specified
    vblank sequence.
    
    Use these (when available) in preference to drmWaitVBlank.
    
    v2: Remove FIRST_PIXEL_OUT_FLAG. This has been removed from the kernel
        API.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/vblank.c b/hw/xfree86/drivers/modesetting/vblank.c
index 3f6568997..e7879f504 100644
--- a/hw/xfree86/drivers/modesetting/vblank.c
+++ b/hw/xfree86/drivers/modesetting/vblank.c
@@ -182,6 +182,21 @@ ms_get_kernel_ust_msc(xf86CrtcPtr crtc,
     drmVBlank vbl;
     int ret;
 
+#ifdef DRM_IOCTL_CRTC_QUEUE_SEQUENCE
+    if (ms->has_queue_sequence || !ms->tried_queue_sequence) {
+        uint64_t ns;
+        ms->tried_queue_sequence = TRUE;
+
+        ret = drmCrtcGetSequence(ms->fd, drmmode_crtc->mode_crtc->crtc_id,
+                                 msc, &ns);
+        if (ret != -1 || errno != ENOTTY) {
+            ms->has_queue_sequence = TRUE;
+            if (ret == 0)
+                *ust = ns / 1000;
+            return ret == 0;
+        }
+    }
+#endif
     /* Get current count */
     vbl.request.type = DRM_VBLANK_RELATIVE | drmmode_crtc->vblank_pipe;
     vbl.request.sequence = 0;
@@ -211,6 +226,35 @@ ms_queue_vblank(xf86CrtcPtr crtc, ms_queue_flag flags,
 
     for (;;) {
         /* Queue an event at the specified sequence */
+#ifdef DRM_IOCTL_CRTC_QUEUE_SEQUENCE
+        if (ms->has_queue_sequence || !ms->tried_queue_sequence) {
+            uint32_t drm_flags = 0;
+            uint64_t kernel;
+            uint64_t kernel_queued;
+
+            ms->tried_queue_sequence = TRUE;
+
+            if (flags & MS_QUEUE_RELATIVE)
+                drm_flags |= DRM_CRTC_SEQUENCE_RELATIVE;
+            if (flags & MS_QUEUE_NEXT_ON_MISS)
+                drm_flags |= DRM_CRTC_SEQUENCE_NEXT_ON_MISS;
+
+            kernel = ms_crtc_msc_to_kernel_msc(crtc, msc);
+            ret = drmCrtcQueueSequence(ms->fd, drmmode_crtc->mode_crtc->crtc_id,
+                                       drm_flags,
+                                       kernel, &kernel_queued, seq);
+            if (ret == 0) {
+                if (msc_queued)
+                    *msc_queued = ms_kernel_msc_to_crtc_msc(crtc, kernel_queued);
+                return TRUE;
+            }
+
+            if (ret != -1 || errno != ENOTTY) {
+                ms->has_queue_sequence = TRUE;
+                goto check;
+            }
+        }
+#endif
         vbl.request.type = DRM_VBLANK_EVENT | drmmode_crtc->vblank_pipe;
         if (flags & MS_QUEUE_RELATIVE)
             vbl.request.type |= DRM_VBLANK_RELATIVE;
@@ -228,6 +272,9 @@ ms_queue_vblank(xf86CrtcPtr crtc, ms_queue_flag flags,
                 *msc_queued = ms_kernel_msc_to_crtc_msc(crtc, vbl.reply.sequence);
             return TRUE;
         }
+#ifdef DRM_IOCTL_CRTC_QUEUE_SEQUENCE
+    check:
+#endif
         if (errno != EBUSY) {
             ms_drm_abort_seq(scrn, seq);
             return FALSE;
@@ -446,9 +493,10 @@ ms_vblank_screen_init(ScreenPtr screen)
     modesettingEntPtr ms_ent = ms_ent_priv(scrn);
     xorg_list_init(&ms_drm_queue);
 
-    ms->event_context.version = 2;
+    ms->event_context.version = 4;
     ms->event_context.vblank_handler = ms_drm_handler;
     ms->event_context.page_flip_handler = ms_drm_handler;
+    ms->event_context.sequence_handler = ms_drm_sequence_handler;
 
     /* We need to re-register the DRM fd for the synchronisation
      * feedback on every server generation, so perform the


More information about the xorg-commit mailing list