211
211
/****************************************************************************/
213
* Sets the default swap interval when the drawable is first bound to a
214
* direct rendering context.
217
void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags )
219
if ( priv->pdraw->swap_interval == (unsigned)-1 ) {
220
priv->pdraw->swap_interval = (flags & VBLANK_FLAG_THROTTLE) != 0 ? 1 : 0;
225
/****************************************************************************/
227
213
* Wrapper to call \c drmWaitVBlank. The main purpose of this function is to
228
214
* wrap the error message logging. The error message should only be logged
229
215
* the first time the \c drmWaitVBlank fails. If \c drmWaitVBlank is
263
249
/****************************************************************************/
251
* Sets the default swap interval when the drawable is first bound to a
252
* direct rendering context.
255
void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags,
258
if ( priv->pdraw->swap_interval == (unsigned)-1 ) {
259
/* Get current vertical blank sequence */
260
drmVBlank vbl = { .request={ .type = DRM_VBLANK_RELATIVE, .sequence = 0 } };
261
do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd );
263
priv->pdraw->swap_interval = (flags & (VBLANK_FLAG_THROTTLE |
264
VBLANK_FLAG_SYNC)) != 0 ? 1 : 0;
269
/****************************************************************************/
271
* Returns the current swap interval of the given drawable.
275
driGetVBlankInterval( const __DRIdrawablePrivate *priv, GLuint flags )
277
if ( (flags & VBLANK_FLAG_INTERVAL) != 0 ) {
278
/* this must have been initialized when the drawable was first bound
279
* to a direct rendering context. */
280
assert ( priv->pdraw->swap_interval != (unsigned)-1 );
282
return priv->pdraw->swap_interval;
284
else if ( (flags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) != 0 ) {
293
/****************************************************************************/
295
* Returns the current vertical blank sequence number of the given drawable.
299
driGetCurrentVBlank( const __DRIdrawablePrivate *priv, GLuint flags,
304
vbl.request.type = DRM_VBLANK_RELATIVE;
305
if ( flags & VBLANK_FLAG_SECONDARY ) {
306
vbl.request.type |= DRM_VBLANK_SECONDARY;
308
vbl.request.sequence = 0;
310
(void) do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd );
314
/****************************************************************************/
265
316
* Waits for the vertical blank for use with glXSwapBuffers.
267
318
* \param vbl_seq Vertical blank sequence number (MSC) after the last buffer
306
357
original_seq = *vbl_seq;
358
interval = driGetVBlankInterval(priv, flags);
359
deadline = original_seq + interval;
361
vbl.request.type = DRM_VBLANK_RELATIVE;
362
if ( flags & VBLANK_FLAG_SECONDARY ) {
363
vbl.request.type |= DRM_VBLANK_SECONDARY;
308
365
vbl.request.sequence = ((flags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0;
309
vbl.request.type = DRM_VBLANK_RELATIVE;
311
367
if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) {
371
diff = *vbl_seq - deadline;
373
/* No need to wait again if we've already reached the target */
374
if (diff <= (1 << 23)) {
375
*missed_deadline = (flags & VBLANK_FLAG_SYNC) ? (diff > 0) : GL_TRUE;
379
/* Wait until the target vertical blank. */
316
380
vbl.request.type = DRM_VBLANK_ABSOLUTE;
318
if ( (flags & VBLANK_FLAG_INTERVAL) != 0 ) {
319
interval = priv->pdraw->swap_interval;
320
/* this must have been initialized when the drawable was first bound
321
* to a direct rendering context. */
322
assert ( interval != (unsigned)-1 );
324
else if ( (flags & VBLANK_FLAG_THROTTLE) != 0 ) {
332
/* Wait until the next vertical blank. If the interval is zero, then
333
* the deadline is one vertical blank after the previous wait.
336
vbl.request.sequence = original_seq + interval;
337
if ( *vbl_seq < vbl.request.sequence ) {
338
if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) {
343
deadline = original_seq + ((interval == 0) ? 1 : interval);
344
*missed_deadline = ( *vbl_seq > deadline );
381
if ( flags & VBLANK_FLAG_SECONDARY ) {
382
vbl.request.type |= DRM_VBLANK_SECONDARY;
384
vbl.request.sequence = deadline;
386
if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) {
390
diff = *vbl_seq - deadline;
391
*missed_deadline = diff > 0 && diff <= (1 << 23);