diff options
author | Louis-Francis Ratté-Boulianne <lfrb@collabora.com> | 2018-04-04 00:01:14 -0400 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2018-04-04 14:01:48 -0400 |
commit | bc4d278132956ec3c43695f1bd34083ef5fe7f22 (patch) | |
tree | 72b3215e19c78d0f25fc8dba687cef671eef7a92 /hw | |
parent | 23c67987a337beb91292f8e318d566941453baa3 (diff) |
modesetting: Use atomic modesetting to set DPMS mode
CRTCs and outputs needs to be enabled/disabled when the current
DPMS mode is changed. We also try to do it in an atomic commit
when possible.
Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com>
Tested-by: Daniel Stone <daniels@collabora.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/xfree86/drivers/modesetting/driver.c | 5 | ||||
-rw-r--r-- | hw/xfree86/drivers/modesetting/driver.h | 1 | ||||
-rw-r--r-- | hw/xfree86/drivers/modesetting/drmmode_display.c | 385 | ||||
-rw-r--r-- | hw/xfree86/drivers/modesetting/drmmode_display.h | 5 | ||||
-rw-r--r-- | hw/xfree86/drivers/modesetting/pageflip.c | 13 |
5 files changed, 299 insertions, 110 deletions
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c index 363e2e19d..7682b24f1 100644 --- a/hw/xfree86/drivers/modesetting/driver.c +++ b/hw/xfree86/drivers/modesetting/driver.c @@ -1658,7 +1658,10 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv) if (!drmmode_setup_colormap(pScreen, pScrn)) return FALSE; - xf86DPMSInit(pScreen, xf86DPMSSet, 0); + if (ms->atomic_modeset) + xf86DPMSInit(pScreen, drmmode_set_dpms, 0); + else + xf86DPMSInit(pScreen, xf86DPMSSet, 0); #ifdef GLAMOR_HAS_GBM if (ms->drmmode.glamor) { diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h index ed32239db..cb8cfe634 100644 --- a/hw/xfree86/drivers/modesetting/driver.h +++ b/hw/xfree86/drivers/modesetting/driver.h @@ -106,6 +106,7 @@ typedef struct _modesettingRec { * @{ */ Bool atomic_modeset; + Bool pending_modeset; /** @} */ DamagePtr damage; diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c index 930a2716f..756aa45c8 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.c +++ b/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -407,6 +407,11 @@ drmmode_prop_info_free(drmmode_prop_info_ptr info, int num_props) free(info[i].enum_values); } +static void +drmmode_ConvertToKMode(ScrnInfoPtr scrn, + drmModeModeInfo * kmode, DisplayModePtr mode); + + static int plane_add_prop(drmModeAtomicReq *req, drmmode_crtc_private_ptr drmmode_crtc, enum drmmode_plane_property prop, uint64_t val) @@ -423,6 +428,33 @@ plane_add_prop(drmModeAtomicReq *req, drmmode_crtc_private_ptr drmmode_crtc, } static int +plane_add_props(drmModeAtomicReq *req, xf86CrtcPtr crtc, + uint32_t fb_id, int x, int y) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + int ret = 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, + fb_id ? drmmode_crtc->mode_crtc->crtc_id : 0); + 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, + crtc->mode.HDisplay << 16); + ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_SRC_H, + crtc->mode.VDisplay << 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, + crtc->mode.HDisplay); + ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_CRTC_H, + crtc->mode.VDisplay); + + return ret; +} + +static int crtc_add_prop(drmModeAtomicReq *req, drmmode_crtc_private_ptr drmmode_crtc, enum drmmode_crtc_property prop, uint64_t val) { @@ -485,6 +517,60 @@ drm_mode_ensure_blob(xf86CrtcPtr crtc, drmModeModeInfo mode_info) return ret; } +static int +crtc_add_dpms_props(drmModeAtomicReq *req, xf86CrtcPtr crtc, + int new_dpms, Bool *active) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + Bool crtc_active = FALSE; + int i; + int ret = 0; + + 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 (new_dpms == DPMSModeOn) + crtc_active = TRUE; + + ret |= connector_add_prop(req, drmmode_output, + DRMMODE_CONNECTOR_CRTC_ID, + crtc_active ? + drmmode_crtc->mode_crtc->crtc_id : 0); + } + + if (crtc_active) { + drmModeModeInfo kmode; + + drmmode_ConvertToKMode(crtc->scrn, &kmode, &crtc->mode); + ret |= drm_mode_ensure_blob(crtc, kmode); + + 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); + } else { + ret |= crtc_add_prop(req, drmmode_crtc, + DRMMODE_CRTC_ACTIVE, 0); + ret |= crtc_add_prop(req, drmmode_crtc, + DRMMODE_CRTC_MODE_ID, 0); + } + + if (active) + *active = crtc_active; + + return ret; +} + static void drm_mode_destroy(xf86CrtcPtr crtc, drmmode_mode_ptr mode) { @@ -495,85 +581,179 @@ drm_mode_destroy(xf86CrtcPtr crtc, drmmode_mode_ptr mode) free(mode); } -static void -drmmode_ConvertToKMode(ScrnInfoPtr scrn, - drmModeModeInfo * kmode, DisplayModePtr mode); +static int +drmmode_crtc_can_test_mode(xf86CrtcPtr crtc) +{ + modesettingPtr ms = modesettingPTR(crtc->scrn); -int -drmmode_crtc_set_fb(xf86CrtcPtr crtc, DisplayModePtr mode, uint32_t fb_id, - int x, int y, uint32_t flags, void *data) + return ms->atomic_modeset; +} + +static Bool +drmmode_crtc_get_fb_id(xf86CrtcPtr crtc, uint32_t *fb_id, int *x, int *y) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + int ret; + + 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; + } + else { + *fb_id = drmmode->fb_id; + *x = crtc->x; + *y = crtc->y; + } + + 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); + return FALSE; + } + *fb_id = drmmode->fb_id; + } + + return TRUE; +} + +void +drmmode_set_dpms(ScrnInfoPtr scrn, int dpms, int flags) +{ + modesettingPtr ms = modesettingPTR(scrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + drmModeAtomicReq *req = drmModeAtomicAlloc(); + uint32_t mode_flags = DRM_MODE_ATOMIC_ALLOW_MODESET; + int ret = 0; + int i; + + assert(ms->atomic_modeset); + + if (!req) + return; + + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + Bool active = FALSE; + + ret |= crtc_add_dpms_props(req, crtc, dpms, &active); + + if (dpms == DPMSModeOn && active && drmmode_crtc->need_modeset) { + uint32_t fb_id; + int x, y; + + if (!drmmode_crtc_get_fb_id(crtc, &fb_id, &x, &y)) + continue; + ret |= plane_add_props(req, crtc, fb_id, x, y); + drmmode_crtc->need_modeset = FALSE; + } + } + + if (ret == 0) + drmModeAtomicCommit(ms->fd, req, mode_flags, NULL); + drmModeAtomicFree(req); + + ms->pending_modeset = TRUE; + xf86DPMSSet(scrn, dpms, flags); + ms->pending_modeset = FALSE; +} + +static int +drmmode_output_disable(xf86OutputPtr output) +{ + modesettingPtr ms = modesettingPTR(output->scrn); + drmmode_output_private_ptr drmmode_output = output->driver_private; + drmModeAtomicReq *req = drmModeAtomicAlloc(); + uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET; + int ret; + + assert(ms->atomic_modeset); + + if (!req) + return 1; + + /* XXX Can we disable all outputs without disabling CRTC right away? */ + ret = connector_add_prop(req, drmmode_output, + DRMMODE_CONNECTOR_CRTC_ID, 0); + if (ret == 0) + ret = drmModeAtomicCommit(ms->fd, req, flags, NULL); + + drmModeAtomicFree(req); + return ret; +} + +static int +drmmode_crtc_disable(xf86CrtcPtr crtc) +{ + modesettingPtr ms = modesettingPTR(crtc->scrn); + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmModeAtomicReq *req = drmModeAtomicAlloc(); + uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET; + int ret = 0; + + assert(ms->atomic_modeset); + + if (!req) + return 1; + + ret |= crtc_add_prop(req, drmmode_crtc, + DRMMODE_CRTC_ACTIVE, 0); + ret |= crtc_add_prop(req, drmmode_crtc, + DRMMODE_CRTC_MODE_ID, 0); + + if (ret == 0) + ret = drmModeAtomicCommit(ms->fd, req, flags, NULL); + + drmModeAtomicFree(req); + return ret; +} + +static int +drmmode_crtc_set_mode(xf86CrtcPtr crtc, Bool test_only) { modesettingPtr ms = modesettingPTR(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; + drmModeModeInfo kmode; int output_count = 0; uint32_t *output_ids = NULL; - drmModeModeInfo kmode; + uint32_t fb_id; + int x, y; int i, ret = 0; - if (mode) - drmmode_ConvertToKMode(crtc->scrn, &kmode, mode); + if (!drmmode_crtc_get_fb_id(crtc, &fb_id, &x, &y)) + return 1; if (ms->atomic_modeset) { drmModeAtomicReq *req = drmModeAtomicAlloc(); + Bool active; + uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET; if (!req) return 1; - if (mode) { - ret = drm_mode_ensure_blob(crtc, kmode); + ret |= crtc_add_dpms_props(req, crtc, DPMSModeOn, &active); + ret |= plane_add_props(req, crtc, active ? fb_id : 0, x, y); - 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 << 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, - crtc->mode.HDisplay << 16); - ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_SRC_H, - crtc->mode.VDisplay << 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, - crtc->mode.HDisplay); - ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_CRTC_H, - crtc->mode.VDisplay); + if (test_only) + flags |= DRM_MODE_ATOMIC_TEST_ONLY; if (ret == 0) - ret = drmModeAtomicCommit(ms->fd, req, flags, data); + ret = drmModeAtomicCommit(ms->fd, req, flags, NULL); drmModeAtomicFree(req); return ret; @@ -597,6 +777,7 @@ drmmode_crtc_set_fb(xf86CrtcPtr crtc, DisplayModePtr mode, uint32_t fb_id, output_count++; } + drmmode_ConvertToKMode(crtc->scrn, &kmode, &crtc->mode); ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, fb_id, x, y, output_ids, output_count, &kmode); @@ -604,6 +785,30 @@ drmmode_crtc_set_fb(xf86CrtcPtr crtc, DisplayModePtr mode, uint32_t fb_id, return ret; } +int +drmmode_crtc_flip(xf86CrtcPtr crtc, uint32_t fb_id, uint32_t flags, void *data) +{ + modesettingPtr ms = modesettingPTR(crtc->scrn); + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + int ret; + + if (ms->atomic_modeset) { + drmModeAtomicReq *req = drmModeAtomicAlloc(); + + if (!req) + return 1; + + ret = plane_add_props(req, crtc, fb_id, crtc->x, crtc->y); + flags |= DRM_MODE_ATOMIC_NONBLOCK; + if (ret == 0) + ret = drmModeAtomicCommit(ms->fd, req, flags, data); + drmModeAtomicFree(req); + return ret; + } + + return drmModePageFlip(ms->fd, drmmode_crtc->mode_crtc->crtc_id, + fb_id, flags, data); +} int drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo) @@ -1077,8 +1282,15 @@ drmmode_ConvertToKMode(ScrnInfoPtr scrn, static void drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode) { + modesettingPtr ms = modesettingPTR(crtc->scrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + /* XXX Check if DPMS mode is already the right one */ + drmmode_crtc->dpms_mode = mode; + + if (ms->atomic_modeset && mode != DPMSModeOn && !ms->pending_modeset) + drmmode_crtc_disable(crtc); } #ifdef GLAMOR_HAS_GBM @@ -1178,6 +1390,7 @@ static Bool drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, int x, int y) { + modesettingPtr ms = modesettingPTR(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; @@ -1185,9 +1398,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, Rotation saved_rotation; DisplayModeRec saved_mode; Bool ret = TRUE; + Bool can_test; int i; - uint32_t fb_id = 0; - uint32_t flags = 0; saved_mode = crtc->mode; saved_x = crtc->x; @@ -1207,35 +1419,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, crtc->gamma_blue, crtc->gamma_size); - 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 = 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; - } - fb_id = drmmode->fb_id; - } - - flags |= DRM_MODE_ATOMIC_ALLOW_MODESET; - if (drmmode_crtc_set_fb(crtc, mode, fb_id, x, y, flags, NULL)) { + can_test = drmmode_crtc_can_test_mode(crtc); + if (drmmode_crtc_set_mode(crtc, can_test)) { xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "failed to set mode: %s\n", strerror(errno)); ret = FALSE; @@ -1246,6 +1431,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, if (crtc->scrn->pScreen) xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen); + ms->pending_modeset = TRUE; drmmode_crtc->need_modeset = FALSE; crtc->funcs->dpms(crtc, DPMSModeOn); @@ -1265,6 +1451,11 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, continue; output->funcs->dpms(output, DPMSModeOn); } + + /* if we only tested the mode previously, really set it now */ + if (can_test) + drmmode_crtc_set_mode(crtc, FALSE); + ms->pending_modeset = FALSE; } done: @@ -2261,20 +2452,22 @@ drmmode_output_destroy(xf86OutputPtr output) static void drmmode_output_dpms(xf86OutputPtr output, int mode) { + modesettingPtr ms = modesettingPTR(output->scrn); drmmode_output_private_ptr drmmode_output = output->driver_private; + drmmode_ptr drmmode = drmmode_output->drmmode; xf86CrtcPtr crtc = output->crtc; - modesettingPtr ms = NULL; drmModeConnectorPtr koutput = drmmode_output->mode_output; - drmmode_ptr drmmode = drmmode_output->drmmode; if (!koutput) return; - if (crtc) - ms = modesettingPTR(crtc->scrn); + /* XXX Check if DPMS mode is already the right one */ - if (ms && ms->atomic_modeset) { - drmmode_output->dpms = mode; + drmmode_output->dpms = mode; + + if (ms->atomic_modeset) { + if (mode != DPMSModeOn && !ms->pending_modeset) + drmmode_output_disable(output); } else { drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id, drmmode_output->dpms_enum_id, mode); diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h index 1086b5ceb..a75576926 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.h +++ b/hw/xfree86/drivers/modesetting/drmmode_display.h @@ -283,7 +283,8 @@ 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, DisplayModePtr mode, uint32_t fb_id, - int x, int y, uint32_t flags, void *data); +int drmmode_crtc_flip(xf86CrtcPtr crtc, uint32_t fb_id, uint32_t flags, void *data); + +void drmmode_set_dpms(ScrnInfoPtr scrn, int PowerManagementMode, int flags); #endif diff --git a/hw/xfree86/drivers/modesetting/pageflip.c b/hw/xfree86/drivers/modesetting/pageflip.c index 5278b1485..9667f132d 100644 --- a/hw/xfree86/drivers/modesetting/pageflip.c +++ b/hw/xfree86/drivers/modesetting/pageflip.c @@ -163,17 +163,8 @@ static Bool do_queue_flip_on_crtc(modesettingPtr ms, xf86CrtcPtr crtc, uint32_t flags, uint32_t seq) { - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - - if (ms->atomic_modeset) { - flags |= DRM_MODE_ATOMIC_NONBLOCK; - return drmmode_crtc_set_fb(crtc, NULL, ms->drmmode.fb_id, crtc->x, crtc->y, flags, - (void *) (uintptr_t) seq); - } - - return drmModePageFlip(ms->fd, drmmode_crtc->mode_crtc->crtc_id, - ms->drmmode.fb_id, flags, - (void *) (uintptr_t) seq); + return drmmode_crtc_flip(crtc, ms->drmmode.fb_id, flags, + (void *) (uintptr_t) seq); } static Bool |