summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Franzke <benjaminfranzke@googlemail.com>2011-05-02 11:56:04 +0200
committerBenjamin Franzke <benjaminfranzke@googlemail.com>2011-05-02 13:19:29 +0200
commit9baee66c3c730187a8788b53f655420a3d8810ae (patch)
tree73cd0e7a140919d55e813e1865276859bdec6927
parent624f7c5cb718f5e82e3dbc256f6f96f56f01b684 (diff)
compositor-openwfd: Make use of wfdDeviceEventAsynceglsync
Additionally added a EGL_MESA_reusable_sync_eventfd, so we do not need an own Thread for polling using eglClientWaitSyncKHR. This drops the use of the temporarily added wfdDeviceEventGetFD.
-rw-r--r--compositor/compositor-openwfd.c129
1 files changed, 90 insertions, 39 deletions
diff --git a/compositor/compositor-openwfd.c b/compositor/compositor-openwfd.c
index a0957dd..2d4fd4f 100644
--- a/compositor/compositor-openwfd.c
+++ b/compositor/compositor-openwfd.c
@@ -42,8 +42,17 @@ struct wfd_compositor {
uint32_t start_time;
uint32_t used_pipelines;
+ EGLSyncKHR esync;
+ int sync_fd;
+
PFNEGLCREATEDRMIMAGEMESA create_drm_image;
PFNEGLEXPORTDRMIMAGEMESA export_drm_image;
+
+ PFNEGLCREATESYNCKHRPROC create_sync;
+ PFNEGLDESTROYSYNCKHRPROC destroy_sync;
+ PFNEGLSIGNALSYNCKHRPROC signal_sync;
+
+ PFNEGLCREATESYNCEVENTFDMESAPROC create_sync_eventfd;
};
struct wfd_output {
@@ -460,35 +469,40 @@ on_wfd_event(int fd, uint32_t mask, void *data)
WFDint pipeline_id;
WFDint bind_time;
- type = wfdDeviceEventWait(c->dev, c->event, timeout);
-
- switch (type) {
- case WFD_EVENT_PIPELINE_BIND_SOURCE_COMPLETE:
- pipeline_id =
- wfdGetEventAttribi(c->dev, c->event,
- WFD_EVENT_PIPELINE_BIND_PIPELINE_ID);
-
- bind_time =
- wfdGetEventAttribi(c->dev, c->event,
- WFD_EVENT_PIPELINE_BIND_TIME_EXT);
-
- wl_list_for_each(output_iter, &c->base.output_list, base.link) {
- if (output_iter->pipeline_id == pipeline_id)
- output = output_iter;
+ do {
+ type = wfdDeviceEventWait(c->dev, c->event, timeout);
+
+ switch (type) {
+ case WFD_EVENT_PIPELINE_BIND_SOURCE_COMPLETE:
+ pipeline_id = wfdGetEventAttribi(c->dev, c->event,
+ WFD_EVENT_PIPELINE_BIND_PIPELINE_ID);
+
+ bind_time = wfdGetEventAttribi(c->dev, c->event,
+ WFD_EVENT_PIPELINE_BIND_TIME_EXT);
+
+ output = NULL;
+ wl_list_for_each(output_iter, &c->base.output_list,
+ base.link) {
+ if (output_iter->pipeline_id == pipeline_id) {
+ output = output_iter;
+ break;
+ }
+ }
+ if (output == NULL)
+ break;
+
+ wlsc_output_finish_frame(&output->base,
+ c->start_time + bind_time);
+ break;
+ case WFD_EVENT_PORT_ATTACH_DETACH:
+ handle_port_state_change(c);
+ break;
+ default:
+ break;
}
+ } while (type != WFD_EVENT_NONE);
- if (output == NULL)
- return 1;
-
- wlsc_output_finish_frame(&output->base,
- c->start_time + bind_time);
- break;
- case WFD_EVENT_PORT_ATTACH_DETACH:
- handle_port_state_change(c);
- break;
- default:
- return 1;
- }
+ c->signal_sync(c->base.display, c->esync, EGL_UNSIGNALED_KHR);
return 1;
}
@@ -507,11 +521,54 @@ wfd_destroy(struct wlsc_compositor *ec)
free(d);
}
+static int
+wfd_events_init(struct wfd_compositor *ec)
+{
+ struct wl_event_loop *loop;
+
+ if (strstr(eglQueryString(ec->base.display, EGL_EXTENSIONS),
+ "EGL_KHR_reusable_sync") == NULL)
+ return -1;
+ if (strstr(eglQueryString(ec->base.display, EGL_EXTENSIONS),
+ "EGL_MESA_reusable_sync_eventfd") == NULL)
+ return -1;
+
+ ec->create_sync = (void *) eglGetProcAddress("eglCreateSyncKHR");
+ ec->destroy_sync = (void *) eglGetProcAddress("eglDestroySyncKHR");
+ ec->signal_sync = (void *) eglGetProcAddress("eglSignalSyncKHR");
+ ec->create_sync_eventfd =
+ (void *) eglGetProcAddress("eglCreateSyncEventfdMESA");
+
+ ec->event = wfdCreateEvent(ec->dev, NULL);
+ if (ec->event == WFD_INVALID_HANDLE) {
+ fprintf(stderr, "failed to create wfd event\n");
+ return -1;
+ }
+
+ ec->esync =
+ ec->create_sync(ec->base.display, EGL_SYNC_REUSABLE_KHR, NULL);
+ if (ec->esync == EGL_NO_SYNC_KHR)
+ return -1;
+
+ ec->sync_fd = ec->create_sync_eventfd(ec->base.display, ec->esync);
+ if (ec->sync_fd < 0)
+ return -1;
+
+ wfdDeviceEventAsync(ec->dev, ec->event,
+ ec->base.display, ec->esync);
+
+ loop = wl_display_get_event_loop(ec->base.wl_display);
+ ec->wfd_source =
+ wl_event_loop_add_fd(loop, ec->sync_fd, WL_EVENT_READABLE,
+ on_wfd_event, ec);
+
+ return 0;
+}
+
struct wlsc_compositor *
wfd_compositor_create(struct wl_display *display, int connector)
{
struct wfd_compositor *ec;
- struct wl_event_loop *loop;
struct timeval tv;
ec = malloc(sizeof *ec);
@@ -535,12 +592,6 @@ wfd_compositor_create(struct wl_display *display, int connector)
return NULL;
}
- ec->event = wfdCreateEvent(ec->dev, NULL);
- if (ec->event == WFD_INVALID_HANDLE) {
- fprintf(stderr, "failed to create wfd event\n");
- return NULL;
- }
-
ec->base.wl_display = display;
if (init_egl(ec) < 0) {
fprintf(stderr, "failed to initialize egl\n");
@@ -569,11 +620,11 @@ wfd_compositor_create(struct wl_display *display, int connector)
evdev_input_add_devices(&ec->base, ec->udev);
- loop = wl_display_get_event_loop(ec->base.wl_display);
- ec->wfd_source =
- wl_event_loop_add_fd(loop,
- wfdDeviceEventGetFD(ec->dev, ec->event),
- WL_EVENT_READABLE, on_wfd_event, ec);
+ if (wfd_events_init(ec) < 0) {
+ fprintf(stderr, "failed to initialize OpenWF Display Events\n");
+ return NULL;
+ }
+
ec->tty = tty_create(&ec->base);
return &ec->base;