Exemple #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;
}
Exemple #4
0
int WaylandNativeWindow::readQueue(bool block)
{
    int ret = 0;

    if (++m_queueReads == 1) {
        if (block) {
            ret = wl_display_dispatch_queue(m_display, wl_queue);
        } else {
            ret = wl_display_dispatch_queue_pending(m_display, wl_queue);
        }

        // all threads waiting on the false branch will wake and return now, so we
        // can safely set m_queueReads to 0 here instead of relying on every thread
        // to decrement it. This prevents a race condition when a thread enters readQueue()
        // before the one in this thread returns.
        // The new thread would go in the false branch, and there would be no thread in the
        // true branch, blocking the new thread and any other that will call readQueue in
        // the future.
        m_queueReads = 0;

        pthread_cond_broadcast(&cond);

        if (ret < 0) {
            TRACE("wl_display_dispatch_queue returned an error");
            check_fatal_error(m_display);
            return ret;
        }
    } else if (block) {
        while (m_queueReads > 0) {
            pthread_cond_wait(&cond, &mutex);
        }
    }

    return ret;
}
void QWaylandDisplay::flushRequests()
{
    int ret = wl_display_dispatch_queue_pending(mDisplay, mEventQueue);
    if (ret < 0) {
        qWarning("The wayland connection broke (error %d). Did the wayland compositor die?", errno);
        exit(1);
    }
    wl_display_flush(mDisplay);
}
int wayland_roundtrip(struct wl_egl_display *display)
{
    struct wl_callback *callback;
    int done = 0, ret = 0;
    wl_display_dispatch_queue_pending(display->display, display->queue);

    callback = wl_display_sync(display->display);
    wl_callback_add_listener(callback, &roundtrip_listener, &done);
    wl_proxy_set_queue((struct wl_proxy *)callback, display->queue);
    while (ret == 0 && !done)
        ret = wl_display_dispatch_queue(display->display, display->queue);

    return ret;
}
    int
WaylandNativeWindow::wayland_roundtrip(WaylandNativeWindow *display)
{
    struct wl_callback *callback;
    int done = 0, ret = 0;
    wl_display_dispatch_queue_pending(display->m_display, display->wl_queue);

    callback = wl_display_sync(display->m_display);
    wl_callback_add_listener(callback, &sync_listener, &done);
    wl_proxy_set_queue((struct wl_proxy *) callback, display->wl_queue);
    while (ret == 0 && !done)
        ret = wl_display_dispatch_queue(display->m_display, display->wl_queue);

    return ret;
}
Exemple #8
0
/** Dispatch main queue events without reading from the display fd
 *
 * \param display The display context object
 * \return The number of dispatched events or -1 on failure
 *
 * This function dispatches events on the main event queue. It does not
 * attempt to read the display fd and simply returns zero if the main
 * queue is empty, i.e., it doesn't block.
 *
 * This is necessary when a client's main loop wakes up on some fd other
 * than the display fd (network socket, timer fd, etc) and calls \ref
 * wl_display_dispatch_queue() from that callback. This may queue up
 * events in the main queue while reading all data from the display fd.
 * When the main thread returns to the main loop to block, the display fd
 * no longer has data, causing a call to \em poll(2) (or similar
 * functions) to block indefinitely, even though there are events ready
 * to dispatch.
 *
 * To proper integrate the wayland display fd into a main loop, the
 * client should always call \ref wl_display_dispatch_pending() and then
 * \ref wl_display_flush() prior to going back to sleep. At that point,
 * the fd typically doesn't have data so attempting I/O could block, but
 * events queued up on the main queue should be dispatched.
 *
 * A real-world example is a main loop that wakes up on a timerfd (or a
 * sound card fd becoming writable, for example in a video player), which
 * then triggers GL rendering and eventually eglSwapBuffers().
 * eglSwapBuffers() may call wl_display_dispatch_queue() if it didn't
 * receive the frame event for the previous frame, and as such queue
 * events in the main queue.
 *
 * \note Calling this makes the current thread the main one.
 *
 * \sa wl_display_dispatch(), wl_display_dispatch_queue(),
 * wl_display_flush()
 *
 * \memberof wl_display
 */
WL_EXPORT int
wl_display_dispatch_pending(struct wl_display *display)
{
	return wl_display_dispatch_queue_pending(display, &display->queue);
}
Exemple #9
0
	int DispatchQueuePending(struct wl_event_queue *queue){
		return wl_display_dispatch_queue_pending(cobj, queue);
	}