Commit 4023d537 authored by Louis-Francis Ratté-Boulianne's avatar Louis-Francis Ratté-Boulianne Committed by Adam Jackson

modesetting: Use atomic modesetting API for pageflip if available

In order to flip between compressed and uncompressed buffers -
something drmModePageFlip explicitly bans us from doing - we need
to port use the atomic modesetting API. It's only 'fake' atomic
though given we still commit for each CRTC separately and
CRTC and connector properties are not set with the atomic API.

The helper functions to retrieve DRM properties have been borrowed
from Weston.
Signed-off-by: Louis-Francis Ratté-Boulianne's avatarLouis-Francis Ratté-Boulianne <lfrb@collabora.com>
Reviewed-by: Daniel Stone's avatarDaniel Stone <daniels@collabora.com>
Acked-by: Keith Packard's avatarKeith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson's avatarAdam Jackson <ajax@redhat.com>
parent e2ef3b44
......@@ -2101,6 +2101,9 @@ if test "x$GLAMOR" = xyes; then
fi
fi
PKG_CHECK_EXISTS(libdrm >= 2.4.62,
[AC_DEFINE(GLAMOR_HAS_DRM_ATOMIC, 1, [libdrm supports atomic API])],
[])
PKG_CHECK_EXISTS(libdrm >= 2.4.74,
[AC_DEFINE(GLAMOR_HAS_DRM_NAME_FROM_FD_2, 1, [Have GLAMOR_HAS_DRM_NAME_FROM_FD_2])],
[])
......
......@@ -1018,6 +1018,12 @@ PreInit(ScrnInfoPtr pScrn, int flags)
}
#endif
#ifdef GLAMOR_HAS_DRM_ATOMIC
ret = drmSetClientCap(ms->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
ret |= drmSetClientCap(ms->fd, DRM_CLIENT_CAP_ATOMIC, 1);
ms->atomic_modeset = (ret == 0);
#endif
if (drmmode_pre_init(pScrn, &ms->drmmode, pScrn->bitsPerPixel / 8) == FALSE) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "KMS setup failed\n");
goto fail;
......
......@@ -105,6 +105,7 @@ typedef struct _modesettingRec {
* Page flipping stuff.
* @{
*/
Bool atomic_modeset;
/** @} */
DamagePtr damage;
......
......@@ -36,6 +36,22 @@
struct gbm_device;
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__COUNT
};
enum drmmode_plane_type {
DRMMODE_PLANE_TYPE_PRIMARY = 0,
DRMMODE_PLANE_TYPE_CURSOR,
DRMMODE_PLANE_TYPE_OVERLAY,
DRMMODE_PLANE_TYPE__COUNT
};
typedef struct {
struct dumb_bo *dumb;
#ifdef GLAMOR_HAS_GBM
......@@ -88,6 +104,19 @@ typedef struct {
Bool present_enable;
} drmmode_rec, *drmmode_ptr;
typedef struct {
const char *name;
Bool valid;
uint64_t value;
} drmmode_prop_enum_info_rec, *drmmode_prop_enum_info_ptr;
typedef struct {
const char *name;
uint32_t prop_id;
unsigned int num_enum_values;
drmmode_prop_enum_info_rec *enum_values;
} drmmode_prop_info_rec, *drmmode_prop_info_ptr;
typedef struct {
drmmode_ptr drmmode;
drmModeCrtcPtr mode_crtc;
......@@ -97,6 +126,9 @@ typedef struct {
Bool cursor_up;
uint16_t lut_r[256], lut_g[256], lut_b[256];
drmmode_prop_info_rec props_plane[DRMMODE_PLANE__COUNT];
uint32_t plane_id;
drmmode_bo rotate_bo;
unsigned rotate_fb_id;
......@@ -205,6 +237,10 @@ void drmmode_get_default_bpp(ScrnInfoPtr pScrn, drmmode_ptr drmmmode,
int *depth, int *bpp);
void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
int drmmode_crtc_set_fb(xf86CrtcPtr crtc, uint32_t fb_id,
int x, int y, uint32_t flags, void *data);
#ifndef DRM_CAP_DUMB_PREFERRED_DEPTH
#define DRM_CAP_DUMB_PREFERRED_DEPTH 3
#endif
......
......@@ -159,6 +159,25 @@ ms_pageflip_abort(void *data)
ms_pageflip_free(flip);
}
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;
#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,
(void *) (uintptr_t) seq);
}
#endif
return drmModePageFlip(ms->fd, drmmode_crtc->mode_crtc->crtc_id,
ms->drmmode.fb_id, flags,
(void *) (uintptr_t) seq);
}
static Bool
queue_flip_on_crtc(ScreenPtr screen, xf86CrtcPtr crtc,
struct ms_flipdata *flipdata,
......@@ -193,8 +212,7 @@ queue_flip_on_crtc(ScreenPtr screen, xf86CrtcPtr crtc,
/* take a reference on flipdata for use in flip */
flipdata->flip_count++;
while (drmModePageFlip(ms->fd, drmmode_crtc->mode_crtc->crtc_id,
ms->drmmode.fb_id, flags, (void *) (uintptr_t) seq)) {
while (do_queue_flip_on_crtc(ms, crtc, flags, seq)) {
err = errno;
/* We may have failed because the event queue was full. Flush it
* and retry. If there was nothing to flush, then we failed for
......
......@@ -491,6 +491,9 @@
/* Build glamor use new drmGetDeviceNameFromFD2 */
#undef GLAMOR_HAS_DRM_NAME_FROM_FD_2
/* Glamor should use atomic DRM API */
#undef GLAMOR_HAS_DRM_ATOMIC
/* byte order */
#undef X_BYTE_ORDER
......
......@@ -73,6 +73,8 @@ conf_data.set_quoted('SHMDIR', '/tmp')
conf_data.set('HAVE_XSHMFENCE', xshmfence_dep.found())
conf_data.set('WITH_LIBDRM', libdrm_dep.found())
conf_data.set('GLAMOR_HAS_DRM_ATOMIC',
libdrm_dep.found() and libdrm_dep.version().version_compare('>= 2.4.62'))
conf_data.set('GLAMOR_HAS_DRM_NAME_FROM_FD_2',
libdrm_dep.found() and libdrm_dep.version().version_compare('>= 2.4.74'))
conf_data.set('GLXEXT', build_glx)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment