diff options
author | Michel Dänzer <[email protected]> | 2006-09-28 14:03:02 +0000 |
---|---|---|
committer | Michel Dänzer <[email protected]> | 2006-09-28 14:03:02 +0000 |
commit | 6a2f5c6752213cea67b142727eba9e0900952346 (patch) | |
tree | 05784d009260b90376056f1114707af7bdf13c01 /src/mesa/drivers | |
parent | 24bb3b399847bdb11f0008820c2c1bad1e21d499 (diff) |
Some restructuring of the driWaitForVBlank() code.
Also some minor fixes for detecting when the deadline is met or missed, in
particular wrt wraparounds of the sequence number.
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r-- | src/mesa/drivers/dri/common/vblank.c | 50 |
1 files changed, 27 insertions, 23 deletions
diff --git a/src/mesa/drivers/dri/common/vblank.c b/src/mesa/drivers/dri/common/vblank.c index 25b912e8242..c7c7b8296ec 100644 --- a/src/mesa/drivers/dri/common/vblank.c +++ b/src/mesa/drivers/dri/common/vblank.c @@ -260,7 +260,8 @@ void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags, drmVBlank vbl = { .request={ .type = DRM_VBLANK_RELATIVE, .sequence = 0 } }; do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd ); - priv->pdraw->swap_interval = (flags & VBLANK_FLAG_THROTTLE) != 0 ? 1 : 0; + priv->pdraw->swap_interval = (flags & (VBLANK_FLAG_THROTTLE | + VBLANK_FLAG_SYNC)) != 0 ? 1 : 0; } } @@ -287,7 +288,7 @@ driWaitForVBlank( const __DRIdrawablePrivate *priv, GLuint * vbl_seq, unsigned original_seq; unsigned deadline; unsigned interval; - + unsigned diff; *missed_deadline = GL_FALSE; if ( (flags & (VBLANK_FLAG_INTERVAL | @@ -310,43 +311,46 @@ driWaitForVBlank( const __DRIdrawablePrivate *priv, GLuint * vbl_seq, original_seq = *vbl_seq; - vbl.request.sequence = ((flags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0; - vbl.request.type = DRM_VBLANK_RELATIVE; - - if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) { - return -1; - } - - - vbl.request.type = DRM_VBLANK_ABSOLUTE; - if ( (flags & VBLANK_FLAG_INTERVAL) != 0 ) { interval = priv->pdraw->swap_interval; /* this must have been initialized when the drawable was first bound * to a direct rendering context. */ assert ( interval != (unsigned)-1 ); } - else if ( (flags & VBLANK_FLAG_THROTTLE) != 0 ) { + else if ( (flags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) != 0 ) { interval = 1; } else { interval = 0; } + deadline = original_seq + interval; - /* Wait until the next vertical blank. If the interval is zero, then - * the deadline is one vertical blank after the previous wait. - */ + vbl.request.sequence = ((flags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0; + vbl.request.type = DRM_VBLANK_RELATIVE; + + if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) { + return -1; + } - vbl.request.sequence = original_seq + interval; - if ( *vbl_seq < vbl.request.sequence ) { - if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) { - return -1; - } + diff = *vbl_seq - deadline; + + /* No need to wait again if we've already reached the target */ + if (diff <= (1 << 23)) { + *missed_deadline = (flags & VBLANK_FLAG_SYNC) ? (diff > 0) : GL_TRUE; + return 0; + } + + /* Wait until the target vertical blank. */ + vbl.request.type = DRM_VBLANK_ABSOLUTE; + vbl.request.sequence = deadline; + + if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) { + return -1; } - deadline = original_seq + ((interval == 0) ? 1 : interval); - *missed_deadline = ( *vbl_seq > deadline ); + diff = *vbl_seq - deadline; + *missed_deadline = diff > 0 && diff <= (1 << 23); return 0; } |