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.main
parent
7f09f957d9
commit
89e323e490
|
@ -252,6 +252,7 @@ typedef struct _drmTextureRegion {
|
||||||
typedef enum {
|
typedef enum {
|
||||||
DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
|
DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
|
||||||
DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
|
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_SECONDARY = 0x20000000, /**< Secondary display controller */
|
||||||
DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */
|
DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */
|
||||||
} drmVBlankSeqType;
|
} drmVBlankSeqType;
|
||||||
|
|
|
@ -249,8 +249,7 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
|
||||||
drm_wait_vblank_t vblwait;
|
drm_wait_vblank_t vblwait;
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
unsigned int flags;
|
unsigned int flags, seq;
|
||||||
atomic_t *seq;
|
|
||||||
|
|
||||||
if ((!dev->irq) || (!dev->irq_enabled))
|
if ((!dev->irq) || (!dev->irq_enabled))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -272,12 +271,12 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
|
||||||
DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL))
|
DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
seq = (flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2 :
|
seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2
|
||||||
&dev->vbl_received;
|
: &dev->vbl_received);
|
||||||
|
|
||||||
switch (vblwait.request.type & _DRM_VBLANK_TYPES_MASK) {
|
switch (vblwait.request.type & _DRM_VBLANK_TYPES_MASK) {
|
||||||
case _DRM_VBLANK_RELATIVE:
|
case _DRM_VBLANK_RELATIVE:
|
||||||
vblwait.request.sequence += atomic_read(seq);
|
vblwait.request.sequence += seq;
|
||||||
vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
|
vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
|
||||||
case _DRM_VBLANK_ABSOLUTE:
|
case _DRM_VBLANK_ABSOLUTE:
|
||||||
break;
|
break;
|
||||||
|
@ -285,13 +284,18 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((flags & _DRM_VBLANK_NEXTONMISS) &&
|
||||||
|
(seq - vblwait.request.sequence) <= (1<<23)) {
|
||||||
|
vblwait.request.sequence = seq + 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (flags & _DRM_VBLANK_SIGNAL) {
|
if (flags & _DRM_VBLANK_SIGNAL) {
|
||||||
unsigned long irqflags;
|
unsigned long irqflags;
|
||||||
drm_vbl_sig_t *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY)
|
drm_vbl_sig_t *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY)
|
||||||
? &dev->vbl_sigs2 : &dev->vbl_sigs;
|
? &dev->vbl_sigs2 : &dev->vbl_sigs;
|
||||||
drm_vbl_sig_t *vbl_sig;
|
drm_vbl_sig_t *vbl_sig;
|
||||||
|
|
||||||
vblwait.reply.sequence = atomic_read(seq);
|
vblwait.reply.sequence = seq;
|
||||||
|
|
||||||
spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
||||||
|
|
||||||
|
|
|
@ -551,12 +551,14 @@ typedef struct drm_irq_busid {
|
||||||
typedef enum {
|
typedef enum {
|
||||||
_DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
|
_DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
|
||||||
_DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
|
_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_SECONDARY = 0x20000000, /**< Secondary display controller */
|
||||||
_DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */
|
_DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */
|
||||||
} drm_vblank_seq_type_t;
|
} drm_vblank_seq_type_t;
|
||||||
|
|
||||||
#define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE)
|
#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 {
|
struct drm_wait_vblank_request {
|
||||||
drm_vblank_seq_type_t type;
|
drm_vblank_seq_type_t type;
|
||||||
|
|
Loading…
Reference in New Issue