drm: Send pending vblank events before disabling vblank.
This is the least-bad behaviour. It means that we signal the vblank event before it actually happens, but since we're disabling vblanks there's no guarantee that it will *ever* happen otherwise. This prevents GL applications which use WaitMSC from hanging indefinitely. Signed-off-by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
eaa4f5e1d0
commit
498548ec69
|
@ -932,11 +932,34 @@ EXPORT_SYMBOL(drm_vblank_put);
|
||||||
|
|
||||||
void drm_vblank_off(struct drm_device *dev, int crtc)
|
void drm_vblank_off(struct drm_device *dev, int crtc)
|
||||||
{
|
{
|
||||||
|
struct drm_pending_vblank_event *e, *t;
|
||||||
|
struct timeval now;
|
||||||
unsigned long irqflags;
|
unsigned long irqflags;
|
||||||
|
unsigned int seq;
|
||||||
|
|
||||||
spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
||||||
vblank_disable_and_save(dev, crtc);
|
vblank_disable_and_save(dev, crtc);
|
||||||
DRM_WAKEUP(&dev->vbl_queue[crtc]);
|
DRM_WAKEUP(&dev->vbl_queue[crtc]);
|
||||||
|
|
||||||
|
/* Send any queued vblank events, lest the natives grow disquiet */
|
||||||
|
seq = drm_vblank_count_and_time(dev, crtc, &now);
|
||||||
|
list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
|
||||||
|
if (e->pipe != crtc)
|
||||||
|
continue;
|
||||||
|
DRM_DEBUG("Sending premature vblank event on disable: \
|
||||||
|
wanted %d, current %d\n",
|
||||||
|
e->event.sequence, seq);
|
||||||
|
|
||||||
|
e->event.sequence = seq;
|
||||||
|
e->event.tv_sec = now.tv_sec;
|
||||||
|
e->event.tv_usec = now.tv_usec;
|
||||||
|
drm_vblank_put(dev, e->pipe);
|
||||||
|
list_move_tail(&e->base.link, &e->base.file_priv->event_list);
|
||||||
|
wake_up_interruptible(&e->base.file_priv->event_wait);
|
||||||
|
trace_drm_vblank_event_delivered(e->base.pid, e->pipe,
|
||||||
|
e->event.sequence);
|
||||||
|
}
|
||||||
|
|
||||||
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
|
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_vblank_off);
|
EXPORT_SYMBOL(drm_vblank_off);
|
||||||
|
|
Loading…
Reference in New Issue