[RFC xserver v3 07/14] modesetting: Use atomic modesetting to configure output/CRTCs

Louis-Francis Ratté-Boulianne lfrb at collabora.com
Wed Sep 27 05:19:06 UTC 2017


To make sure we also use the same primary plane and to avoid
mixing uses of two APIs, it is better to always use the atomic
modesetting API when possible.

Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
---
 hw/xfree86/drivers/modesetting/drmmode_display.c | 402 +++++++++++++++++------
 hw/xfree86/drivers/modesetting/drmmode_display.h |  35 +-
 hw/xfree86/drivers/modesetting/pageflip.c        |   2 +-
 hw/xfree86/drivers/modesetting/present.c         |   3 +-
 4 files changed, 335 insertions(+), 107 deletions(-)

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 6cd6a35b3..0e9498a6b 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -279,16 +279,100 @@ plane_add_prop(drmModeAtomicReq *req, drmmode_crtc_private_ptr drmmode_crtc,
                                    info->prop_id, val);
     return (ret <= 0) ? -1 : 0;
 }
+
+static int
+crtc_add_prop(drmModeAtomicReq *req, drmmode_crtc_private_ptr drmmode_crtc,
+              enum drmmode_crtc_property prop, uint64_t val)
+{
+    drmmode_prop_info_ptr info = &drmmode_crtc->props[prop];
+    int ret;
+
+    if (!info)
+        return -1;
+
+    ret = drmModeAtomicAddProperty(req, drmmode_crtc->mode_crtc->crtc_id,
+                                   info->prop_id, val);
+    return (ret <= 0) ? -1 : 0;
+}
+
+static int
+connector_add_prop(drmModeAtomicReq *req, drmmode_output_private_ptr drmmode_output,
+                   enum drmmode_connector_property prop, uint64_t val)
+{
+    drmmode_prop_info_ptr info = &drmmode_output->props_connector[prop];
+    int ret;
+
+    if (!info)
+        return -1;
+
+    ret = drmModeAtomicAddProperty(req, drmmode_output->mode_output->connector_id,
+                                   info->prop_id, val);
+    return (ret <= 0) ? -1 : 0;
+}
+
+static int
+drmmode_CompareKModes(drmModeModeInfo * kmode, drmModeModeInfo * other)
+{
+    return memcmp(kmode, other, sizeof(*kmode));
+}
+
+static int
+drm_mode_ensure_blob(xf86CrtcPtr crtc, drmModeModeInfo mode_info)
+{
+    modesettingPtr ms = modesettingPTR(crtc->scrn);
+    drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+    drmmode_mode_ptr mode;
+    int ret;
+
+    if (drmmode_crtc->current_mode &&
+        drmmode_CompareKModes(&drmmode_crtc->current_mode->mode_info, &mode_info) == 0)
+        return 0;
+
+    mode = calloc(sizeof(drmmode_mode_rec), 1);
+    if (!mode)
+        return -1;
+
+    mode->mode_info = mode_info;
+    ret = drmModeCreatePropertyBlob(ms->fd,
+                                    &mode->mode_info,
+                                    sizeof(mode->mode_info),
+                                    &mode->blob_id);
+    drmmode_crtc->current_mode = mode;
+    xorg_list_add(&mode->entry, &drmmode_crtc->mode_list);
+
+    return ret;
+}
+
+static void
+drm_mode_destroy(xf86CrtcPtr crtc, drmmode_mode_ptr mode)
+{
+    modesettingPtr ms = modesettingPTR(crtc->scrn);
+    if (mode->blob_id)
+        drmModeDestroyPropertyBlob(ms->fd, mode->blob_id);
+    xorg_list_del(&mode->entry);
+    free(mode);
+}
 #endif
 
+static void
+drmmode_ConvertToKMode(ScrnInfoPtr scrn,
+                       drmModeModeInfo * kmode, DisplayModePtr mode);
+
 int
