/**
 * Wait for a surface to finish being displayed.
 */
VdpStatus
vlVdpPresentationQueueBlockUntilSurfaceIdle(VdpPresentationQueue presentation_queue,
                                            VdpOutputSurface surface,
                                            VdpTime *first_presentation_time)
{
   vlVdpPresentationQueue *pq;
   vlVdpOutputSurface *surf;
   struct pipe_screen *screen;

   if (!first_presentation_time)
      return VDP_STATUS_INVALID_POINTER;

   pq = vlGetDataHTAB(presentation_queue);
   if (!pq)
      return VDP_STATUS_INVALID_HANDLE;

   surf = vlGetDataHTAB(surface);
   if (!surf)
      return VDP_STATUS_INVALID_HANDLE;

   pipe_mutex_lock(pq->device->mutex);
   if (surf->fence) {
      screen = pq->device->vscreen->pscreen;
      screen->fence_finish(screen, surf->fence, 0);
   }
   pipe_mutex_unlock(pq->device->mutex);

   return vlVdpPresentationQueueGetTime(presentation_queue, first_presentation_time);
}
Exemplo n.º 2
0
/**
 * Poll the current queue status of a surface.
 */
VdpStatus
vlVdpPresentationQueueQuerySurfaceStatus(VdpPresentationQueue presentation_queue,
                                         VdpOutputSurface surface,
                                         VdpPresentationQueueStatus *status,
                                         VdpTime *first_presentation_time)
{
   vlVdpPresentationQueue *pq;
   vlVdpOutputSurface *surf;
   struct pipe_screen *screen;

   if (!(status && first_presentation_time))
      return VDP_STATUS_INVALID_POINTER;

   pq = vlGetDataHTAB(presentation_queue);
   if (!pq)
      return VDP_STATUS_INVALID_HANDLE;

   surf = vlGetDataHTAB(surface);
   if (!surf)
      return VDP_STATUS_INVALID_HANDLE;

   *first_presentation_time = 0;

   if (!surf->fence) {
      if (pq->last_surf == surf)
         *status = VDP_PRESENTATION_QUEUE_STATUS_VISIBLE;
      else
         *status = VDP_PRESENTATION_QUEUE_STATUS_IDLE;
   } else {
      pipe_mutex_lock(pq->device->mutex);
      screen = pq->device->vscreen->pscreen;
      if (screen->fence_finish(screen, NULL, surf->fence, 0)) {
         screen->fence_reference(screen, &surf->fence, NULL);
         *status = VDP_PRESENTATION_QUEUE_STATUS_VISIBLE;
         pipe_mutex_unlock(pq->device->mutex);

         // We actually need to query the timestamp of the last VSYNC event from the hardware
         vlVdpPresentationQueueGetTime(presentation_queue, first_presentation_time);
         *first_presentation_time += 1;
      } else {
         *status = VDP_PRESENTATION_QUEUE_STATUS_QUEUED;
         pipe_mutex_unlock(pq->device->mutex);
      }
   }

   return VDP_STATUS_OK;
}