diff options
author | Benjamin Franzke <benjaminfranzke@googlemail.com> | 2011-05-02 11:56:04 +0200 |
---|---|---|
committer | Benjamin Franzke <benjaminfranzke@googlemail.com> | 2011-05-02 13:19:29 +0200 |
commit | 9baee66c3c730187a8788b53f655420a3d8810ae (patch) | |
tree | 73cd0e7a140919d55e813e1865276859bdec6927 | |
parent | 624f7c5cb718f5e82e3dbc256f6f96f56f01b684 (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.c | 129 |
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; |