-drmmode_crtc_set_fb(xf86CrtcPtr crtc, uint32_t fb_id,
+drmmode_crtc_set_fb(xf86CrtcPtr crtc, DisplayModePtr mode, uint32_t fb_id,
                     int x, int y, uint32_t flags, void *data)
 {
     modesettingPtr ms = modesettingPTR(crtc->scrn);
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
     drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-    int ret = 0;
+    drmmode_ptr drmmode = drmmode_crtc->drmmode;
+    int output_count = 0;
+    uint32_t *output_ids = NULL;
+    drmModeModeInfo kmode;
+    int i, ret = 0;
+
+    if (mode)
+        drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
 
 #ifdef GLAMOR_HAS_DRM_ATOMIC
     if (ms->atomic_modeset) {
@@ -297,12 +381,56 @@ drmmode_crtc_set_fb(xf86CrtcPtr crtc, uint32_t fb_id,
         if (!req)
             return 1;
 
+        if (mode) {
+            ret = drm_mode_ensure_blob(crtc, kmode);
+
+            for (i = 0; i < xf86_config->num_output; i++) {
+                xf86OutputPtr output = xf86_config->output[i];
+                drmmode_output_private_ptr drmmode_output;
+
+                if (output->crtc != crtc)
+                    continue;
+
+                drmmode_output = output->driver_private;
+                if (drmmode_output->output_id == -1)
+                    continue;
+
+                if (drmmode_output->dpms == DPMSModeOn) {
+                    ret |= crtc_add_prop(req, drmmode_crtc,
+                                         DRMMODE_CRTC_ACTIVE, 1);
+                    ret |= crtc_add_prop(req, drmmode_crtc,
+                                         DRMMODE_CRTC_MODE_ID,
+                                         drmmode_crtc->current_mode->blob_id);
+                    ret |= connector_add_prop(req, drmmode_output,
+                                              DRMMODE_CONNECTOR_CRTC_ID,
+                                              drmmode_crtc->mode_crtc->crtc_id);
+                } else {
+                    ret |= crtc_add_prop(req, drmmode_crtc,
+                                         DRMMODE_CRTC_ACTIVE, 0);
+                    ret |= crtc_add_prop(req, drmmode_crtc,
+                                         DRMMODE_CRTC_MODE_ID, 0);
+                    ret |= connector_add_prop(req, drmmode_output,
+                                              DRMMODE_CONNECTOR_CRTC_ID, 0);
+                }
+            }
+        }
+
         ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_FB_ID,
                               fb_id);
         ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_CRTC_ID,
                               drmmode_crtc->mode_crtc->crtc_id);
-        ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_SRC_X, x);
-        ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_SRC_Y, y);
+        ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_SRC_X, x << 16);
+        ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_SRC_Y, y << 16);
+        ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_SRC_W,
+                              drmmode->front_bo.width << 16);
+        ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_SRC_H,
+                              drmmode->front_bo.height << 16);
+        ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_CRTC_X, 0);
+        ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_CRTC_Y, 0);
+        ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_CRTC_W,
+                              drmmode->front_bo.width);
+        ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_CRTC_H,
+                              drmmode->front_bo.height);
 
         if (ret == 0)
             ret = drmModeAtomicCommit(ms->fd, req, flags, data);
@@ -312,7 +440,30 @@ drmmode_crtc_set_fb(xf86CrtcPtr crtc, uint32_t fb_id,
     }
 #endif
 
-    return 0;
+    output_ids = calloc(sizeof(uint32_t), xf86_config->num_output);
+    if (!output_ids)
+        return -1;
+
+    for (i = 0; i < xf86_config->num_output; i++) {
+        xf86OutputPtr output = xf86_config->output[i];
+        drmmode_output_private_ptr drmmode_output;
+
+        if (output->crtc != crtc)
+            continue;
+
+        drmmode_output = output->driver_private;
+        if (drmmode_output->output_id == -1)
+            continue;
+        output_ids[output_count] =
+            drmmode_output->mode_output->connector_id;
+        output_count++;
+    }
+
+    ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+                         fb_id, x, y, output_ids, output_count, &kmode);
+
+    free(output_ids);
+    return ret;
 }
 
 
