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
dev
Ander Conselvan de Oliveira 12 years ago committed by Kristian Høgsberg
parent be7c4dd2a0
commit 95eb3a2eb4
  1. 2
      src/Makefile.am
  2. 30
      src/compositor-drm.c

@ -133,7 +133,7 @@ if ENABLE_DRM_COMPOSITOR
drm_backend = drm-backend.la drm_backend = drm-backend.la
drm_backend_la_LDFLAGS = -module -avoid-version drm_backend_la_LDFLAGS = -module -avoid-version
drm_backend_la_LIBADD = $(COMPOSITOR_LIBS) $(DRM_COMPOSITOR_LIBS) \ drm_backend_la_LIBADD = $(COMPOSITOR_LIBS) $(DRM_COMPOSITOR_LIBS) \
../shared/libshared.la ../shared/libshared.la -lrt
drm_backend_la_CFLAGS = \ drm_backend_la_CFLAGS = \
$(COMPOSITOR_CFLAGS) \ $(COMPOSITOR_CFLAGS) \
$(DRM_COMPOSITOR_CFLAGS) \ $(DRM_COMPOSITOR_CFLAGS) \

@ -37,6 +37,7 @@
#include <linux/input.h> #include <linux/input.h>
#include <assert.h> #include <assert.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <time.h>
#include <xf86drm.h> #include <xf86drm.h>
#include <xf86drmMode.h> #include <xf86drmMode.h>
@ -52,6 +53,10 @@
#include "udev-seat.h" #include "udev-seat.h"
#include "launcher-util.h" #include "launcher-util.h"
#ifndef DRM_CAP_TIMESTAMP_MONOTONIC
#define DRM_CAP_TIMESTAMP_MONOTONIC 0x6
#endif
static int option_current_mode = 0; static int option_current_mode = 0;
static char *output_name; static char *output_name;
static char *output_mode; static char *output_mode;
@ -114,6 +119,8 @@ struct drm_compositor {
int use_pixman; int use_pixman;
uint32_t prev_state; uint32_t prev_state;
clockid_t clock;
}; };
struct drm_mode { struct drm_mode {
@ -663,10 +670,19 @@ drm_output_start_repaint_loop(struct weston_output *output_base)
output_base->compositor; output_base->compositor;
uint32_t fb_id; uint32_t fb_id;
if (output->current) 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; fb_id = output->current->fb_id;
else
fb_id = output->original_crtc->buffer_id;
if (drmModePageFlip(compositor->drm.fd, output->crtc_id, fb_id, if (drmModePageFlip(compositor->drm.fd, output->crtc_id, fb_id,
DRM_MODE_PAGE_FLIP_EVENT, output) < 0) { DRM_MODE_PAGE_FLIP_EVENT, output) < 0) {
@ -1184,7 +1200,8 @@ static int
init_drm(struct drm_compositor *ec, struct udev_device *device) init_drm(struct drm_compositor *ec, struct udev_device *device)
{ {
const char *filename, *sysnum; const char *filename, *sysnum;
int fd; uint64_t cap;
int fd, ret;
sysnum = udev_device_get_sysnum(device); sysnum = udev_device_get_sysnum(device);
if (sysnum) if (sysnum)
@ -1207,6 +1224,11 @@ init_drm(struct drm_compositor *ec, struct udev_device *device)
ec->drm.fd = fd; 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; return 0;
} }

Loading…
Cancel
Save