OSDN Git Service

i915_vblank_swap: Add support for DRM_VBLANK_NEXTONMISS.
authorMichel Dänzer <michel@tungstengraphics.com>
Wed, 13 Sep 2006 06:59:35 +0000 (08:59 +0200)
committerMichel Dänzer <michel@tungstengraphics.com>
Fri, 29 Sep 2006 10:55:09 +0000 (12:55 +0200)
(cherry picked from 0356fe260dcf80f6d2d20e3384f2a1f4ee7f5b30 commit)

shared-core/i915_irq.c

index 158a91d..b72ceb2 100644 (file)
@@ -431,7 +431,7 @@ int i915_vblank_swap(DRM_IOCTL_ARGS)
                                 sizeof(swap));
 
        if (swap.seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE |
-                            _DRM_VBLANK_SECONDARY)) {
+                            _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS)) {
                DRM_ERROR("Invalid sequence type 0x%x\n", swap.seqtype);
                return DRM_ERR(EINVAL);
        }
@@ -440,11 +440,6 @@ int i915_vblank_swap(DRM_IOCTL_ARGS)
 
        seqtype = swap.seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE);
 
-       if (seqtype == _DRM_VBLANK_RELATIVE && swap.sequence == 0) {
-               DRM_DEBUG("Not scheduling swap for current sequence\n");
-               return DRM_ERR(EINVAL);
-       }
-
        if (!(dev_priv->vblank_pipe & (1 << pipe))) {
                DRM_ERROR("Invalid pipe %d\n", pipe);
                return DRM_ERR(EINVAL);
@@ -462,21 +457,20 @@ int i915_vblank_swap(DRM_IOCTL_ARGS)
 
        curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received);
 
-       spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
-
-       switch (seqtype) {
-       case _DRM_VBLANK_RELATIVE:
+       if (seqtype == _DRM_VBLANK_RELATIVE)
                swap.sequence += curseq;
-               break;
-       case _DRM_VBLANK_ABSOLUTE:
-               if ((curseq - swap.sequence) <= (1<<23)) {
-                       spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
+
+       if ((curseq - swap.sequence) <= (1<<23)) {
+               if (swap.seqtype & _DRM_VBLANK_NEXTONMISS) {
+                       swap.sequence = curseq + 1;
+               } else {
                        DRM_DEBUG("Missed target sequence\n");
                        return DRM_ERR(EINVAL);
                }
-               break;
        }
 
+       spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
+
        list_for_each(list, &dev_priv->vbl_swaps.head) {
                vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head);