From 3177b4e2cf7d2fff7428cb6057bebbe60ff5cc6c Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Tue, 30 Oct 2007 13:16:50 +0100 Subject: More vblank cleanups. * Fix crash at context creation in most drivers supporting vblank. * Don't pass vblank sequence or flags to functions that get passed the drawable private already. * Attempt to initialize vblank related drawable private fields just once per drawable. May need more work in some drivers. --- src/mesa/drivers/dri/common/vblank.c | 85 ++++++++++++++++++++---------------- src/mesa/drivers/dri/common/vblank.h | 10 ++--- 2 files changed, 51 insertions(+), 44 deletions(-) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/vblank.c b/src/mesa/drivers/dri/common/vblank.c index 0596440463..8f8d94853e 100644 --- a/src/mesa/drivers/dri/common/vblank.c +++ b/src/mesa/drivers/dri/common/vblank.c @@ -299,6 +299,23 @@ static int do_wait( drmVBlank * vbl, GLuint * vbl_seq, int fd ) } +/****************************************************************************/ +/** + * Returns the default swap interval of the given drawable. + */ + +static unsigned +driGetDefaultVBlankInterval( const __DRIdrawablePrivate *priv ) +{ + if ( (priv->vblFlags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) != 0 ) { + return 1; + } + else { + return 0; + } +} + + /****************************************************************************/ /** * Sets the default swap interval when the drawable is first bound to a @@ -307,7 +324,8 @@ static int do_wait( drmVBlank * vbl, GLuint * vbl_seq, int fd ) void driDrawableInitVBlank( __DRIdrawablePrivate *priv ) { - if ( priv->swap_interval == (unsigned)-1 ) { + if ( priv->swap_interval == (unsigned)-1 && + !( priv->vblFlags & VBLANK_FLAG_NO_IRQ ) ) { /* Get current vertical blank sequence */ drmVBlank vbl; @@ -318,8 +336,7 @@ void driDrawableInitVBlank( __DRIdrawablePrivate *priv ) do_wait( &vbl, &priv->vblSeq, priv->driScreenPriv->fd ); priv->vblank_base = priv->vblSeq; - priv->swap_interval = - (priv->vblFlags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) ? 1 : 0; + priv->swap_interval = driGetDefaultVBlankInterval( priv ); } } @@ -330,21 +347,17 @@ void driDrawableInitVBlank( __DRIdrawablePrivate *priv ) */ unsigned -driGetVBlankInterval( const __DRIdrawablePrivate *priv, GLuint flags ) +driGetVBlankInterval( const __DRIdrawablePrivate *priv ) { - if ( (flags & VBLANK_FLAG_INTERVAL) != 0 ) { + if ( (priv->vblFlags & VBLANK_FLAG_INTERVAL) != 0 ) { /* this must have been initialized when the drawable was first bound * to a direct rendering context. */ assert ( priv->swap_interval != (unsigned)-1 ); return priv->swap_interval; } - else if ( (flags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) != 0 ) { - return 1; - } - else { - return 0; - } + else + return driGetDefaultVBlankInterval( priv ); } @@ -354,18 +367,17 @@ driGetVBlankInterval( const __DRIdrawablePrivate *priv, GLuint flags ) */ void -driGetCurrentVBlank( const __DRIdrawablePrivate *priv, GLuint flags, - GLuint *vbl_seq ) +driGetCurrentVBlank( __DRIdrawablePrivate *priv ) { drmVBlank vbl; vbl.request.type = DRM_VBLANK_RELATIVE; - if ( flags & VBLANK_FLAG_SECONDARY ) { + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) { vbl.request.type |= DRM_VBLANK_SECONDARY; } vbl.request.sequence = 0; - (void) do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd ); + (void) do_wait( &vbl, &priv->vblSeq, priv->driScreenPriv->fd ); } @@ -373,19 +385,15 @@ driGetCurrentVBlank( const __DRIdrawablePrivate *priv, GLuint flags, /** * Waits for the vertical blank for use with glXSwapBuffers. * - * \param vbl_seq Vertical blank sequence number (MSC) after the last buffer - * swap. Updated after this wait. - * \param flags \c VBLANK_FLAG bits that control how long to wait. * \param missed_deadline Set to \c GL_TRUE if the MSC after waiting is later - * than the "target" based on \c flags. The idea is that if - * \c missed_deadline is set, then the application is not - * achieving its desired framerate. + * than the "target" based on \c priv->vblFlags. The idea is + * that if \c missed_deadline is set, then the application is + * not achieving its desired framerate. * \return Zero on success, -1 on error. */ int -driWaitForVBlank( const __DRIdrawablePrivate *priv, GLuint * vbl_seq, - GLuint flags, GLboolean * missed_deadline ) +driWaitForVBlank( __DRIdrawablePrivate *priv, GLboolean * missed_deadline ) { drmVBlank vbl; unsigned original_seq; @@ -394,10 +402,10 @@ driWaitForVBlank( const __DRIdrawablePrivate *priv, GLuint * vbl_seq, unsigned diff; *missed_deadline = GL_FALSE; - if ( (flags & (VBLANK_FLAG_INTERVAL | - VBLANK_FLAG_THROTTLE | - VBLANK_FLAG_SYNC)) == 0 || - (flags & VBLANK_FLAG_NO_IRQ) != 0 ) { + if ( (priv->vblFlags & (VBLANK_FLAG_INTERVAL | + VBLANK_FLAG_THROTTLE | + VBLANK_FLAG_SYNC)) == 0 || + (priv->vblFlags & VBLANK_FLAG_NO_IRQ) != 0 ) { return 0; } @@ -408,44 +416,45 @@ driWaitForVBlank( const __DRIdrawablePrivate *priv, GLuint * vbl_seq, * * VBLANK_FLAG_INTERVAL and VBLANK_FLAG_THROTTLE mean to wait for at * least one vertical blank since the last wait. Since do_wait modifies - * vbl_seq, we have to save the original value of vbl_seq for the + * priv->vblSeq, we have to save the original value of priv->vblSeq for the * VBLANK_FLAG_INTERVAL / VBLANK_FLAG_THROTTLE calculation later. */ - original_seq = *vbl_seq; - interval = driGetVBlankInterval(priv, flags); + original_seq = priv->vblSeq; + interval = driGetVBlankInterval(priv); deadline = original_seq + interval; vbl.request.type = DRM_VBLANK_RELATIVE; - if ( flags & VBLANK_FLAG_SECONDARY ) { + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) { vbl.request.type |= DRM_VBLANK_SECONDARY; } - vbl.request.sequence = ((flags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0; + vbl.request.sequence = ((priv->vblFlags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0; - if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) { + if ( do_wait( & vbl, &priv->vblSeq, priv->driScreenPriv->fd ) != 0 ) { return -1; } - diff = *vbl_seq - deadline; + diff = priv->vblSeq - 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; + *missed_deadline = (priv->vblFlags & VBLANK_FLAG_SYNC) ? (diff > 0) : + GL_TRUE; return 0; } /* Wait until the target vertical blank. */ vbl.request.type = DRM_VBLANK_ABSOLUTE; - if ( flags & VBLANK_FLAG_SECONDARY ) { + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) { vbl.request.type |= DRM_VBLANK_SECONDARY; } vbl.request.sequence = deadline; - if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) { + if ( do_wait( & vbl, &priv->vblSeq, priv->driScreenPriv->fd ) != 0 ) { return -1; } - diff = *vbl_seq - deadline; + diff = priv->vblSeq - deadline; *missed_deadline = diff > 0 && diff <= (1 << 23); return 0; diff --git a/src/mesa/drivers/dri/common/vblank.h b/src/mesa/drivers/dri/common/vblank.h index e8550b2812..4613c09222 100644 --- a/src/mesa/drivers/dri/common/vblank.h +++ b/src/mesa/drivers/dri/common/vblank.h @@ -53,12 +53,10 @@ extern int driWaitForMSC32( __DRIdrawablePrivate *priv, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t * msc ); extern GLuint driGetDefaultVBlankFlags( const driOptionCache *optionCache ); extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv ); -extern unsigned driGetVBlankInterval( const __DRIdrawablePrivate *priv, - GLuint flags ); -extern void driGetCurrentVBlank( const __DRIdrawablePrivate *priv, - GLuint flags, GLuint *vbl_seq ); -extern int driWaitForVBlank( const __DRIdrawablePrivate *priv, - GLuint * vbl_seq, GLuint flags, GLboolean * missed_deadline ); +extern unsigned driGetVBlankInterval( const __DRIdrawablePrivate *priv ); +extern void driGetCurrentVBlank( __DRIdrawablePrivate *priv ); +extern int driWaitForVBlank( __DRIdrawablePrivate *priv, + GLboolean * missed_deadline ); #undef usleep #include /* for usleep() */ -- cgit v1.2.3