Exemplo n.º 1
0
void
_cogl_poll_renderer_add_fd (CoglRenderer *renderer,
                            int fd,
                            CoglPollFDEvent events,
                            CoglPollPrepareCallback prepare,
                            CoglPollDispatchCallback dispatch,
                            void *user_data)
{
  CoglPollFD pollfd = {
    fd,
    events
  };
  CoglPollSource *source;

  _cogl_poll_renderer_remove_fd (renderer, fd);

  source = g_slice_new0 (CoglPollSource);
  source->fd = fd;
  source->prepare = prepare;
  source->dispatch = dispatch;
  source->user_data = user_data;

  renderer->poll_sources = g_list_prepend (renderer->poll_sources, source);

  g_array_append_val (renderer->poll_fds, pollfd);
  renderer->poll_fds_age++;
}
Exemplo n.º 2
0
static void
dispatch_wayland_display_events (void *user_data, int revents)
{
  CoglRenderer *renderer = user_data;
  CoglRendererEGL *egl_renderer = renderer->winsys;
  CoglRendererWayland *wayland_renderer = egl_renderer->platform;

  if ((revents & COGL_POLL_FD_EVENT_IN))
    {
      if (wl_display_dispatch (wayland_renderer->wayland_display) == -1 &&
          errno != EAGAIN &&
          errno != EINTR)
        goto socket_error;
    }

  if ((revents & COGL_POLL_FD_EVENT_OUT))
    {
      int ret = wl_display_flush (wayland_renderer->wayland_display);

      if (ret == -1)
        {
          if (errno != EAGAIN && errno != EINTR)
            goto socket_error;
        }
      else
        {
          /* There is no more data to write so we don't need to wake
           * up when the write buffer is emptied anymore */
          _cogl_poll_renderer_modify_fd (renderer,
                                         wayland_renderer->fd,
                                         COGL_POLL_FD_EVENT_IN);
        }
    }

  return;

 socket_error:
  /* If there was an error on the wayland socket then it's likely that
   * it's going to consistently fail so we'll stop waiting on the file
   * descriptor instead of making the application take up 100% CPU.
   * FIXME: it would be nice if there was some way to report this to
   * the application so that it can quit or recover */
  _cogl_poll_renderer_remove_fd (renderer, wayland_renderer->fd);
}
Exemplo n.º 3
0
static int64_t
prepare_wayland_display_events (void *user_data)
{
  CoglRenderer *renderer = user_data;
  CoglRendererEGL *egl_renderer = renderer->winsys;
  CoglRendererWayland *wayland_renderer = egl_renderer->platform;
  int flush_ret;

  flush_ret = wl_display_flush (wayland_renderer->wayland_display);

  if (flush_ret == -1)
    {
      /* If the socket buffer became full then we need to wake up the
       * main loop once it is writable again */
      if (errno == EAGAIN)
        {
          _cogl_poll_renderer_modify_fd (renderer,
                                         wayland_renderer->fd,
                                         COGL_POLL_FD_EVENT_IN |
                                         COGL_POLL_FD_EVENT_OUT);
        }
      else if (errno != EINTR)
        {
          /* If the flush failed for some other reason then it's
           * likely that it's going to consistently fail so we'll stop
           * waiting on the file descriptor instead of making the
           * application take up 100% CPU. FIXME: it would be nice if
           * there was some way to report this to the application so
           * that it can quit or recover */
          _cogl_poll_renderer_remove_fd (renderer, wayland_renderer->fd);
        }
    }

  /* Calling this here is a bit dodgy because Cogl usually tries to
   * say that it won't do any event processing until
   * cogl_poll_renderer_dispatch is called. However Wayland doesn't
   * seem to provide any way to query whether the event queue is empty
   * and we would need to do that in order to force the main loop to
   * wake up to call it from dispatch. */
  wl_display_dispatch_pending (wayland_renderer->wayland_display);

  return -1;
}
Exemplo n.º 4
0
static void
_cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
{
  CoglRendererEGL *egl_renderer = renderer->winsys;
  CoglRendererWayland *wayland_renderer = egl_renderer->platform;

  if (egl_renderer->edpy)
    eglTerminate (egl_renderer->edpy);

  if (wayland_renderer->wayland_display)
    {
      _cogl_poll_renderer_remove_fd (renderer, wayland_renderer->fd);

      if (renderer->foreign_wayland_display == NULL)
        wl_display_disconnect (wayland_renderer->wayland_display);
    }

  g_slice_free (CoglRendererWayland, egl_renderer->platform);
  g_slice_free (CoglRendererEGL, egl_renderer);
}