~ubuntu-branches/ubuntu/quantal/mesa/quantal

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/common/vblank.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-02-21 12:44:07 UTC
  • mfrom: (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 22.
  • Revision ID: james.westby@ubuntu.com-20070221124407-rgcacs32mycrtadl
ImportĀ upstreamĀ versionĀ 6.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
210
210
 
211
211
/****************************************************************************/
212
212
/**
213
 
 * Sets the default swap interval when the drawable is first bound to a
214
 
 * direct rendering context.
215
 
 */
216
 
 
217
 
void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags )
218
 
{
219
 
   if ( priv->pdraw->swap_interval == (unsigned)-1 ) {
220
 
      priv->pdraw->swap_interval = (flags & VBLANK_FLAG_THROTTLE) != 0 ? 1 : 0;
221
 
   }
222
 
}
223
 
 
224
 
 
225
 
/****************************************************************************/
226
 
/**
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
262
248
 
263
249
/****************************************************************************/
264
250
/**
 
251
 * Sets the default swap interval when the drawable is first bound to a
 
252
 * direct rendering context.
 
253
 */
 
254
 
 
255
void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags,
 
256
                            GLuint *vbl_seq )
 
257
{
 
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 );
 
262
 
 
263
      priv->pdraw->swap_interval = (flags & (VBLANK_FLAG_THROTTLE |
 
264
                                             VBLANK_FLAG_SYNC)) != 0 ? 1 : 0;
 
265
   }
 
266
}
 
267
 
 
268
 
 
269
/****************************************************************************/
 
270
/**
 
271
 * Returns the current swap interval of the given drawable.
 
272
 */
 
273
 
 
274
unsigned
 
275
driGetVBlankInterval( const  __DRIdrawablePrivate *priv, GLuint flags )
 
276
{
 
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 );
 
281
 
 
282
      return priv->pdraw->swap_interval;
 
283
   }
 
284
   else if ( (flags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) != 0 ) {
 
285
      return 1;
 
286
   }
 
287
   else {
 
288
      return 0;
 
289
   }
 
290
}
 
291
 
 
292
 
 
293
/****************************************************************************/
 
294
/**
 
295
 * Returns the current vertical blank sequence number of the given drawable.
 
296
 */
 
297
 
 
298
void
 
299
driGetCurrentVBlank( const  __DRIdrawablePrivate *priv, GLuint flags,
 
300
                     GLuint *vbl_seq )
 
301
{
 
302
   drmVBlank vbl;
 
303
 
 
304
   vbl.request.type = DRM_VBLANK_RELATIVE;
 
305
   if ( flags & VBLANK_FLAG_SECONDARY ) {
 
306
      vbl.request.type |= DRM_VBLANK_SECONDARY;
 
307
   }
 
308
   vbl.request.sequence = 0;
 
309
 
 
310
   (void) do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd );
 
311
}
 
312
 
 
313
 
 
314
/****************************************************************************/
 
315
/**
265
316
 * Waits for the vertical blank for use with glXSwapBuffers.
266
317
 * 
267
318
 * \param vbl_seq  Vertical blank sequence number (MSC) after the last buffer
282
333
   unsigned   original_seq;
283
334
   unsigned   deadline;
284
335
   unsigned   interval;
285
 
 
 
336
   unsigned   diff;
286
337
 
287
338
   *missed_deadline = GL_FALSE;
288
339
   if ( (flags & (VBLANK_FLAG_INTERVAL |
304
355
    */
305
356
 
306
357
   original_seq = *vbl_seq;
 
358
   interval = driGetVBlankInterval(priv, flags);
 
359
   deadline = original_seq + interval;
307
360
 
 
361
   vbl.request.type = DRM_VBLANK_RELATIVE;
 
362
   if ( flags & VBLANK_FLAG_SECONDARY ) {
 
363
      vbl.request.type |= DRM_VBLANK_SECONDARY;
 
364
   }
308
365
   vbl.request.sequence = ((flags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0;
309
 
   vbl.request.type = DRM_VBLANK_RELATIVE;
310
 
      
 
366
 
311
367
   if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) {
312
368
      return -1;
313
369
   }
314
370
 
315
 
        
 
371
   diff = *vbl_seq - deadline;
 
372
 
 
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;
 
376
      return 0;
 
377
   }
 
378
 
 
379
   /* Wait until the target vertical blank. */
316
380
   vbl.request.type = DRM_VBLANK_ABSOLUTE;
317
 
 
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 );
323
 
   }
324
 
   else if ( (flags & VBLANK_FLAG_THROTTLE) != 0 ) {
325
 
      interval = 1;
326
 
   }
327
 
   else {
328
 
      interval = 0;
329
 
   }
330
 
 
331
 
 
332
 
   /* Wait until the next vertical blank.  If the interval is zero, then
333
 
    * the deadline is one vertical blank after the previous wait.
334
 
    */
335
 
 
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 ) {
339
 
         return -1;
340
 
      }
341
 
   }
342
 
 
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;
 
383
   }
 
384
   vbl.request.sequence = deadline;
 
385
 
 
386
   if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) {
 
387
      return -1;
 
388
   }
 
389
 
 
390
   diff = *vbl_seq - deadline;
 
391
   *missed_deadline = diff > 0 && diff <= (1 << 23);
345
392
 
346
393
   return 0;
347
394
}