From ba7efea5e40ba59e966b29f40385db0951bc4da1 Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Tue, 25 Oct 2016 11:26:48 +0900 Subject: [PATCH 01/16] tpl_wayland_egl: clean up code __tpl_wayland_egl_surface_init() This patch cleans up code __tpl_wayland_egl_surface_init(). The original TPL_ASSERT()s are called after using those pointer already. And the 'surface->backend.data' re-initialization code is missed. Change-Id: I34b4d2ac65d57f555b097da77302febffe177a97 Signed-off-by: YoungJun Cho --- src/tpl_wayland_egl.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index d796dd1..8e92f0b 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -466,17 +466,19 @@ __tpl_wayland_egl_surface_create_vblank(tpl_wayland_egl_surface_t static tpl_result_t __tpl_wayland_egl_surface_init(tpl_surface_t *surface) { - tpl_wayland_egl_display_t *wayland_egl_display = - (tpl_wayland_egl_display_t *) surface->display->backend.data; - tpl_wayland_egl_surface_t *wayland_egl_surface = NULL; - - struct wl_egl_window *wl_egl_window = (struct wl_egl_window *) - surface->native_handle; + tpl_wayland_egl_display_t *wayland_egl_display; + tpl_wayland_egl_surface_t *wayland_egl_surface; + struct wl_egl_window *wl_egl_window; TPL_ASSERT(surface); + TPL_ASSERT(surface->display); TPL_ASSERT(surface->type == TPL_SURFACE_TYPE_WINDOW); TPL_ASSERT(surface->native_handle); + wayland_egl_display = + (tpl_wayland_egl_display_t *)surface->display->backend.data; + wl_egl_window = (struct wl_egl_window *)surface->native_handle; + wayland_egl_surface = (tpl_wayland_egl_surface_t *) calloc(1, sizeof(tpl_wayland_egl_surface_t)); if (!wayland_egl_surface) { @@ -517,7 +519,7 @@ __tpl_wayland_egl_surface_init(tpl_surface_t *surface) wl_egl_window->height, TBM_FORMAT_ARGB8888); } else - /*Why wl_surafce is NULL ?*/ + /*Why wl_surface is NULL ?*/ wayland_egl_surface->tbm_queue = tbm_surface_queue_sequence_create( CLIENT_QUEUE_SIZE, wl_egl_window->width, @@ -528,6 +530,7 @@ __tpl_wayland_egl_surface_init(tpl_surface_t *surface) if (!wayland_egl_surface->tbm_queue) { TPL_ERR("TBM surface queue creation failed!"); free(wayland_egl_surface); + surface->backend.data = NULL; return TPL_ERROR_INVALID_OPERATION; } @@ -536,7 +539,6 @@ __tpl_wayland_egl_surface_init(tpl_surface_t *surface) __cb_tbm_surface_queue_reset_callback, (void *)surface); - surface->width = wl_egl_window->width; surface->height = wl_egl_window->height; @@ -546,13 +548,12 @@ __tpl_wayland_egl_surface_init(tpl_surface_t *surface) /* tdm_vblank object decide to be maintained every tpl_wayland_egl_surface for the case where the several surfaces is created in one display connection. */ if (wayland_egl_display->tdm_client) { - tpl_result_t tpl_ret = TPL_ERROR_NONE; - tpl_ret = - __tpl_wayland_egl_surface_create_vblank(wayland_egl_surface, - wayland_egl_display->tdm_client); - if (tpl_ret != TPL_ERROR_NONE) { + if (TPL_ERROR_NONE != __tpl_wayland_egl_surface_create_vblank( + wayland_egl_surface, + wayland_egl_display->tdm_client)) { tbm_surface_queue_destroy(wayland_egl_surface->tbm_queue); free(wayland_egl_surface); + surface->backend.data = NULL; return TPL_ERROR_INVALID_OPERATION; } } -- 2.7.4 From 6ab323a3e80bfa5135b1933f4359ddc4e7e0e567 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Fri, 4 Nov 2016 11:38:30 +0900 Subject: [PATCH 02/16] tpl_wayland_egl: Invert y to rect of the damaged region. - Wayland Window System Coordinate uses top-left position as (0,0) ,but GL Window Surface Coordinate uses bottom-left position as (0,0). So, tpl_wayland_egl should covert "GL Window Surface Coordinate" to "Wayland Window System Coordinate" before calling of wl_surface_damage(). Wayland Window System Coordinate (0,0) (Width,0) +---------+ | | | | | | | | | | +---------+ (0,Height) (Width, Height) GL Window Surface Coordinate (0,Height) (Width,Height) +---------+ | | | | | | | | | | +---------+ (0,0) (Width, 0) * reference: https://www.khronos.org/registry/egl/extensions/EXT/EGL_EXT_buffer_age.txt https://www.khronos.org/registry/egl/extensions/KHR/EGL_KHR_partial_update.txt Change-Id: I2cc0eadda428028ac2a53983e9a18c13378ee777 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 8e92f0b..e118a55 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -724,9 +724,16 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, wl_egl_window->width, wl_egl_window->height); } else { int i; + for (i = 0; i < num_rects; i++) { + /* The rectangles are specified relative to the bottom-left of the + * GL surface. So, these rectanglesd has to be converted to + * WINDOW(Top-left) coord like below. + * y = [WINDOW.HEIGHT] - (RECT.Y + RECT.HEIGHT) */ + int inverted_y = + wl_egl_window->height - (rects[i * 4 + 1] + rects[i * 4 + 3]); wl_surface_damage(wl_egl_window->surface, - rects[i * 4 + 0], rects[i * 4 + 1], + rects[i * 4 + 0], inverted_y, rects[i * 4 + 2], rects[i * 4 + 3]); } } -- 2.7.4 From 107ba47ff96685bc248697a23712fdd9e16d215f Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Fri, 4 Nov 2016 11:46:40 +0900 Subject: [PATCH 03/16] tpl_wayland_egl: Add log for checking flush callback. Change-Id: Ic01ba0606c44ed5fa14715db43254ae848841123 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index e118a55..0059894 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -1349,6 +1349,9 @@ static void __cb_tizen_surface_shm_flusher_flush_callback(void *data, TPL_CHECK_ON_NULL_RETURN(wayland_egl_display->wl_tbm_event_queue); TPL_CHECK_ON_NULL_RETURN(wayland_egl_surface->tbm_queue); + TPL_LOG_B("WL_EGL", "[FLUSH_CB] tpl_wayland_egl_surface_t(%p)", + wayland_egl_surface); + /*Fist distach panding queue for TPL - dispatch buffer-release - dispatch queue flush -- 2.7.4 From 3f4a079a3e0b6cc1919be3ec658a4b4d2eadd7c1 Mon Sep 17 00:00:00 2001 From: "Mun, Gwan-gyeong" Date: Fri, 11 Nov 2016 16:33:46 +0900 Subject: [PATCH 04/16] tpl_worker_thread: Add Missing break and Checking of fd of close() Change-Id: I45ef4b82bbee90a1d20dc4d7c4d6e318ab62d0a0 --- src/tpl_worker_thread.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/tpl_worker_thread.c b/src/tpl_worker_thread.c index e50c755..64d053c 100644 --- a/src/tpl_worker_thread.c +++ b/src/tpl_worker_thread.c @@ -384,6 +384,7 @@ __tpl_worker_thread_loop(void *arg) switch (fence_result = tbm_sync_fence_wait(wait_fd, 0)) { case 0: TPL_ERR_ERRNO("sync_fence_wait return error."); + break; case 1: /* some time recieve event two times */ epoll_ctl(epoll_fd, EPOLL_CTL_DEL, wait_fd, NULL); @@ -418,9 +419,14 @@ cleanup: if (tdm_client) tdm_client_destroy(tdm_client); - close(epoll_fd); - close(tpl_worker_thread.event_fd); - tpl_worker_thread.event_fd = -1; + if (epoll_fd != -1) { + close(epoll_fd); + epoll_fd = -1; + } + if (tpl_worker_thread.event_fd != -1) { + close(tpl_worker_thread.event_fd); + tpl_worker_thread.event_fd = -1; + } return NULL; } -- 2.7.4 From 0e6a01597e41bd0a0ee5133f75909e45fb510ab1 Mon Sep 17 00:00:00 2001 From: Sangjin Lee Date: Tue, 15 Nov 2016 10:57:52 +0900 Subject: [PATCH 05/16] tpl_wayland_egl: remove wl_callback routine wayland-egl just use tdm_vblank protocol for frame control. so wl_buffer useless. Change-Id: I009a12c197a55c56ba2f1cf9ee5418c25c9c57e6 --- src/tpl_wayland_egl.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 0059894..ceb2e87 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -64,7 +64,6 @@ struct _tpl_wayland_egl_buffer { }; static const struct wl_callback_listener sync_listener; -static const struct wl_callback_listener frame_listener; static const struct wl_buffer_listener buffer_release_listener; static int tpl_wayland_egl_buffer_key; @@ -738,11 +737,6 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, } } - /* Register a meaningless surface frame callback. - Because the buffer_release callback only be triggered if this callback is registered. */ - frame_callback = wl_surface_frame(wl_egl_window->surface); - wl_callback_add_listener(frame_callback, &frame_listener, tbm_surface); - wl_surface_commit(wl_egl_window->surface); wl_display_flush(wayland_egl_display->wl_dpy); @@ -1158,23 +1152,6 @@ static const struct wl_callback_listener sync_listener = { }; static void -__cb_client_frame_callback(void *data, struct wl_callback *callback, - uint32_t time) -{ - /* We moved the buffer reclaim logic to buffer_release_callback(). - buffer_release_callback() is more suitable point to delete or reuse buffer instead of frame_callback(). - But we remain this callback because buffer_release_callback() works only when frame_callback() is activated.*/ - TPL_IGNORE(data); - TPL_IGNORE(time); - - wl_callback_destroy(callback); -} - -static const struct wl_callback_listener frame_listener = { - __cb_client_frame_callback -}; - -static void __cb_client_buffer_release_callback(void *data, struct wl_proxy *proxy) { tbm_surface_h tbm_surface = NULL; -- 2.7.4 From b56c545d8898fa6d21384026df5393f5f7a0bfde Mon Sep 17 00:00:00 2001 From: Sangjin Lee Date: Tue, 15 Nov 2016 11:01:02 +0900 Subject: [PATCH 06/16] tpl_wayland_egl: remove useless member of struct _tpl_wayland_egl_display Change-Id: Ic50d054e18e8fd0856b3fbde504d0849ae389e9d --- src/tpl_wayland_egl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index ceb2e87..eab6d4e 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -33,7 +33,6 @@ typedef struct _tpl_wayland_egl_surface tpl_wayland_egl_surface_t; typedef struct _tpl_wayland_egl_buffer tpl_wayland_egl_buffer_t; struct _tpl_wayland_egl_display { - tbm_bufmgr bufmgr; struct wayland_tbm_client *wl_tbm_client; struct wl_proxy *wl_tbm; /* wayland_tbm_client proxy */ tdm_client *tdm_client; -- 2.7.4 From 53ae41a7ed04d66486b7fd8e2f91b4a0c93a6c1d Mon Sep 17 00:00:00 2001 From: Hoyub Lee Date: Tue, 22 Nov 2016 19:41:28 +0900 Subject: [PATCH 07/16] tpl_wayland_egl: remove remaining unused surface frame callback in function Since surface frame callback has been removed, remove remaining unused surface frame callback in function. Change-Id: I1efb08ba356e2fb93f354fa18842e8bd92f97bc1 Signed-off-by: Hoyub Lee --- src/tpl_wayland_egl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index eab6d4e..d16aa84 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -694,7 +694,6 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, tpl_wayland_egl_buffer_t *wayland_egl_buffer = NULL; struct wl_egl_window *wl_egl_window = (struct wl_egl_window *)surface->native_handle; - struct wl_callback *frame_callback = NULL; tpl_wayland_egl_display_t *wayland_egl_display = (tpl_wayland_egl_display_t *) surface->display->backend.data; tpl_wayland_egl_surface_t *wayland_egl_surface = -- 2.7.4 From ad242d572673bc6eab0d6e943dcda5394ea1f5f1 Mon Sep 17 00:00:00 2001 From: Hoyub Lee Date: Tue, 22 Nov 2016 20:37:24 +0900 Subject: [PATCH 08/16] tpl_worker_thread: temporarily add 'unused' attribute to suppress warning __tpl_worker_prepare_vblank() has been defined but not used. Therefore, add 'unused' attribute to suppress warning to pass the criteria of final release. Change-Id: I12e8d495d5e7536e2ffcf85879d82b64d6581da5 Signed-off-by: Hoyub Lee --- src/tpl_worker_thread.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tpl_worker_thread.c b/src/tpl_worker_thread.c index 64d053c..f1eb580 100644 --- a/src/tpl_worker_thread.c +++ b/src/tpl_worker_thread.c @@ -237,7 +237,9 @@ __tpl_worker_prepare_event_fd(int epoll_fd) return event_fd; } -static tpl_bool_t +/* FIXME: Temporarily added 'unused' attribute to suppress warning. */ +/* Remove this attribute when you use this function. */ +static tpl_bool_t __attribute__((unused)) __tpl_worker_prepare_vblank(int epoll_fd, tdm_client **ret_client, tdm_client_vblank **ret_vblank) { tdm_error tdm_err; -- 2.7.4 From 4c39f4550a471cc98c7f485d2fa7e3976370f8a1 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Mon, 28 Nov 2016 18:49:10 +0900 Subject: [PATCH 09/16] tpl_wayland_egl: For the hide effect, client should not attach 'NULL' when surface destroy. - If client attach 'NULL' to wl_surface when the surface destroy, server cannot show hide effect of that surface. - This commit was requested by effect member. (minjjj.kim@samsung.com) Change-Id: I349bbb5885dd86bd6c95d523d9fee6851c181c03 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index d16aa84..2569a00 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -594,16 +594,6 @@ __tpl_wayland_egl_surface_fini(tpl_surface_t *surface) wl_egl_window->private = NULL; - /* Detach all pending buffers */ - if (wl_egl_window->surface && - /* if-statement to be removed once evas/gl patch is in place */ - wl_egl_window->width == wl_egl_window->attached_width && - wl_egl_window->height == wl_egl_window->attached_height) { - - wl_surface_attach(wl_egl_window->surface, NULL, 0, 0); - wl_surface_commit(wl_egl_window->surface); - } - wl_display_flush(wayland_egl_display->wl_dpy); wl_display_dispatch_queue_pending(wayland_egl_display->wl_dpy, wayland_egl_display->wl_tbm_event_queue); -- 2.7.4 From 4dfa25034e916a96ad8d7a2c44e6e58eb6fcc889 Mon Sep 17 00:00:00 2001 From: "deasung.kim" Date: Tue, 25 Oct 2016 15:46:46 +0900 Subject: [PATCH 10/16] tpl_utils: fix double callback call in __tpl_list_remove_data in __tpl_list_remove has call callback Change-Id: Id1f8b5fbf3847449f4444cffd2bf07b740fcc00c --- src/tpl_utils.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/tpl_utils.h b/src/tpl_utils.h index 386174e..c888022 100644 --- a/src/tpl_utils.h +++ b/src/tpl_utils.h @@ -567,8 +567,6 @@ __tpl_list_remove_data(tpl_list_t *list, void *data, int occurrence, TPL_ASSERT(node); if (curr->data == data) { - if (func) func(data); - __tpl_list_remove(curr, func); return; } @@ -586,8 +584,6 @@ __tpl_list_remove_data(tpl_list_t *list, void *data, int occurrence, TPL_ASSERT(node); if (curr->data == data) { - if (func) func(data); - __tpl_list_remove(curr, func); return; } @@ -604,11 +600,8 @@ __tpl_list_remove_data(tpl_list_t *list, void *data, int occurrence, TPL_ASSERT(curr); TPL_ASSERT(node); - if (curr->data == data) { - if (func) func(data); - + if (curr->data == data) __tpl_list_remove(curr, func); - } } } } -- 2.7.4 From 2e90486413b2e09143dd36eba0bdafa79fc62c79 Mon Sep 17 00:00:00 2001 From: "deasung.kim" Date: Tue, 25 Oct 2016 18:46:48 +0900 Subject: [PATCH 11/16] tpl_worker_thread: rollback change the timing of calling of epoll_ctl_add() on "next draw wait buffer". it has sig abort with vulkan wayland wsi test Change-Id: I90cf2dfbe488e797ff62da2c34d53bc04df640d0 --- src/tpl_worker_thread.c | 60 +++++++++++++++++-------------------------------- src/tpl_worker_thread.h | 1 - 2 files changed, 20 insertions(+), 41 deletions(-) diff --git a/src/tpl_worker_thread.c b/src/tpl_worker_thread.c index f1eb580..658c574 100644 --- a/src/tpl_worker_thread.c +++ b/src/tpl_worker_thread.c @@ -49,10 +49,6 @@ __tpl_worker_surface_list_insert(tpl_worker_surface_t *surface) } surface->draw_wait_buffer = NULL; - - if (pthread_mutex_init(&surface->mutex, NULL) != 0) - TPL_ERR_ERRNO("surface mutex init failed"); - __tpl_list_push_back(&tpl_worker_thread.surface_list, surface); pthread_mutex_unlock(&tpl_worker_thread.surface_mutex); @@ -69,23 +65,6 @@ __tpl_worker_surface_list_remove(tpl_worker_surface_t *surface) __tpl_list_remove_data(&tpl_worker_thread.surface_list, surface, TPL_FIRST, NULL); - if (pthread_mutex_lock(&surface->mutex) != 0) - TPL_ERR_ERRNO("surface list mutex lock failed"); - - if (surface->draw_wait_buffer) { - int wait_fd; - - wait_fd = surface->draw_wait_fd_get(surface->surface, - surface->draw_wait_buffer); - if (wait_fd != -1) - epoll_ctl(tpl_worker_thread.epoll_fd, EPOLL_CTL_DEL, wait_fd, NULL); - surface->draw_wait_buffer = NULL; - } - pthread_mutex_unlock(&surface->mutex); - - if (pthread_mutex_destroy(&surface->mutex) != 0) - TPL_ERR_ERRNO("surface mutex init failed"); - pthread_mutex_unlock(&tpl_worker_thread.surface_mutex); } @@ -155,12 +134,7 @@ __tpl_worker_new_buffer_notify(tpl_worker_surface_t *surface) { TPL_ASSERT(surface->surface); - if (pthread_mutex_lock(&surface->mutex) != 0) - TPL_ERR_ERRNO("surface list mutex lock failed"); - - __tpl_worker_prepare_draw_wait_buffer(tpl_worker_thread.epoll_fd, surface); - - pthread_mutex_unlock(&surface->mutex); + __tpl_worker_event_send(); } static tpl_bool_t @@ -184,14 +158,8 @@ __tpl_worker_cb_vblank(tdm_client_vblank *tdm_vblank, tdm_error error, tpl_worker_surface_t *surface; surface = __tpl_list_node_get_data(trail); - - if (pthread_mutex_lock(&surface->mutex) != 0) - TPL_ERR_ERRNO("surface list mutex lock failed"); - if (surface->vblank) surface->vblank(surface->surface, sequence, tv_sec, tv_usec); - - pthread_mutex_unlock(&surface->mutex); } pthread_mutex_unlock(&tpl_worker_thread.surface_mutex); @@ -331,6 +299,23 @@ __tpl_worker_thread_loop(void *arg) while(tpl_worker_thread.running) { int i; + tpl_list_node_t *trail; + + /* set buffer's sync fd and vblank list */ + if (pthread_mutex_lock(&tpl_worker_thread.surface_mutex) != 0) { + TPL_ERR_ERRNO("surface list mutex lock failed"); + goto cleanup; + } + + for (trail = __tpl_list_get_front_node(&tpl_worker_thread.surface_list); + trail != NULL; + trail = __tpl_list_node_next(trail)) { + tpl_worker_surface_t *surface = __tpl_list_node_get_data(trail); + TPL_ASSERT(surface); + + __tpl_worker_prepare_draw_wait_buffer(epoll_fd, surface); + } + pthread_mutex_unlock(&tpl_worker_thread.surface_mutex); /* wait events */ ret = epoll_wait(epoll_fd, ev_list, EPOLL_MAX_SIZE, -1); @@ -353,7 +338,7 @@ __tpl_worker_thread_loop(void *arg) tpl_worker_thread.event_fd); continue; } else { - break; + continue; } } } else if (ev_list[i].data.ptr == tdm_client) { @@ -367,9 +352,6 @@ __tpl_worker_thread_loop(void *arg) if (!(ev_list[i].events & EPOLLIN)) continue; - if (pthread_mutex_lock(&surface->mutex) != 0) - TPL_ERR_ERRNO("surface list mutex lock failed"); - if (surface->draw_wait_buffer) { int wait_fd; @@ -407,9 +389,7 @@ __tpl_worker_thread_loop(void *arg) TPL_WARN("recieve already signaled event\n"); } - if (surface->draw_wait_buffer == NULL) - __tpl_worker_prepare_draw_wait_buffer(epoll_fd, surface); - pthread_mutex_unlock(&surface->mutex); + /* prepare next buffer in loop start time */ } } } diff --git a/src/tpl_worker_thread.h b/src/tpl_worker_thread.h index 987dbb1..5afa75b 100644 --- a/src/tpl_worker_thread.h +++ b/src/tpl_worker_thread.h @@ -19,7 +19,6 @@ struct __tpl_worker_surface { unsigned int tv_usec); tbm_surface_h draw_wait_buffer; - pthread_mutex_t mutex; }; tpl_bool_t __tpl_worker_support_vblank(); -- 2.7.4 From 9fb800fc3402427caa9e369b8eb1f48bdd7480c1 Mon Sep 17 00:00:00 2001 From: "deasung.kim" Date: Tue, 25 Oct 2016 15:31:01 +0900 Subject: [PATCH 12/16] worker_thread: added epoll_wait continue condition If errno is EINTR goto epoll_wait Change-Id: If937e95a08b0abc7a27e7cb75a087e5b1d361934 --- src/tpl_worker_thread.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tpl_worker_thread.c b/src/tpl_worker_thread.c index 658c574..6d62c4b 100644 --- a/src/tpl_worker_thread.c +++ b/src/tpl_worker_thread.c @@ -318,10 +318,12 @@ __tpl_worker_thread_loop(void *arg) pthread_mutex_unlock(&tpl_worker_thread.surface_mutex); /* wait events */ +cont_epoll_wait: ret = epoll_wait(epoll_fd, ev_list, EPOLL_MAX_SIZE, -1); if (ret == -1) { - TPL_ERR_ERRNO("epoll fd: %d.", epoll_fd); - continue; + if (errno != EINTR) + TPL_ERR_ERRNO("epoll fd: %d.", epoll_fd); + goto cont_epoll_wait; } for (i = 0; i < ret; i++) { -- 2.7.4 From 6b9c9ba4f6a24d7a31a8776409c01be2aeb624fa Mon Sep 17 00:00:00 2001 From: "Mun, Gwan-gyeong" Date: Wed, 30 Nov 2016 19:52:56 +0900 Subject: [PATCH 13/16] tpl_wayland_egl: Add missing error-checking to __tpl_wayland_egl_display_buffer_flusher_init When the wl_display_get_registry() fails on __tpl_wayland_egl_display_buffer_flusher_init(), this patch makes to return and deinitialize allocated resource. Change-Id: I773089d55f7555d269e183f3c129e2171c0243eb Signed-off-by: Mun, Gwan-gyeong --- src/tpl_wayland_egl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 2569a00..d6c5cac 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -1255,7 +1255,7 @@ __tpl_wayland_egl_display_buffer_flusher_init( } registry = wl_display_get_registry(wayland_egl_display->wl_dpy); - if (!queue) { + if (!registry) { TPL_ERR("Failed to create wl_registry"); goto fini; } -- 2.7.4 From b9075f4473e8d08c83f21903c792385eca4fc5cf Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Wed, 30 Nov 2016 21:18:26 +0900 Subject: [PATCH 14/16] tpl_tbm: Delete TPL_ASSERT checking to __tpl_tbm_display_get_window_info. - Unused parameter(tpl_display) change TPL_ASSERT to TPL_IGNORE. - TPL_ASSERT(window) doesn't the necessity because there are NULL checking for window and log printing. Change-Id: Ie3412ca8a33e59436caee8c3546781f949b672e0 Signed-off-by: joonbum.ko --- src/tpl_tbm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/tpl_tbm.c b/src/tpl_tbm.c index b656306..cfdbd84 100644 --- a/src/tpl_tbm.c +++ b/src/tpl_tbm.c @@ -117,12 +117,11 @@ __tpl_tbm_display_get_window_info(tpl_display_t *display, tpl_handle_t window, int *width, int *height, tbm_format *format, int depth, int a_size) { - TPL_ASSERT(display); - TPL_ASSERT(window); + TPL_IGNORE(display); tbm_surface_queue_h surf_queue = (tbm_surface_queue_h)window; if (!surf_queue) { - TPL_ERR("Native widow(%p) is invalid.", window); + TPL_ERR("Native window(%p) is invalid.", window); return TPL_ERROR_INVALID_PARAMETER; } -- 2.7.4 From 4b09350a21ae3fa4f726f4c9a8fff9d4e1222471 Mon Sep 17 00:00:00 2001 From: "Mun, Gwan-gyeong" Date: Wed, 30 Nov 2016 21:21:04 +0900 Subject: [PATCH 15/16] tpl_worker_thread: drop checking of fence_result on __tpl_worker_thread_loop() fence_result is always 1 in the switch case statement of fence_result == 1 so we should drop checking of fence_result on __tpl_worker_thread_loop() Change-Id: Iae6db812889dcb0adaeb202d90711f7c1089d889 --- src/tpl_worker_thread.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/tpl_worker_thread.c b/src/tpl_worker_thread.c index 6d62c4b..7946e4f 100644 --- a/src/tpl_worker_thread.c +++ b/src/tpl_worker_thread.c @@ -377,9 +377,7 @@ cont_epoll_wait: if (surface->draw_done) surface->draw_done(surface->surface, surface->draw_wait_buffer, - fence_result == 1 ? - TPL_ERROR_NONE : - TPL_ERROR_INVALID_OPERATION); + TPL_ERROR_NONE); surface->draw_wait_buffer = NULL; break; case -1: -- 2.7.4 From e31a5104bf9eb31ee1ca28230d99812c84e25818 Mon Sep 17 00:00:00 2001 From: "Mun, Gwan-gyeong" Date: Wed, 9 Nov 2016 17:36:40 +0900 Subject: [PATCH 16/16] tpl: Add tpl_surface_get_rotation() / tpl_surface_set_rotation_capability() apis tpl_wayland_egl: implement getting of tpl_surface angle. implement getting of tpl_surface's capabilities wayland-egl: Add wl_egl_window_set_rotation() / wl_egl_window_get_capabilities() - tpl_surface_get_rotation() api used for getting the current rotation-angle of the given TPL surface. tpl_surface's angle can be in 0, 90, 180, 270. - wl_egl_window_set_rotation api used fo setting the current egl_window's angle. - wl_egl_window_get_capabilities api used for getting capabilities of egl_window. Change-Id: If051e890c040aff40097f88d26276b3b0b2bf4fd Signed-off-by: Mun, Gwan-gyeong --- src/tpl.h | 19 +++++++++++ src/tpl_internal.h | 2 ++ src/tpl_surface.c | 29 +++++++++++++++++ src/tpl_wayland_egl.c | 47 +++++++++++++++++++++++++++ src/wayland-egl/wayland-egl-priv.h | 5 +++ src/wayland-egl/wayland-egl.c | 65 +++++++++++++++++++++++++++++++++++++- 6 files changed, 166 insertions(+), 1 deletion(-) diff --git a/src/tpl.h b/src/tpl.h index 4d9145f..82cf601 100644 --- a/src/tpl.h +++ b/src/tpl.h @@ -426,6 +426,17 @@ tpl_result_t tpl_surface_get_size(tpl_surface_t *surface, int *width, int *height); /** + * Get the current rotation-angle of the given TPL surface. + * + * tpl_surface's angle can be in 0, 90, 180, 270. + * + * @param surface surface to get rotation-angle. + * @param rotation pointer to receive rotation-angle value. + */ +tpl_result_t +tpl_surface_get_rotation(tpl_surface_t *surface, int *rotation); + +/** * Validate current frame of the given TPL surface. * * Users should call this function before getting actual final render target @@ -730,6 +741,14 @@ tpl_surface_set_reset_cb(tpl_surface_t *surface, void* data, tpl_surface_cb_func_t reset_cb); /** + * Set rotation capability to the given tpl_surface + * @param surface surface used for set + * @param set TPL_TRUE if user want to set to enable / disable capability of rotation + */ +tpl_result_t +tpl_surface_set_rotation_capability(tpl_surface_t *surface, tpl_bool_t set); + +/** * Present mode types. * * @TPL_DISPLAY_MODE_IMMEDIATE_KHR: The presentation engine does not wait for diff --git a/src/tpl_internal.h b/src/tpl_internal.h index 2297db4..a881013 100644 --- a/src/tpl_internal.h +++ b/src/tpl_internal.h @@ -128,8 +128,10 @@ struct _tpl_surface { tpl_surface_type_t type; tbm_format format; int width, height; + int rotation; int post_interval; int dump_count; + tpl_bool_t rotation_capability; tpl_surface_backend_t backend; /*For frontbuffer extension*/ diff --git a/src/tpl_surface.c b/src/tpl_surface.c index ed8cc9f..c991868 100644 --- a/src/tpl_surface.c +++ b/src/tpl_surface.c @@ -119,6 +119,18 @@ tpl_surface_get_size(tpl_surface_t *surface, int *width, int *height) return TPL_ERROR_NONE; } +tpl_result_t +tpl_surface_get_rotation(tpl_surface_t *surface, int *rotation) +{ + if (!surface) { + TPL_ERR("Surface is NULL!"); + return TPL_ERROR_INVALID_PARAMETER; + } + + if (rotation) *rotation = surface->rotation; + + return TPL_ERROR_NONE; +} tpl_bool_t tpl_surface_validate(tpl_surface_t *surface) @@ -425,3 +437,20 @@ tpl_surface_set_reset_cb(tpl_surface_t *surface, void *data, tpl_surface_cb_func return ret; } + +tpl_result_t +tpl_surface_set_rotation_capability(tpl_surface_t *surface, tpl_bool_t set) +{ + if (!surface || (surface->type != TPL_SURFACE_TYPE_WINDOW)) { + TPL_ERR("Invalid surface!"); + return TPL_ERROR_INVALID_PARAMETER; + } + + TPL_OBJECT_LOCK(surface); + + surface->rotation_capability = set; + + TPL_OBJECT_UNLOCK(surface); + + return TPL_ERROR_NONE; +} diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index d6c5cac..2b89173 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -373,6 +373,14 @@ static void __cb_client_window_resize_callback(struct wl_egl_window *wl_egl_window, void *private); +static void +__cb_client_window_rotate_callback(struct wl_egl_window *wl_egl_window, + void *private); + +static int +__cb_client_window_get_rotation_capability(struct wl_egl_window *wl_egl_window, + void *private); + static TPL_INLINE void __tpl_wayland_egl_buffer_set_reset_flag(tpl_list_t *tracking_list) { @@ -539,9 +547,13 @@ __tpl_wayland_egl_surface_init(tpl_surface_t *surface) surface->width = wl_egl_window->width; surface->height = wl_egl_window->height; + surface->rotation = wl_egl_window->rotation; + surface->rotation_capability = TPL_FALSE; wl_egl_window->private = surface; wl_egl_window->resize_callback = (void *)__cb_client_window_resize_callback; + wl_egl_window->rotate_callback = (void *)__cb_client_window_rotate_callback; + wl_egl_window->get_rotation_capability = (void *)__cb_client_window_get_rotation_capability; /* tdm_vblank object decide to be maintained every tpl_wayland_egl_surface for the case where the several surfaces is created in one display connection. */ @@ -1212,6 +1224,41 @@ __cb_client_window_resize_callback(struct wl_egl_window *wl_egl_window, wayland_egl_surface->resized = TPL_TRUE; } +static void +__cb_client_window_rotate_callback(struct wl_egl_window *wl_egl_window, + void *private) +{ + TPL_ASSERT(private); + TPL_ASSERT(wl_egl_window); + + int rotation; + tpl_surface_t *surface = (tpl_surface_t *)private; + + rotation = wl_egl_window->rotation; + + TPL_LOG_B("WL_EGL", "[ROTATE_CB] wl_egl_window(%p) (%d) -> (%d)", + wl_egl_window, surface->rotation, rotation); + /* Check whether the surface was resized by wayland_egl */ + surface->rotation = rotation; +} + +static int +__cb_client_window_get_rotation_capability(struct wl_egl_window *wl_egl_window, + void *private) +{ + int rotation_capability = WL_EGL_WINDOW_CAPABILITY_NONE; + TPL_ASSERT(private); + TPL_ASSERT(wl_egl_window); + tpl_surface_t *surface = (tpl_surface_t *)private; + if (TPL_TRUE == surface->rotation_capability) + rotation_capability = WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED; + else + rotation_capability = WL_EGL_WINDOW_CAPABILITY_ROTATION_UNSUPPORTED; + + return rotation_capability; +} + + void __cb_resistry_global_callback(void *data, struct wl_registry *wl_registry, uint32_t name, const char *interface, diff --git a/src/wayland-egl/wayland-egl-priv.h b/src/wayland-egl/wayland-egl-priv.h index da25be9..3c284fc 100644 --- a/src/wayland-egl/wayland-egl-priv.h +++ b/src/wayland-egl/wayland-egl-priv.h @@ -13,6 +13,7 @@ extern "C" { #endif #include +#include struct wl_egl_window { struct wl_surface *surface; @@ -25,8 +26,12 @@ struct wl_egl_window { int attached_width; int attached_height; + wl_egl_window_rotation rotation; + void *private; void (*resize_callback)(struct wl_egl_window *, void *); + void (*rotate_callback)(struct wl_egl_window *, void *); + int (*get_rotation_capability)(struct wl_egl_window *, void *); }; #ifdef __cplusplus diff --git a/src/wayland-egl/wayland-egl.c b/src/wayland-egl/wayland-egl.c index f577bcc..77e8e22 100644 --- a/src/wayland-egl/wayland-egl.c +++ b/src/wayland-egl/wayland-egl.c @@ -1,7 +1,6 @@ #include #include -#include "wayland-egl.h" #include "wayland-egl-priv.h" #define WL_EGL_DEBUG 1 @@ -98,6 +97,7 @@ wl_egl_window_create(struct wl_surface *surface, wl_egl_window_resize(egl_window, width, height, 0, 0); egl_window->attached_width = 0; egl_window->attached_height = 0; + egl_window->rotation = ROTATION_0; WL_EGL_LOG(2, "surf:%10p WxH:%dx%d egl_win:%10p priv:%10p", surface, width, height, egl_window, egl_window->private); @@ -131,3 +131,66 @@ wl_egl_window_get_attached_size(struct wl_egl_window *egl_window, egl_window, width, height, egl_window->attached_width, egl_window->attached_height); } + +WL_EGL_EXPORT void +wl_egl_window_set_rotation(struct wl_egl_window *egl_window, + wl_egl_window_rotation rotation) +{ + int resize = 0; + + if (egl_window == NULL) { + WL_EGL_ERR("egl_window is NULL"); + return; + } + + if (egl_window->rotation == rotation) { + WL_EGL_ERR("rotation value is same"); + return; + } + + switch (rotation) { + case ROTATION_0: + case ROTATION_180: + if (egl_window->rotation == ROTATION_90 || egl_window->rotation == ROTATION_270) + resize = 1; + break; + case ROTATION_90: + case ROTATION_270: + if (egl_window->rotation == ROTATION_0 || egl_window->rotation == ROTATION_180) + resize = 1; + break; + default: + WL_EGL_ERR("Invalid rotation value"); + return; + } + + WL_EGL_LOG(2, "egl_win:%10p prev_rotation:%d curr_rotation: %d", + egl_window, egl_window->rotation, rotation); + + egl_window->rotation = rotation; + + if (egl_window->rotate_callback) + egl_window->rotate_callback(egl_window, egl_window->private); + + if (resize) { + wl_egl_window_resize(egl_window, egl_window->height, egl_window->width, + egl_window->dx, egl_window->dy); + } +} + +WL_EGL_EXPORT int +wl_egl_window_get_capabilities(struct wl_egl_window *egl_window) +{ + int capabilities = WL_EGL_WINDOW_CAPABILITY_NONE; + if (egl_window == NULL) { + WL_EGL_ERR("egl_window is NULL"); + return capabilities; + } + + if (egl_window->get_rotation_capability) + capabilities = egl_window->get_rotation_capability(egl_window, egl_window->private); + else + capabilities = WL_EGL_WINDOW_CAPABILITY_ROTATION_UNKNOWN; + + return capabilities; +} -- 2.7.4