@@ -873,124 +1024,93 @@ static Bool
 drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
                        Rotation rotation, int x, int y)
 {
-    ScrnInfoPtr pScrn = crtc->scrn;
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
     drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
     drmmode_ptr drmmode = drmmode_crtc->drmmode;
     int saved_x, saved_y;
     Rotation saved_rotation;
     DisplayModeRec saved_mode;
-    uint32_t *output_ids = NULL;
-    int output_count = 0;
     Bool ret = TRUE;
     int i;
     uint32_t fb_id = 0;
-    drmModeModeInfo kmode;
+    uint32_t flags = 0;
 
     saved_mode = crtc->mode;
     saved_x = crtc->x;
     saved_y = crtc->y;
     saved_rotation = crtc->rotation;
 
-    if (mode) {
-        crtc->mode = *mode;
-        crtc->x = x;
-        crtc->y = y;
-        crtc->rotation = rotation;
-    }
-
-    output_ids = calloc(sizeof(uint32_t), xf86_config->num_output);
-    if (!output_ids) {
-        ret = FALSE;
+    if (!mode)
         goto done;
-    }
 
-    if (mode) {
-        for (i = 0; i < xf86_config->num_output; i++) {
-            xf86OutputPtr output = xf86_config->output[i];
-            drmmode_output_private_ptr drmmode_output;
+    crtc->mode = *mode;
+    crtc->x = x;
+    crtc->y = y;
+    crtc->rotation = rotation;
 
-            if (output->crtc != crtc)
-                continue;
+    if (!xf86CrtcRotate(crtc)) {
+        goto done;
+    }
+    crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
+                           crtc->gamma_blue, crtc->gamma_size);
 
-            drmmode_output = output->driver_private;
-            if (drmmode_output->output_id == -1)
-                continue;
-            output_ids[output_count] =
-                drmmode_output->mode_output->connector_id;
-            output_count++;
-        }
+    fb_id = drmmode->fb_id;
+    if (drmmode_crtc->prime_pixmap) {
+        if (!drmmode->reverse_prime_offload_mode) {
+            msPixmapPrivPtr ppriv =
+                msGetPixmapPriv(drmmode, drmmode_crtc->prime_pixmap);
+            fb_id = ppriv->fb_id;
+            x = 0;
+        } else
+            x = drmmode_crtc->prime_pixmap_x;
+        y = 0;
+    }
+    else if (drmmode_crtc->rotate_fb_id) {
+        fb_id = drmmode_crtc->rotate_fb_id;
+        x = y = 0;
+    }
 
-        if (!xf86CrtcRotate(crtc)) {
+    if (fb_id == 0) {
+        ret = drmmode_bo_import(drmmode, &drmmode->front_bo,
+                                &drmmode->fb_id);
+        if (ret < 0) {
+            ErrorF("failed to add fb %d\n", ret);
+            ret = FALSE;
             goto done;
         }
-        crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
-                               crtc->gamma_blue, crtc->gamma_size);
-
-        drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
-
         fb_id = drmmode->fb_id;
-        if (drmmode_crtc->prime_pixmap) {
-            if (!drmmode->reverse_prime_offload_mode) {
-                msPixmapPrivPtr ppriv =
-                    msGetPixmapPriv(drmmode, drmmode_crtc->prime_pixmap);
-                fb_id = ppriv->fb_id;
-                x = 0;
-            } else
-                x = drmmode_crtc->prime_pixmap_x;
-            y = 0;
-        }
-        else if (drmmode_crtc->rotate_fb_id) {
-            fb_id = drmmode_crtc->rotate_fb_id;
-            x = y = 0;
-        }
-
-        if (fb_id == 0) {
-            ret = drmModeAddFB(drmmode->fd,
-                               pScrn->virtualX, pScrn->virtualY,
-                               pScrn->depth, drmmode->kbpp,
-                               drmmode_bo_get_pitch(&drmmode->front_bo),
-                               drmmode_bo_get_handle(&drmmode->front_bo),
-                               &drmmode->fb_id);
-            if (ret < 0) {
-                ErrorF("failed to add fb %d\n", ret);
-                ret = FALSE;
-                goto done;
-            }
-            fb_id = drmmode->fb_id;
-        }
+    }
 
-        if (drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
-                           fb_id, x, y, output_ids, output_count, &kmode)) {
-            xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
-                       "failed to set mode: %s\n", strerror(errno));
-            ret = FALSE;
-            goto done;
-        } else
-            ret = TRUE;
+    flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
+    if (drmmode_crtc_set_fb(crtc, mode, fb_id, x, y, flags, NULL)) {
+        xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
+                   "failed to set mode: %s\n", strerror(errno));
+        ret = FALSE;
+        goto done;
+    } else
+        ret = TRUE;
 
-        if (crtc->scrn->pScreen)
-            xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen);
+    if (crtc->scrn->pScreen)
+        xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen);
 
-        drmmode_crtc->need_modeset = FALSE;
-        crtc->funcs->dpms(crtc, DPMSModeOn);
+    drmmode_crtc->need_modeset = FALSE;
+    crtc->funcs->dpms(crtc, DPMSModeOn);
 
-        if (drmmode_crtc->prime_pixmap_back)
-            drmmode_InitSharedPixmapFlipping(crtc, drmmode);
+    if (drmmode_crtc->prime_pixmap_back)
+        drmmode_InitSharedPixmapFlipping(crtc, drmmode);
 
-        /* go through all the outputs and force DPMS them back on? */
-        for (i = 0; i < xf86_config->num_output; i++) {
-            xf86OutputPtr output = xf86_config->output[i];
-            drmmode_output_private_ptr drmmode_output;
+    /* go through all the outputs and force DPMS them back on? */
+    for (i = 0; i < xf86_config->num_output; i++) {
+        xf86OutputPtr output = xf86_config->output[i];
+        drmmode_output_private_ptr drmmode_output;
 
-            if (output->crtc != crtc)
-                continue;
+        if (output->crtc != crtc)
+            continue;
 
-            drmmode_output = output->driver_private;
-            if (drmmode_output->output_id == -1)
-                continue;
-            output->funcs->dpms(output, DPMSModeOn);
-        }
+        drmmode_output = output->driver_private;
+        if (drmmode_output->output_id == -1)
+            continue;
+        output->funcs->dpms(output, DPMSModeOn);
     }
 
  done:
@@ -1002,8 +1122,6 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
     } else
         crtc->active = TRUE;
 
-    free(output_ids);
-
     return ret;
 }
 
@@ -1382,9 +1500,15 @@ drmmode_crtc_is_enabled(xf86CrtcPtr crtc)
 static void
 drmmode_crtc_destroy(xf86CrtcPtr crtc)
 {
+#ifdef GLAMOR_HAS_DRM_ATOMIC
+    drmmode_mode_ptr iterator, next;
     drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 
     drmmode_prop_info_free(drmmode_crtc->props_plane, DRMMODE_PLANE__COUNT);
+    xorg_list_for_each_entry_safe(iterator, next, &drmmode_crtc->mode_list, entry) {
+        drm_mode_destroy(crtc, iterator);
+    }
+#endif
 }
 
 static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
@@ -1463,6 +1587,14 @@ drmmode_crtc_create_planes(xf86CrtcPtr crtc, int num)
         },
         [DRMMODE_PLANE_FB_ID] = { .name = "FB_ID", },
         [DRMMODE_PLANE_CRTC_ID] = { .name = "CRTC_ID", },
+        [DRMMODE_PLANE_SRC_X] = { .name = "SRC_X", },
+        [DRMMODE_PLANE_SRC_Y] = { .name = "SRC_Y", },
+        [DRMMODE_PLANE_SRC_W] = { .name = "SRC_W", },
+        [DRMMODE_PLANE_SRC_H] = { .name = "SRC_H", },
+        [DRMMODE_PLANE_CRTC_X] = { .name = "CRTC_X", },
+        [DRMMODE_PLANE_CRTC_Y] = { .name = "CRTC_Y", },
+        [DRMMODE_PLANE_CRTC_W] = { .name = "CRTC_W", },
+        [DRMMODE_PLANE_CRTC_H] = { .name = "CRTC_H", },
     };
     drmmode_prop_info_rec tmp_props[DRMMODE_PLANE__COUNT];
 
@@ -1548,19 +1680,37 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res
     xf86CrtcPtr crtc;
     drmmode_crtc_private_ptr drmmode_crtc;
     modesettingEntPtr ms_ent = ms_ent_priv(pScrn);
