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 <[email protected]>
---
 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

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to