diff options
author | Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> | 2013-05-07 14:16:59 +0300 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2013-05-14 10:21:54 -0400 |
commit | 95eb3a2eb470bd341ab078c7e48a28ffebc6dde1 (patch) | |
tree | 891b678cf26e7902031e342bac4b27048a99e638 | |
parent | be7c4dd2a0044955103786120b73bc9ee521326f (diff) |
compositor-drm: Don't page flip before a mode is set
The function drm_output_start_repaint_loop() unconditionally issues a
page flip, even if the crtc for that output has not been enabled yet.
That causes the page flip to fail, and drm_output_repaint() is never
called.
Solve this by bypassing the initial page flip if the output needs a
mode set.
This has the caveat of affecting latency predictability for that first
frame and when a "driver" mode fullscreen surface causes a mode set.
However, on both cases the mode set would take an unpredictable amount
of time anyway.
https://bugs.freedesktop.org/show_bug.cgi?id=63812
https://bugs.freedesktop.org/show_bug.cgi?id=64183
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/compositor-drm.c | 32 |
2 files changed, 28 insertions, 6 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 1b55181..859f583 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -133,7 +133,7 @@ if ENABLE_DRM_COMPOSITOR drm_backend = drm-backend.la drm_backend_la_LDFLAGS = -module -avoid-version drm_backend_la_LIBADD = $(COMPOSITOR_LIBS) $(DRM_COMPOSITOR_LIBS) \ - ../shared/libshared.la + ../shared/libshared.la -lrt drm_backend_la_CFLAGS = \ $(COMPOSITOR_CFLAGS) \ $(DRM_COMPOSITOR_CFLAGS) \ diff --git a/src/compositor-drm.c b/src/compositor-drm.c index bb8ea46..9dce809 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -37,6 +37,7 @@ #include <linux/input.h> #include <assert.h> #include <sys/mman.h> +#include <time.h> #include <xf86drm.h> #include <xf86drmMode.h> @@ -52,6 +53,10 @@ #include "udev-seat.h" #include "launcher-util.h" +#ifndef DRM_CAP_TIMESTAMP_MONOTONIC +#define DRM_CAP_TIMESTAMP_MONOTONIC 0x6 +#endif + static int option_current_mode = 0; static char *output_name; static char *output_mode; @@ -114,6 +119,8 @@ struct drm_compositor { int use_pixman; uint32_t prev_state; + + clockid_t clock; }; struct drm_mode { @@ -663,10 +670,19 @@ drm_output_start_repaint_loop(struct weston_output *output_base) output_base->compositor; uint32_t fb_id; - if (output->current) - fb_id = output->current->fb_id; - else - fb_id = output->original_crtc->buffer_id; + struct timespec ts; + + if (!output->current) { + /* We can't page flip if there's no mode set */ + uint32_t msec; + + clock_gettime(compositor->clock, &ts); + msec = ts.tv_sec * 1000 + ts.tv_nsec / 1000000; + weston_output_finish_frame(output_base, msec); + return; + } + + fb_id = output->current->fb_id; if (drmModePageFlip(compositor->drm.fd, output->crtc_id, fb_id, DRM_MODE_PAGE_FLIP_EVENT, output) < 0) { @@ -1184,7 +1200,8 @@ static int init_drm(struct drm_compositor *ec, struct udev_device *device) { const char *filename, *sysnum; - int fd; + uint64_t cap; + int fd, ret; sysnum = udev_device_get_sysnum(device); if (sysnum) @@ -1207,6 +1224,11 @@ init_drm(struct drm_compositor *ec, struct udev_device *device) ec->drm.fd = fd; + ret = drmGetCap(fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap); + if (ret == 0 && cap == 1) + ec->clock = CLOCK_MONOTONIC; + else + ec->clock = CLOCK_REALTIME; return 0; } |