From 89e323e4900af84cc33219ad24eb0b435a039d23 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michel=20D=C3=A4nzer?= Date: Fri, 1 Sep 2006 11:27:14 +0200 Subject: [PATCH] Core vsync: Add flag DRM_VBLANK_NEXTONMISS. When this flag is set and the target sequence is missed, wait for the next vertical blank instead of returning immediately. --- libdrm/xf86drm.h | 1 + linux-core/drm_irq.c | 16 ++++++++++------ shared-core/drm.h | 4 +++- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index cda570d..2ad7080 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -252,6 +252,7 @@ typedef struct _drmTextureRegion { typedef enum { DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ + DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */ } drmVBlankSeqType; diff --git a/linux-core/drm_irq.c b/linux-core/drm_irq.c index fef0e8d..bd8a9c8 100644 --- a/linux-core/drm_irq.c +++ b/linux-core/drm_irq.c @@ -249,8 +249,7 @@ int drm_wait_vblank(DRM_IOCTL_ARGS) drm_wait_vblank_t vblwait; struct timeval now; int ret = 0; - unsigned int flags; - atomic_t *seq; + unsigned int flags, seq; if ((!dev->irq) || (!dev->irq_enabled)) return -EINVAL; @@ -272,12 +271,12 @@ int drm_wait_vblank(DRM_IOCTL_ARGS) DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL)) return -EINVAL; - seq = (flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2 : - &dev->vbl_received; + seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2 + : &dev->vbl_received); switch (vblwait.request.type & _DRM_VBLANK_TYPES_MASK) { case _DRM_VBLANK_RELATIVE: - vblwait.request.sequence += atomic_read(seq); + vblwait.request.sequence += seq; vblwait.request.type &= ~_DRM_VBLANK_RELATIVE; case _DRM_VBLANK_ABSOLUTE: break; @@ -285,13 +284,18 @@ int drm_wait_vblank(DRM_IOCTL_ARGS) return -EINVAL; } + if ((flags & _DRM_VBLANK_NEXTONMISS) && + (seq - vblwait.request.sequence) <= (1<<23)) { + vblwait.request.sequence = seq + 1; + } + if (flags & _DRM_VBLANK_SIGNAL) { unsigned long irqflags; drm_vbl_sig_t *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_sigs2 : &dev->vbl_sigs; drm_vbl_sig_t *vbl_sig; - vblwait.reply.sequence = atomic_read(seq); + vblwait.reply.sequence = seq; spin_lock_irqsave(&dev->vbl_lock, irqflags); diff --git a/shared-core/drm.h b/shared-core/drm.h index 614422b..7f90a96 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -551,12 +551,14 @@ typedef struct drm_irq_busid { typedef enum { _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ + _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */ } drm_vblank_seq_type_t; #define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE) -#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_SIGNAL | _DRM_VBLANK_SECONDARY) +#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_SIGNAL | _DRM_VBLANK_SECONDARY | \ + _DRM_VBLANK_NEXTONMISS) struct drm_wait_vblank_request { drm_vblank_seq_type_t type; -- 2.7.4