Esempio n. 1
0
static gpointer
gst_wl_display_thread_run (gpointer data)
{
  GstWlDisplay *self = data;
  GstPollFD pollfd = GST_POLL_FD_INIT;

  pollfd.fd = wl_display_get_fd (self->display);
  gst_poll_add_fd (self->wl_fd_poll, &pollfd);
  gst_poll_fd_ctl_read (self->wl_fd_poll, &pollfd, TRUE);

  /* main loop */
  while (1) {
    while (wl_display_prepare_read_queue (self->display, self->queue) != 0)
      wl_display_dispatch_queue_pending (self->display, self->queue);
    wl_display_flush (self->display);

    if (gst_poll_wait (self->wl_fd_poll, GST_CLOCK_TIME_NONE) < 0) {
      gboolean normal = (errno == EBUSY);
      wl_display_cancel_read (self->display);
      if (normal)
        break;
      else
        goto error;
    } else {
      wl_display_read_events (self->display);
      wl_display_dispatch_queue_pending (self->display, self->queue);
    }
  }

  return NULL;

error:
  GST_ERROR ("Error communicating with the wayland server");
  return NULL;
}
static gboolean
gst_vaapi_window_wayland_sync (GstVaapiWindow * window)
{
    GstVaapiWindowWaylandPrivate *const priv =
        GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window);
    struct wl_display *const wl_display =
        GST_VAAPI_OBJECT_NATIVE_DISPLAY (window);

    if (priv->sync_failed)
        return FALSE;

    if (priv->pollfd.fd < 0) {
        priv->pollfd.fd = wl_display_get_fd (wl_display);
        gst_poll_add_fd (priv->poll, &priv->pollfd);
        gst_poll_fd_ctl_read (priv->poll, &priv->pollfd, TRUE);
    }

    while (g_atomic_int_get (&priv->num_frames_pending) > 0) {
        while (wl_display_prepare_read_queue (wl_display, priv->event_queue) < 0) {
            if (wl_display_dispatch_queue_pending (wl_display, priv->event_queue) < 0)
                goto error;
        }

        if (wl_display_flush (wl_display) < 0)
            goto error;

again:
        if (gst_poll_wait (priv->poll, GST_CLOCK_TIME_NONE) < 0) {
            int saved_errno = errno;
            if (saved_errno == EAGAIN || saved_errno == EINTR)
                goto again;
            if (saved_errno == EBUSY) {       /* closing */
                wl_display_cancel_read (wl_display);
                return FALSE;
            }
            goto error;
        }

        if (wl_display_read_events (wl_display) < 0)
            goto error;
        if (wl_display_dispatch_queue_pending (wl_display, priv->event_queue) < 0)
            goto error;
    }
    return TRUE;

    /* ERRORS */
error:
    {
        priv->sync_failed = TRUE;
        GST_ERROR ("Error on dispatching events: %s", g_strerror (errno));
        return FALSE;
    }
}
static gpointer
gst_mfx_window_wayland_thread_run (gpointer window)
{
  GstMfxWindowWaylandPrivate *const priv =
      GST_MFX_WINDOW_WAYLAND_GET_PRIVATE (window);
  struct wl_display *const wl_display =
      GST_MFX_DISPLAY_HANDLE (GST_MFX_WINDOW_DISPLAY (window));

  if (priv->sync_failed)
    return NULL;

  if (priv->pollfd.fd < 0) {
    priv->pollfd.fd = wl_display_get_fd (wl_display);
    gst_poll_add_fd (priv->poll, &priv->pollfd);
    gst_poll_fd_ctl_read (priv->poll, &priv->pollfd, TRUE);
  }

  while (1) {
    while (wl_display_prepare_read_queue (wl_display, priv->event_queue) < 0) {
      if (wl_display_dispatch_queue_pending (wl_display, priv->event_queue) < 0)
        goto error;
    }

    if (wl_display_flush (wl_display) < 0)
      goto error;

  again:
    if (gst_poll_wait (priv->poll, GST_CLOCK_TIME_NONE) < 0) {
      int saved_errno = errno;
      if (saved_errno == EAGAIN || saved_errno == EINTR)
        goto again;
      wl_display_cancel_read (wl_display);
      if (saved_errno == EBUSY) /* flushing */
        return NULL;
      else
        goto error;
    }
    if (wl_display_read_events (wl_display) < 0)
      goto error;
    if (wl_display_dispatch_queue_pending (wl_display, priv->event_queue) < 0)
      goto error;
  }

  return NULL;
error:
  priv->sync_failed = TRUE;
  GST_ERROR ("Error on dispatching events: %s", g_strerror (errno));
  return NULL;
}
Esempio n. 4
0
/** Prepare to read events after polling file descriptor
 *
 * \param display The display context object
 * \return 0 on success or -1 if event queue was not empty
 *
 * This function must be called before reading from the file
 * descriptor using wl_display_read_events().  Calling
 * wl_display_prepare_read() announces the calling threads intention
 * to read and ensures that until the thread is ready to read and
 * calls wl_display_read_events(), no other thread will read from the
 * file descriptor.  This only succeeds if the event queue is empty
 * though, and if there are undispatched events in the queue, -1 is
 * returned and errno set to EAGAIN.
 *
 * If a thread successfully calls wl_display_prepare_read(), it must
 * either call wl_display_read_events() when it's ready or cancel the
 * read intention by calling wl_display_cancel_read().
 *
 * Use this function before polling on the display fd or to integrate
 * the fd into a toolkit event loop in a race-free way.  Typically, a
 * toolkit will call wl_display_dispatch_pending() before sleeping, to
 * make sure it doesn't block with unhandled events.  Upon waking up,
 * it will assume the file descriptor is readable and read events from
 * the fd by calling wl_display_dispatch().  Simplified, we have:
 *
 *   wl_display_dispatch_pending(display);
 *   wl_display_flush(display);
 *   poll(fds, nfds, -1);
 *   wl_display_dispatch(display);
 *
 * There are two races here: first, before blocking in poll(), the fd
 * could become readable and another thread reads the events.  Some of
 * these events may be for the main queue and the other thread will
 * queue them there and then the main thread will go to sleep in
 * poll().  This will stall the application, which could be waiting
 * for a event to kick of the next animation frame, for example.
 *
 * The other race is immediately after poll(), where another thread
 * could preempt and read events before the main thread calls
 * wl_display_dispatch().  This call now blocks and starves the other
 * fds in the event loop.
 *
 * A correct sequence would be:
 *
 *   while (wl_display_prepare_read(display) != 0)
 *           wl_display_dispatch_pending(display);
 *   wl_display_flush(display);
 *   poll(fds, nfds, -1);
 *   wl_display_read_events(display);
 *   wl_display_dispatch_pending(display);
 *
 * Here we call wl_display_prepare_read(), which ensures that between
 * returning from that call and eventually calling
 * wl_display_read_events(), no other thread will read from the fd and
 * queue events in our queue.  If the call to
 * wl_display_prepare_read() fails, we dispatch the pending events and
 * try again until we're successful.
 *
 * \memberof wl_display
 */
WL_EXPORT int
wl_display_prepare_read(struct wl_display *display)
{
	return wl_display_prepare_read_queue(display, &display->queue);
}
Esempio n. 5
0
	int PrepareReadQueue(struct wl_event_queue *queue){
		return wl_display_prepare_read_queue(cobj, queue);
	}