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.
(cherry picked from 89e323e490
commit)
main
parent
c4c47a7eac
commit
ed82172378
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -558,12 +558,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