+#ifdef GLAMOR_HAS_DRM_ATOMIC
+    drmModeObjectPropertiesPtr props;
+    static const drmmode_prop_info_rec crtc_props[] = {
+        [DRMMODE_CRTC_ACTIVE] = { .name = "ACTIVE" },
+        [DRMMODE_CRTC_MODE_ID] = { .name = "MODE_ID" },
+    };
+#endif
 
     crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs);
     if (crtc == NULL)
         return 0;
-
     drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
+    crtc->driver_private = drmmode_crtc;
     drmmode_crtc->mode_crtc =
         drmModeGetCrtc(drmmode->fd, mode_res->crtcs[num]);
     drmmode_crtc->drmmode = drmmode;
     drmmode_crtc->vblank_pipe = drmmode_crtc_vblank_pipe(num);
-    crtc->driver_private = drmmode_crtc;
+    xorg_list_init(&drmmode_crtc->mode_list);
 
 #ifdef GLAMOR_HAS_DRM_ATOMIC
+    props = drmModeObjectGetProperties(drmmode->fd, mode_res->crtcs[num],
+                                       DRM_MODE_OBJECT_CRTC);
+    if (!props || !drmmode_prop_info_copy(drmmode_crtc->props, crtc_props,
+                                          DRMMODE_CRTC__COUNT, 0)) {
+        xf86CrtcDestroy(crtc);
+        return 0;
+    }
+
+    drmmode_prop_info_update(drmmode, drmmode_crtc->props,
+                             DRMMODE_CRTC__COUNT, props);
+    drmModeFreeObjectProperties(props);
     drmmode_crtc_create_planes(crtc, num);
 #endif
 
@@ -1733,13 +1883,28 @@ drmmode_output_get_modes(xf86OutputPtr output)
     drmmode_ptr drmmode = drmmode_output->drmmode;
     int i;
     DisplayModePtr Modes = NULL, Mode;
-    drmModePropertyPtr props;
     xf86MonPtr mon = NULL;
+#ifdef GLAMOR_HAS_DRM_ATOMIC
+    drmModeObjectPropertiesPtr props;
+    uint32_t id;
+#else
+    drmModePropertyPtr props;
+#endif
 
     if (!koutput)
         return NULL;
 
+#ifdef GLAMOR_HAS_DRM_ATOMIC
+    props = drmModeObjectGetProperties(drmmode->fd,
+                                       drmmode_output->mode_output->connector_id,
+                                       DRM_MODE_OBJECT_CONNECTOR);
+    id = drmmode_prop_get_value(&drmmode_output->props_connector[DRMMODE_CONNECTOR_EDID],
+                                props, 0);
+    if (id)
+        drmmode_output->edid_blob = drmModeGetPropertyBlob(drmmode->fd, id);
+#else
     /* look for an EDID property */
+
     for (i = 0; i < koutput->count_props; i++) {
         props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
         if (props && (props->flags & DRM_MODE_PROP_BLOB)) {
@@ -1753,6 +1918,7 @@ drmmode_output_get_modes(xf86OutputPtr output)
             drmModeFreeProperty(props);
         }
     }
