summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnder Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>2013-05-07 14:16:59 +0300
committerKristian Høgsberg <krh@bitplanet.net>2013-05-14 10:21:54 -0400
commit95eb3a2eb470bd341ab078c7e48a28ffebc6dde1 (patch)
tree891b678cf26e7902031e342bac4b27048a99e638
parentbe7c4dd2a0044955103786120b73bc9ee521326f (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.am2
-rw-r--r--src/compositor-drm.c32
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;
}