diff options
Diffstat (limited to 'src/wfdevent.c')
-rw-r--r-- | src/wfdevent.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/wfdevent.c b/src/wfdevent.c index e0abf27..042a38b 100644 --- a/src/wfdevent.c +++ b/src/wfdevent.c @@ -40,6 +40,11 @@ #include <glib.h> +#define EGL_EGLEXT_PROTOTYPES +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <pthread.h> + struct wfd_event { int epoll_fd; @@ -57,12 +62,25 @@ struct wfd_event { int source_bind_event_queue_fd; GQueue *bind_event_queue; + + EGLDisplay egl_display; + EGLSyncKHR egl_sync; + pthread_t thread; + int thread_destroy_fd; }; void wfd_event_destroy(struct wfd_device *device, struct wfd_event *event) { + if (event->thread_destroy_fd >= 0) { + int64_t value = 1; + write(event->thread_destroy_fd, &value, sizeof value); + pthread_join(event->thread, NULL); + close(event->thread_destroy_fd); + event->thread_destroy_fd = -1; + } + g_queue_free(event->bind_event_queue); close(event->drm_fd); udev_monitor_unref(event->udev_monitor); @@ -164,6 +182,7 @@ wfd_create_event(struct wfd_device *device, event->bind_event_queue = g_queue_new(); event->device = device; + event->thread_destroy_fd = -1; return event; } @@ -300,3 +319,53 @@ wfd_event_get_fd(struct wfd_device *device, { return event->epoll_fd; } + +static void * +signalling_thread(void *_event) +{ + struct wfd_event *event = _event; + struct epoll_event ep[16]; + int i, num; + + while (1) { + num = epoll_wait(event->epoll_fd, ep, 16, -1); + if (num < 0) + continue; + for (i = 0; i < num; ++i) { + if (ep[i].data.fd == event->thread_destroy_fd) + return NULL; + else + eglSignalSyncKHR(event->egl_display, + event->egl_sync, + EGL_SIGNALED_KHR); + } + } + + return NULL; +} + +int +wfd_event_async(struct wfd_device *device, + struct wfd_event *event, + WFDEGLDisplay *egl_display, + WFDEGLSync *egl_sync) +{ + struct epoll_event ep; + + if (event->egl_sync != NULL) + return -1; + + event->egl_display = (EGLDisplay) egl_display; + event->egl_sync = (EGLSyncKHR) egl_sync; + + event->thread_destroy_fd = eventfd(0, EFD_NONBLOCK | EFD_SEMAPHORE); + + memset(&ep, 0, sizeof ep); + ep.events = EPOLLIN; + ep.data.fd = event->thread_destroy_fd; + epoll_ctl(event->epoll_fd, EPOLL_CTL_ADD, ep.data.fd, &ep); + + pthread_create(&event->thread, NULL, signalling_thread, event); + + return 0; +} |