+#endif
 
     if (drmmode_output->edid_blob) {
         mon = xf86InterpretEDID(output->scrn->scrnIndex,
@@ -1806,13 +1972,19 @@ drmmode_output_dpms(xf86OutputPtr output, int mode)
     drmmode_output_private_ptr drmmode_output = output->driver_private;
     xf86CrtcPtr crtc = output->crtc;
     drmModeConnectorPtr koutput = drmmode_output->mode_output;
+#ifndef GLAMOR_HAS_DRM_ATOMIC
     drmmode_ptr drmmode = drmmode_output->drmmode;
+#endif
 
     if (!koutput)
         return;
 
+#ifdef GLAMOR_HAS_DRM_ATOMIC
+    drmmode_output->dpms = mode;
+#else
     drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id,
                                 drmmode_output->dpms_enum_id, mode);
+#endif
 
     if (crtc) {
         drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
@@ -2133,25 +2305,35 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r
     drmModeConnectorPtr koutput;
     drmModeEncoderPtr *kencoders = NULL;
     drmmode_output_private_ptr drmmode_output;
-    drmModePropertyPtr props;
     char name[32];
     int i;
     drmModePropertyBlobPtr path_blob = NULL;
+    drmModePropertyPtr path_props;
     const char *s;
+#ifdef GLAMOR_HAS_DRM_ATOMIC
+    drmModeObjectPropertiesPtr props;
+    static const drmmode_prop_info_rec connector_props[] = {
+        [DRMMODE_CONNECTOR_PATH] = { .name = "PATH" },
+        [DRMMODE_CONNECTOR_EDID] = { .name = "EDID" },
+        [DRMMODE_CONNECTOR_DPMS] = { .name = "DPMS" },
+        [DRMMODE_CONNECTOR_CRTC_ID] = { .name = "CRTC_ID", },
+    };
+#endif
+
     koutput =
         drmModeGetConnector(drmmode->fd, mode_res->connectors[num]);
     if (!koutput)
         return 0;
 
     for (i = 0; i < koutput->count_props; i++) {
-        props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
-        if (props && (props->flags & DRM_MODE_PROP_BLOB)) {
-            if (!strcmp(props->name, "PATH")) {
+        path_props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
+        if (path_props && (path_props->flags & DRM_MODE_PROP_BLOB)) {
+            if (!strcmp(path_props->name, "PATH")) {
                 path_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]);
-                drmModeFreeProperty(props);
+                drmModeFreeProperty(path_props);
                 break;
             }
-            drmModeFreeProperty(props);
+            drmModeFreeProperty(path_props);
         }
     }
 
@@ -2230,6 +2412,17 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r
     /* work out the possible clones later */
     output->possible_clones = 0;
 
+#ifdef GLAMOR_HAS_DRM_ATOMIC
+    if (!drmmode_prop_info_copy(drmmode_output->props_connector, connector_props,
+                                DRMMODE_CONNECTOR__COUNT, 0)) {
+        goto out_free_encoders;
+    }
+    props = drmModeObjectGetProperties(drmmode->fd,
+                                       drmmode_output->mode_output->connector_id,
+                                       DRM_MODE_OBJECT_CONNECTOR);
+    drmmode_prop_info_update(drmmode, drmmode_output->props_connector,
+                             DRMMODE_CONNECTOR__COUNT, props);
+#else
     for (i = 0; i < koutput->count_props; i++) {
         props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
         if (props && (props->flags & DRM_MODE_PROP_ENUM)) {
@@ -2241,6 +2434,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r
             drmModeFreeProperty(props);
         }
     }
+#endif
 
     if (dynamic)
         output->randr_output = RROutputCreate(xf86ScrnToScreen(pScrn), output->name, strlen(output->name), output);
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index ca83eae4b..c369478bf 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -40,6 +40,14 @@ enum drmmode_plane_property {
     DRMMODE_PLANE_TYPE = 0,
     DRMMODE_PLANE_FB_ID,
     DRMMODE_PLANE_CRTC_ID,
+    DRMMODE_PLANE_SRC_X,
+    DRMMODE_PLANE_SRC_Y,
+    DRMMODE_PLANE_SRC_W,
+    DRMMODE_PLANE_SRC_H,
+    DRMMODE_PLANE_CRTC_X,
+    DRMMODE_PLANE_CRTC_Y,
+    DRMMODE_PLANE_CRTC_W,
+    DRMMODE_PLANE_CRTC_H,
     DRMMODE_PLANE__COUNT
 };
 
@@ -50,6 +58,20 @@ enum drmmode_plane_type {
     DRMMODE_PLANE_TYPE__COUNT
 };
 
+enum drmmode_connector_property {
+    DRMMODE_CONNECTOR_PATH,
+    DRMMODE_CONNECTOR_EDID,
+    DRMMODE_CONNECTOR_DPMS,
+    DRMMODE_CONNECTOR_CRTC_ID,
+    DRMMODE_CONNECTOR__COUNT
+};
+
+enum drmmode_crtc_property {
+    DRMMODE_CRTC_ACTIVE,
+    DRMMODE_CRTC_MODE_ID,
+    DRMMODE_CRTC__COUNT
+};
+
 typedef struct {
     uint32_t width;
     uint32_t height;
@@ -115,6 +137,12 @@ typedef struct {
 } drmmode_prop_info_rec, *drmmode_prop_info_ptr;
 
 typedef struct {
+    drmModeModeInfo mode_info;
+    uint32_t blob_id;
+    struct xorg_list entry;
+} drmmode_mode_rec, *drmmode_mode_ptr;
+
+typedef struct {
     drmmode_ptr drmmode;
     drmModeCrtcPtr mode_crtc;
     uint32_t vblank_pipe;
@@ -123,8 +151,10 @@ typedef struct {
     Bool cursor_up;
     uint16_t lut_r[256], lut_g[256], lut_b[256];
 
+    drmmode_prop_info_rec props[DRMMODE_CRTC__COUNT];
     drmmode_prop_info_rec props_plane[DRMMODE_PLANE__COUNT];
     uint32_t plane_id;
+    drmmode_mode_ptr current_mode;
 
     drmmode_bo rotate_bo;
     unsigned rotate_fb_id;
@@ -146,6 +176,7 @@ typedef struct {
     /** @} */
 
     Bool need_modeset;
+    struct xorg_list mode_list;
 
     Bool enable_flipping;
     Bool flipping_active;
@@ -166,8 +197,10 @@ typedef struct {
     drmModePropertyBlobPtr edid_blob;
     drmModePropertyBlobPtr tile_blob;
     int dpms_enum_id;
+    int dpms;
     int num_props;
     drmmode_prop_ptr props;
+    drmmode_prop_info_rec props_connector[DRMMODE_CONNECTOR__COUNT];
     int enc_mask;
     int enc_clone_mask;
 } drmmode_output_private_rec, *drmmode_output_private_ptr;
@@ -231,7 +264,7 @@ void drmmode_get_default_bpp(ScrnInfoPtr pScrn, drmmode_ptr drmmmode,
 
 void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
 
-int drmmode_crtc_set_fb(xf86CrtcPtr crtc, uint32_t fb_id,
+int drmmode_crtc_set_fb(xf86CrtcPtr crtc, DisplayModePtr mode, uint32_t fb_id,
                         int x, int y, uint32_t flags, void *data);
 
 #ifndef DRM_CAP_DUMB_PREFERRED_DEPTH
diff --git a/hw/xfree86/drivers/modesetting/pageflip.c b/hw/xfree86/drivers/modesetting/pageflip.c
index 4a09fa40f..2aba9f2f5 100644
--- a/hw/xfree86/drivers/modesetting/pageflip.c
+++ b/hw/xfree86/drivers/modesetting/pageflip.c
@@ -168,7 +168,7 @@ do_queue_flip_on_crtc(modesettingPtr ms, xf86CrtcPtr crtc,
 #ifdef GLAMOR_HAS_DRM_ATOMIC
     if (ms->atomic_modeset) {
         flags |= DRM_MODE_ATOMIC_NONBLOCK;
-        return drmmode_crtc_set_fb(crtc, ms->drmmode.fb_id, 0, 0, flags,
+        return drmmode_crtc_set_fb(crtc, NULL, ms->drmmode.fb_id, 0, 0, flags,
                                    (void *) (uintptr_t) seq);
     }
 #endif
diff --git a/hw/xfree86/drivers/modesetting/present.c b/hw/xfree86/drivers/modesetting/present.c
index b69415b2f..3946c1e26 100644
--- a/hw/xfree86/drivers/modesetting/present.c
+++ b/hw/xfree86/drivers/modesetting/present.c
@@ -267,7 +267,8 @@ ms_present_check_flip(RRCrtcPtr crtc,
         return FALSE;
 
     /* Check stride, can't change that on flip */
-    if (pixmap->devKind != drmmode_bo_get_pitch(&ms->drmmode.front_bo))
+    if (!ms->atomic_modeset &&
+        pixmap->devKind != drmmode_bo_get_pitch(&ms->drmmode.front_bo))
         return FALSE;
 
     /* Make sure there's a bo we can get to */
-- 
2.13.0



More information about the xorg-devel mailing list