From 115ebb65c80ebce7ea47f5d2363e47c4907300ba Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Thu, 16 Mar 2017 09:13:32 +0900 Subject: [PATCH 01/16] tpl_wayland_egl: Added geometry information of the client window to tpl_wayland_egl_buffer_t. - Store the native window information when the wayland client do dequeue buffer in tpl_wayland_egl_buffer_t. - By using the information remaining in the tpl_wayland_egl_buffer_t which rendering job end, do commit to server. - This change will be able to inform accurate information of client window to server. Change-Id: I4a7c4646cfc8ab3f39c8755f7c1193b33992a1ed Signed-off-by: joonbum.ko --- src/tpl_wayland_egl.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index f24bdc4..4f9cb12 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -57,6 +57,9 @@ struct _tpl_wayland_egl_surface { struct _tpl_wayland_egl_buffer { tpl_wayland_egl_display_t *display; tpl_wayland_egl_surface_t *wayland_egl_surface; + int dx, dy; + int width, height; + int rotation; tbm_bo bo; tpl_bool_t reset; /* TRUE if queue reseted by external */ struct wl_proxy *wl_proxy; /* wl_buffer proxy */ @@ -723,15 +726,15 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, TPL_IMAGE_DUMP(tbm_surface, surface->width, surface->height); wl_surface_attach(wl_egl_window->surface, (void *)wayland_egl_buffer->wl_proxy, - wl_egl_window->dx, wl_egl_window->dy); + wayland_egl_buffer->dx, wayland_egl_buffer->dy); - wl_egl_window->attached_width = wl_egl_window->width; - wl_egl_window->attached_height = wl_egl_window->height; + wl_egl_window->attached_width = wayland_egl_buffer->width; + wl_egl_window->attached_height = wayland_egl_buffer->height; if (num_rects < 1 || rects == NULL) { wl_surface_damage(wl_egl_window->surface, - wl_egl_window->dx, wl_egl_window->dy, - wl_egl_window->width, wl_egl_window->height); + wayland_egl_buffer->dx, wayland_egl_buffer->dy, + wayland_egl_buffer->width, wayland_egl_buffer->height); } else { int i; @@ -741,7 +744,7 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, * 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]); + wayland_egl_buffer->height - (rects[i * 4 + 1] + rects[i * 4 + 3]); wl_surface_damage(wl_egl_window->surface, rects[i * 4 + 0], inverted_y, rects[i * 4 + 2], rects[i * 4 + 3]); @@ -753,9 +756,10 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, wl_display_flush(wayland_egl_display->wl_dpy); TPL_LOG_B("WL_EGL", - "[COMMIT] wl_surface(%p) wl_egl_window(%p)(%dx%d) wl_buffer(%p)", + "[COMMIT] wl_surface(%p) wl_egl_window(%p) wl_buffer(%p)(%dx%d)", wl_egl_window->surface, wl_egl_window, - wl_egl_window->width, wl_egl_window->height, wayland_egl_buffer->wl_proxy); + wayland_egl_buffer->wl_proxy, + wayland_egl_buffer->width, wayland_egl_buffer->height); if (wayland_egl_surface->attached_buffers) { TPL_OBJECT_LOCK(&wayland_egl_surface->base); @@ -999,6 +1003,8 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou tpl_wayland_egl_display_t *wayland_egl_display = (tpl_wayland_egl_display_t *)surface->display->backend.data; struct wl_proxy *wl_proxy = NULL; + struct wl_egl_window *wl_egl_window = + (struct wl_egl_window *)surface->native_handle; tbm_surface_queue_error_e tsq_err = 0; if (sync_fence) @@ -1006,8 +1012,6 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou /* Check whether the surface was resized by wayland_egl */ if (wayland_egl_surface->resized == TPL_TRUE) { - struct wl_egl_window *wl_egl_window = - (struct wl_egl_window *)surface->native_handle; int width, height, format; width = wl_egl_window->width; height = wl_egl_window->height; @@ -1047,6 +1051,12 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou wayland_egl_buffer->wl_proxy, tbm_surface, tbm_bo_export(wayland_egl_buffer->bo)); + wayland_egl_buffer->dx = wl_egl_window->dx; + wayland_egl_buffer->dy = wl_egl_window->dy; + wayland_egl_buffer->width = wl_egl_window->width; + wayland_egl_buffer->height = wl_egl_window->height; + wayland_egl_buffer->rotation = wl_egl_window->rotation; + wayland_egl_buffer->reset = TPL_FALSE; wayland_egl_surface->reset = TPL_FALSE; @@ -1084,6 +1094,11 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou wl_display_flush(wayland_egl_display->wl_dpy); + wayland_egl_buffer->dx = wl_egl_window->dx; + wayland_egl_buffer->dy = wl_egl_window->dy; + wayland_egl_buffer->width = wl_egl_window->width; + wayland_egl_buffer->height = wl_egl_window->height; + wayland_egl_buffer->rotation = wl_egl_window->rotation; wayland_egl_buffer->display = wayland_egl_display; wayland_egl_buffer->wl_proxy = wl_proxy; wayland_egl_buffer->bo = tbm_surface_internal_get_bo(tbm_surface, 0); -- 2.7.4 From a7d8b298449ddef34062cdb933115b8eaec02bf4 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Thu, 2 Mar 2017 15:29:14 +0900 Subject: [PATCH 02/16] wayland-egl: Prerotation need not to do window resize. Change-Id: I1b12350e01862317358f7ac29a1274cab6812ae8 Signed-off-by: joonbum.ko --- src/wayland-egl/wayland-egl.c | 83 ++++++------------------------------------- 1 file changed, 11 insertions(+), 72 deletions(-) diff --git a/src/wayland-egl/wayland-egl.c b/src/wayland-egl/wayland-egl.c index 8ed649f..46d47a0 100644 --- a/src/wayland-egl/wayland-egl.c +++ b/src/wayland-egl/wayland-egl.c @@ -15,17 +15,14 @@ unsigned int wl_egl_log_level; /* WL-EGL Log Level - 0:unintialized, 1:initialized(no logging), 2:min log, 3:more log */ -#define WL_EGL_LOG(lvl, f, x...) \ - { \ - if(wl_egl_log_level == 1) \ - {} \ - else if(wl_egl_log_level > 1) \ - { \ +#define WL_EGL_LOG(lvl, f, x...) { \ + if(wl_egl_log_level == 1) { \ + } \ + else if(wl_egl_log_level > 1) { \ if(wl_egl_log_level <= lvl) \ WL_EGL_LOG_PRINT(f, ##x) \ } \ - else \ - { \ + else { \ char *env = getenv("WL_EGL_LOG_LEVEL"); \ if(env == NULL) \ wl_egl_log_level = 1; \ @@ -37,14 +34,12 @@ unsigned int wl_egl_log_level; } \ } -#define WL_EGL_LOG_PRINT(fmt, args...) \ - { \ +#define WL_EGL_LOG_PRINT(fmt, args...) { \ printf("[\x1b[32mWL-EGL\x1b[0m %d:%d|\x1b[32m%s\x1b[0m|%d] " fmt "\n", \ getpid(), (int)syscall(SYS_gettid), __func__,__LINE__, ##args); \ } -#define WL_EGL_ERR(f, x...) \ - { \ +#define WL_EGL_ERR(f, x...) { \ printf("[\x1b[31mWL-EGL_ERR\x1b[0m %d:%d|\x1b[31m%s\x1b[0m|%d] " f "\n",\ getpid(), (int)syscall(SYS_gettid), __func__, __LINE__, ##x); \ } @@ -58,7 +53,6 @@ wl_egl_window_resize(struct wl_egl_window *egl_window, int width, int height, int dx, int dy) { - int prev_width, prev_height; wl_egl_window_rotation rotation; if (egl_window == NULL) { @@ -69,35 +63,10 @@ wl_egl_window_resize(struct wl_egl_window *egl_window, egl_window->dx = dx; egl_window->dy = dy; - rotation = egl_window->rotation; - switch (rotation) { - case ROTATION_0: - case ROTATION_180: - default: - prev_width = egl_window->width; - prev_height = egl_window->height; - break; - case ROTATION_90: - case ROTATION_270: - prev_width = egl_window->height; - prev_height = egl_window->width; - break; - } - if ((prev_width == width) && (prev_height == height)) return; - - switch (rotation) { - case ROTATION_0: - case ROTATION_180: - default: - egl_window->width = width; - egl_window->height = height; - break; - case ROTATION_90: - case ROTATION_270: - egl_window->width = height; - egl_window->height = width; - break; - } + if ((egl_window->width == width) && (egl_window->height == height)) return; + + egl_window->width = width; + egl_window->height = height; if (egl_window->resize_callback) egl_window->resize_callback(egl_window, egl_window->private); @@ -175,9 +144,6 @@ WL_EGL_EXPORT void wl_egl_window_set_rotation(struct wl_egl_window *egl_window, wl_egl_window_rotation rotation) { - int resize = 0; - wl_egl_window_rotation prev_rotation; - if (egl_window == NULL) { WL_EGL_ERR("egl_window is NULL"); return; @@ -188,37 +154,10 @@ wl_egl_window_set_rotation(struct wl_egl_window *egl_window, return; } - prev_rotation = egl_window->rotation; - switch (rotation) { - case ROTATION_0: - case ROTATION_180: - if (prev_rotation == ROTATION_90 || prev_rotation == ROTATION_270) - resize = 1; - break; - case ROTATION_90: - case ROTATION_270: - if (prev_rotation == ROTATION_0 || prev_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 == 1) && (egl_window->resize_callback != NULL)) { - int temp = egl_window->width; - egl_window->width = egl_window->height; - egl_window->height = temp; - egl_window->resize_callback(egl_window, egl_window->private); - } } WL_EGL_EXPORT int -- 2.7.4 From 27275e57af0bf648079b9ec3c0a8d73e0dc83ace Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Mon, 10 Apr 2017 13:21:52 +0900 Subject: [PATCH 03/16] wayland-egl: Changed an ERR_LOG to normal log when wl_egl_window already has been rotated. Change-Id: I10f8fe00be29cdfb24c0c3a6962091d87dbca4c6 Signed-off-by: joonbum.ko --- src/wayland-egl/wayland-egl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wayland-egl/wayland-egl.c b/src/wayland-egl/wayland-egl.c index 46d47a0..475bf7c 100644 --- a/src/wayland-egl/wayland-egl.c +++ b/src/wayland-egl/wayland-egl.c @@ -150,7 +150,7 @@ wl_egl_window_set_rotation(struct wl_egl_window *egl_window, } if (egl_window->rotation == rotation) { - WL_EGL_ERR("rotation value is same"); + WL_EGL_LOG(2, "rotation(%d) egl_window->rotation(%d) already rotated"); return; } -- 2.7.4 From 632bc065beec9e09625f5b8d1e3f987efad5475c Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Mon, 15 May 2017 18:58:44 +0900 Subject: [PATCH 04/16] tpl_surface, tpl_wayland_egl: Refactored the procedue related with frontbuffer mode. - There was a problem with HWC in the existing procedure related with frontbuffer_mode. The existing procedure was difficult to use eglFrontBufferSetSEC because the client did not know exactly when to use the frontbuffer. - Solved this problem through wayland_tbm_client API. - platform/core/uifw/wayland-tbm commit_id : 0de11f336d666d7b8cc171deeb404ec3b287cde8 commit_message : client: added wayland_tbm_client_queue_check_activate - See comments of the codes related with frontbuffer_mode for details. Change-Id: I5d024284d65ae65277fe67a4cd000a78f592665f Signed-off-by: joonbum.ko --- src/tpl_surface.c | 25 ++-------------- src/tpl_wayland_egl.c | 80 +++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 75 insertions(+), 30 deletions(-) diff --git a/src/tpl_surface.c b/src/tpl_surface.c index c991868..a595ef4 100644 --- a/src/tpl_surface.c +++ b/src/tpl_surface.c @@ -214,16 +214,7 @@ tpl_surface_dequeue_buffer_with_sync(tpl_surface_t *surface, TRACE_BEGIN("TPL:DEQUEUE_BUFFER"); TPL_OBJECT_LOCK(surface); - if (surface->is_frontbuffer_mode && surface->frontbuffer) { - if (TPL_TRUE == surface->backend.validate(surface)) { - tbm_surface = surface->frontbuffer; - } else { - surface->frontbuffer = NULL; - } - } - - if (!tbm_surface) - tbm_surface = surface->backend.dequeue_buffer(surface, timeout_ns, sync_fence); + tbm_surface = surface->backend.dequeue_buffer(surface, timeout_ns, sync_fence); if (tbm_surface) { /* Update size of the surface. */ @@ -277,15 +268,6 @@ tpl_surface_enqueue_buffer_with_damage_and_sync(tpl_surface_t *surface, TRACE_BEGIN("TPL:ENQUEUE_BUFFER_WITH_DAMAGE"); TPL_OBJECT_LOCK(surface); - if (surface->is_frontbuffer_mode) { - if (surface->frontbuffer == tbm_surface) { - TPL_OBJECT_UNLOCK(surface); - TRACE_END(); - return ret; - } - surface->frontbuffer = tbm_surface; - } - TPL_LOG_F("tpl_surface_t(%p) tbm_surface(%p) (%dx%d)", surface, tbm_surface, tbm_surface_get_width(tbm_surface), tbm_surface_get_height(tbm_surface)); @@ -341,7 +323,7 @@ tpl_surface_create_swapchain(tpl_surface_t *surface, tbm_format format, return TPL_ERROR_INVALID_PARAMETER; } - if ((width <= 0) || (height <= 0) ) { + if ((width <= 0) || (height <= 0)) { TPL_ERR("Invalid width or height!"); return TPL_ERROR_INVALID_PARAMETER; } @@ -422,8 +404,7 @@ tpl_surface_set_reset_cb(tpl_surface_t *surface, void *data, tpl_surface_cb_func { tpl_result_t ret = TPL_ERROR_NONE; - if (!surface) - { + if (!surface) { TPL_ERR("Invalid surface!"); return TPL_ERROR_INVALID_PARAMETER; } diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 4f9cb12..fe8c4d8 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -62,6 +62,7 @@ struct _tpl_wayland_egl_buffer { int rotation; tbm_bo bo; tpl_bool_t reset; /* TRUE if queue reseted by external */ + tpl_bool_t is_new; /* for frontbuffer mode */ struct wl_proxy *wl_proxy; /* wl_buffer proxy */ }; @@ -817,6 +818,33 @@ __tpl_wayland_egl_surface_enqueue_buffer(tpl_surface_t *surface, wayland_egl_surface, wayland_egl_surface->tbm_queue, tbm_surface, tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); + wayland_egl_buffer = + __tpl_wayland_egl_get_wayland_buffer_from_tbm_surface(tbm_surface); + + if (!wayland_egl_buffer) return TPL_ERROR_INVALID_PARAMETER; + + /* In frontbuffer mode, will skip tbm_surface_queue_enqueue, acquire, and + * commit if surface->frontbuffer that is already set and the tbm_surface + * client want to enqueue are the same. + */ + if (surface->is_frontbuffer_mode && surface->frontbuffer == tbm_surface) { + TPL_LOG_B("WL_EGL", + "[ENQ_SKIP][F] Client already uses frontbuffer(%p)", + surface->frontbuffer); + + /* The first buffer to be activated in frontbuffer mode muse be + * committed. Subsequence frames do not need to be committed because + * the buffer is already displayed. + */ + if (wayland_egl_buffer->is_new) { + __tpl_wayland_egl_surface_commit(surface, tbm_surface, + num_rects, rects); + wayland_egl_buffer->is_new = TPL_FALSE; + } + + return TPL_ERROR_NONE; + } + if (wayland_egl_surface->vblank_done == TPL_FALSE) __tpl_wayland_egl_surface_wait_vblank(surface); @@ -833,11 +861,6 @@ __tpl_wayland_egl_surface_enqueue_buffer(tpl_surface_t *surface, TPL_OBJECT_UNLOCK(&wayland_egl_surface->base); } - wayland_egl_buffer = - __tpl_wayland_egl_get_wayland_buffer_from_tbm_surface(tbm_surface); - - if (!wayland_egl_buffer) return TPL_ERROR_INVALID_PARAMETER; - if (wayland_egl_buffer->reset) { /* * When tbm_surface_queue being reset for receiving @@ -1006,6 +1029,7 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou struct wl_egl_window *wl_egl_window = (struct wl_egl_window *)surface->native_handle; tbm_surface_queue_error_e tsq_err = 0; + int is_activated = 0; if (sync_fence) *sync_fence = -1; @@ -1026,10 +1050,41 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou } if (__tpl_wayland_egl_surface_wait_dequeuable(surface)) { - TPL_ERR("Failed to wait dequeeable buffer"); + TPL_ERR("Failed to wait dequeueable buffer"); return NULL; } + /* wayland client can check their states (ACTIVATED or DEACTIVATED) with + * below function [wayland_tbm_client_queue_check_activate()]. + * This function has to be called between + * __tpl_wayland_egl_surface_wait_dequeuable and tbm_surface_queue_dequeue() + * in order to know what state the buffer will be dequeued next. + * + * ACTIVATED state means non-composite mode. Client can get buffers which + can be displayed directly(without compositing). + * DEACTIVATED state means composite mode. Client's buffer will be displayed + by compositor(E20) with compositing. + */ + is_activated = wayland_tbm_client_queue_check_activate( + wayland_egl_display->wl_tbm_client, + wayland_egl_surface->tbm_queue); + + if (surface->is_frontbuffer_mode && surface->frontbuffer != NULL) { + /* If surface->frontbuffer is already set in frontbuffer mode, + * it will return that frontbuffer if it is still activated, + * otherwise dequeue the new buffer after initializing + * surface->frontbuffer to NULL. */ + if (is_activated) { + TPL_LOG_B("WL_EGL", + "[DEQ][F] surface->frontbuffer(%p) BO_NAME(%d)", + surface->frontbuffer, + tbm_bo_export(tbm_surface_internal_get_bo( + surface->frontbuffer, 0))); + return surface->frontbuffer; + } else + surface->frontbuffer = NULL; + } + tsq_err = tbm_surface_queue_dequeue(wayland_egl_surface->tbm_queue, &tbm_surface); if (!tbm_surface) { @@ -1040,6 +1095,9 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou tbm_surface_internal_ref(tbm_surface); + if (surface->is_frontbuffer_mode && is_activated) + surface->frontbuffer = tbm_surface; + if ((wayland_egl_buffer = __tpl_wayland_egl_get_wayland_buffer_from_tbm_surface(tbm_surface)) != NULL) { TRACE_MARK("[DEQ][REUSED]BO_NAME:%d", tbm_bo_export(wayland_egl_buffer->bo)); @@ -1056,8 +1114,9 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou wayland_egl_buffer->width = wl_egl_window->width; wayland_egl_buffer->height = wl_egl_window->height; wayland_egl_buffer->rotation = wl_egl_window->rotation; - wayland_egl_buffer->reset = TPL_FALSE; + wayland_egl_buffer->is_new = TPL_FALSE; + wayland_egl_surface->reset = TPL_FALSE; if (wayland_egl_surface->dequeued_buffers) { @@ -1104,9 +1163,14 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou wayland_egl_buffer->bo = tbm_surface_internal_get_bo(tbm_surface, 0); wayland_egl_buffer->wayland_egl_surface = wayland_egl_surface; - /* reset flag is to check whether it is the buffer before tbm_surface_queue is reset or not. */ + /* reset flag is to check whether it is the buffer before + * tbm_surface_queue is reset or not. */ wayland_egl_buffer->reset = TPL_FALSE; + /* 'is_new' flag is to check wheter it is a new buffer need to commit + * in frontbuffer mode. */ + wayland_egl_buffer->is_new = TPL_TRUE; + wayland_egl_surface->current_buffer = tbm_surface; wayland_egl_surface->reset = TPL_FALSE; -- 2.7.4 From 52babccab63b757c16cfba32caf26de9b8aa7953 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 16 May 2017 18:17:54 +0900 Subject: [PATCH 05/16] tpl_wayland_egl: Fixed case of non-pixed buffer in frontbuffer mode. Change-Id: Ie5b6a7bc29bca359aa01092d4b9c86c79d8b0713 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index fe8c4d8..262183a 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -49,6 +49,7 @@ struct _tpl_wayland_egl_surface { tpl_bool_t reset; /* TRUE if queue reseted by external */ tdm_client_vblank *tdm_vblank; /* vblank object for each wl_surface */ tpl_bool_t vblank_done; + tpl_bool_t is_activated; tpl_list_t *attached_buffers; /* list for tracking [ACQ]~[REL] buffers */ tpl_list_t *dequeued_buffers; /* list for tracking [DEQ]~[ENQ] buffers */ struct tizen_surface_shm_flusher *tizen_surface_shm_flusher; /* wl_proxy for buffer flush */ @@ -500,6 +501,7 @@ __tpl_wayland_egl_surface_init(tpl_surface_t *surface) wayland_egl_surface->resized = TPL_FALSE; wayland_egl_surface->reset = TPL_FALSE; wayland_egl_surface->vblank_done = TPL_TRUE; + wayland_egl_surface->is_activated = TPL_FALSE; wayland_egl_surface->current_buffer = NULL; wayland_egl_surface->attached_buffers = __tpl_list_alloc(); @@ -1115,9 +1117,12 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou wayland_egl_buffer->height = wl_egl_window->height; wayland_egl_buffer->rotation = wl_egl_window->rotation; wayland_egl_buffer->reset = TPL_FALSE; - wayland_egl_buffer->is_new = TPL_FALSE; + + if (wayland_egl_surface->is_activated != is_activated) + wayland_egl_buffer->is_new = TPL_TRUE; wayland_egl_surface->reset = TPL_FALSE; + wayland_egl_surface->is_activated = is_activated; if (wayland_egl_surface->dequeued_buffers) { TPL_OBJECT_LOCK(&wayland_egl_surface->base); @@ -1170,6 +1175,7 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou /* 'is_new' flag is to check wheter it is a new buffer need to commit * in frontbuffer mode. */ wayland_egl_buffer->is_new = TPL_TRUE; + wayland_egl_surface->is_activated = is_activated; wayland_egl_surface->current_buffer = tbm_surface; wayland_egl_surface->reset = TPL_FALSE; -- 2.7.4 From 62256d3d39b892520d7fa20ce64a2fe57239fbea Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 16 May 2017 18:51:59 +0900 Subject: [PATCH 06/16] wayland_egl: Fixed build warning. Change-Id: I21132792d3606114dc3cb96192a9703d7836d8e1 Signed-off-by: joonbum.ko --- src/wayland-egl/wayland-egl.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/wayland-egl/wayland-egl.c b/src/wayland-egl/wayland-egl.c index 475bf7c..423de31 100644 --- a/src/wayland-egl/wayland-egl.c +++ b/src/wayland-egl/wayland-egl.c @@ -16,27 +16,27 @@ unsigned int wl_egl_log_level; /* WL-EGL Log Level - 0:unintialized, 1:initialized(no logging), 2:min log, 3:more log */ #define WL_EGL_LOG(lvl, f, x...) { \ - if(wl_egl_log_level == 1) { \ + if (wl_egl_log_level == 1) { \ } \ - else if(wl_egl_log_level > 1) { \ - if(wl_egl_log_level <= lvl) \ + else if (wl_egl_log_level > 1) { \ + if (wl_egl_log_level <= lvl) \ WL_EGL_LOG_PRINT(f, ##x) \ } \ else { \ char *env = getenv("WL_EGL_LOG_LEVEL"); \ - if(env == NULL) \ + if (env == NULL) \ wl_egl_log_level = 1; \ else \ wl_egl_log_level = atoi(env); \ \ - if(wl_egl_log_level > 1 && wl_egl_log_level <= lvl) \ + if (wl_egl_log_level > 1 && wl_egl_log_level <= lvl)\ WL_EGL_LOG_PRINT(f, ##x) \ } \ } #define WL_EGL_LOG_PRINT(fmt, args...) { \ printf("[\x1b[32mWL-EGL\x1b[0m %d:%d|\x1b[32m%s\x1b[0m|%d] " fmt "\n", \ - getpid(), (int)syscall(SYS_gettid), __func__,__LINE__, ##args); \ + getpid(), (int)syscall(SYS_gettid), __func__, __LINE__, ##args); \ } #define WL_EGL_ERR(f, x...) { \ @@ -53,8 +53,6 @@ wl_egl_window_resize(struct wl_egl_window *egl_window, int width, int height, int dx, int dy) { - wl_egl_window_rotation rotation; - if (egl_window == NULL) { WL_EGL_ERR("egl_window is NULL"); return; @@ -150,7 +148,8 @@ wl_egl_window_set_rotation(struct wl_egl_window *egl_window, } if (egl_window->rotation == rotation) { - WL_EGL_LOG(2, "rotation(%d) egl_window->rotation(%d) already rotated"); + WL_EGL_LOG(2, "rotation(%d) egl_window->rotation(%d) already rotated", + rotation, egl_window->rotation); return; } -- 2.7.4 From 682d1002a2440e65c9af593b058460b7ca8e6549 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 16 May 2017 20:04:17 +0900 Subject: [PATCH 07/16] tpl_wayland_egl: Added async trace points to track frontbuffer. Change-Id: I61f9a665ffaf492ecd5b465f7f2786f764572f1c Signed-off-by: joonbum.ko --- src/tpl_wayland_egl.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 262183a..e05c845 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -842,6 +842,9 @@ __tpl_wayland_egl_surface_enqueue_buffer(tpl_surface_t *surface, __tpl_wayland_egl_surface_commit(surface, tbm_surface, num_rects, rects); wayland_egl_buffer->is_new = TPL_FALSE; + } else { + TRACE_ASYNC_END((int)wayland_egl_buffer, "[DEQ]~[ENQ] BO_NAME:%d", + tbm_bo_export(wayland_egl_buffer->bo)); } return TPL_ERROR_NONE; @@ -1082,6 +1085,13 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou surface->frontbuffer, tbm_bo_export(tbm_surface_internal_get_bo( surface->frontbuffer, 0))); + wayland_egl_buffer = + __tpl_wayland_egl_get_wayland_buffer_from_tbm_surface( + surface->frontbuffer); + if (wayland_egl_buffer) + TRACE_ASYNC_BEGIN((int)wayland_egl_buffer, + "[DEQ]~[ENQ] BO_NAME:%d", + tbm_bo_export(wayland_egl_buffer->bo)); return surface->frontbuffer; } else surface->frontbuffer = NULL; -- 2.7.4 From eaf23ddd76f8ff718763decb447fe5509ff37bce Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Wed, 17 May 2017 15:25:58 +0900 Subject: [PATCH 08/16] tpl: Add missed mutex lock / unlock on __tpl_runtime_fini() If race condition occures on __tpl_hashlist_destroy() of __tpl_runtime_fini(), then __tpl_hashlist_destroy() can raise double free. This patch fixes it. Change-Id: Ib438e7e9b3a69d330fbda05d8090d76a80a19222 Signed-off-by: joonbum.ko --- src/tpl.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/tpl.c b/src/tpl.c index 23cf39b..afde8d8 100644 --- a/src/tpl.c +++ b/src/tpl.c @@ -2,7 +2,7 @@ unsigned int tpl_log_lvl = 0; unsigned int tpl_log_initialized = 0; -unsigned int tpl_dump_lvl; +unsigned int tpl_dump_lvl = 0; struct _tpl_runtime { tpl_hlist_t *displays[TPL_BACKEND_COUNT]; @@ -40,9 +40,12 @@ __tpl_runtime_fini(void) if (runtime != NULL) { int i; - for (i = 0; i < TPL_BACKEND_COUNT; i++) { - if (runtime->displays[i] != NULL) - __tpl_hashlist_destroy(&(runtime->displays[i])); + if (!pthread_mutex_lock(&runtime_mutex)) { + for (i = 0; i < TPL_BACKEND_COUNT; i++) { + if (runtime->displays[i] != NULL) + __tpl_hashlist_destroy(&(runtime->displays[i])); + } + pthread_mutex_unlock(&runtime_mutex); } free(runtime); @@ -71,7 +74,7 @@ __tpl_util_sys_yield(void) int __tpl_util_clz(int val) { - return __builtin_clz( val ); + return __builtin_clz(val); } int @@ -99,7 +102,7 @@ __tpl_util_atomic_set(tpl_util_atomic_uint *const atom, unsigned int val) } unsigned int -__tpl_util_atomic_inc(tpl_util_atomic_uint *const atom ) +__tpl_util_atomic_inc(tpl_util_atomic_uint *const atom) { TPL_ASSERT(atom); @@ -107,7 +110,7 @@ __tpl_util_atomic_inc(tpl_util_atomic_uint *const atom ) } unsigned int -__tpl_util_atomic_dec( tpl_util_atomic_uint *const atom ) +__tpl_util_atomic_dec(tpl_util_atomic_uint *const atom) { TPL_ASSERT(atom); -- 2.7.4 From 8ba144e4e516e8c528ab0c63470c6b0b07aa6e8e Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Mon, 22 May 2017 16:36:18 +0900 Subject: [PATCH 09/16] wayland-egl: Added an API to set frontbuffer mode. Change-Id: Id8f52c83ae4a110ce00c9c1271babcfaf242f9bd Signed-off-by: joonbum.ko --- src/wayland-egl/wayland-egl-priv.h | 3 +++ src/wayland-egl/wayland-egl.c | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/wayland-egl/wayland-egl-priv.h b/src/wayland-egl/wayland-egl-priv.h index 3c284fc..619fa99 100644 --- a/src/wayland-egl/wayland-egl-priv.h +++ b/src/wayland-egl/wayland-egl-priv.h @@ -28,10 +28,13 @@ struct wl_egl_window { wl_egl_window_rotation rotation; + int frontbuffer_mode; + 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 *); + void (*set_frontbuffer_callback)(struct wl_egl_window *, void *, int); }; #ifdef __cplusplus diff --git a/src/wayland-egl/wayland-egl.c b/src/wayland-egl/wayland-egl.c index 423de31..8c03f04 100644 --- a/src/wayland-egl/wayland-egl.c +++ b/src/wayland-egl/wayland-egl.c @@ -175,3 +175,19 @@ wl_egl_window_get_capabilities(struct wl_egl_window *egl_window) return capabilities; } + +WL_EGL_EXPORT void +wl_egl_window_set_frontbuffer_mode(struct wl_egl_window *egl_window, + int set) +{ + if (egl_window == NULL) { + WL_EGL_ERR("egl_window is NULL"); + return; + } + + egl_window->frontbuffer_mode = set; + + if (egl_window->set_frontbuffer_callback) + egl_window->set_frontbuffer_callback(egl_window, egl_window->private, + set); +} -- 2.7.4 From 8713ce9bcf0e284ec70d59f040cad1f65c850a80 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Mon, 22 May 2017 16:40:09 +0900 Subject: [PATCH 10/16] tpl_wayland_egl: Registered a callback function to set frontbuffer mode. Change-Id: I03267086c07b258b6453dd9fe1fcd42bcbf503cc Signed-off-by: joonbum.ko --- src/tpl_wayland_egl.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index e05c845..5e83345 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -379,6 +379,10 @@ static int __cb_client_window_get_rotation_capability(struct wl_egl_window *wl_egl_window, void *private); +static void +__cb_client_window_set_frontbuffer_mode(struct wl_egl_window *wl_egl_window, + void *private, int set); + static TPL_INLINE void __tpl_wayland_egl_buffer_set_reset_flag(tpl_list_t *tracking_list) { @@ -556,6 +560,8 @@ __tpl_wayland_egl_surface_init(tpl_surface_t *surface) wl_egl_window->rotate_callback = (void *)__cb_client_window_rotate_callback; wl_egl_window->get_rotation_capability = (void *) __cb_client_window_get_rotation_capability; + wl_egl_window->set_frontbuffer_callback = (void *) + __cb_client_window_set_frontbuffer_mode; /* 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. */ @@ -1095,6 +1101,8 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou return surface->frontbuffer; } else surface->frontbuffer = NULL; + } else { + surface->frontbuffer = NULL; } tsq_err = tbm_surface_queue_dequeue(wayland_egl_surface->tbm_queue, @@ -1397,6 +1405,19 @@ __cb_client_window_get_rotation_capability(struct wl_egl_window *wl_egl_window, return rotation_capability; } +static void +__cb_client_window_set_frontbuffer_mode(struct wl_egl_window *wl_egl_window, + void *private, int set) +{ + TPL_ASSERT(private); + TPL_ASSERT(wl_egl_window); + tpl_surface_t *surface = (tpl_surface_t *)private; + + if (set) + surface->is_frontbuffer_mode = TPL_TRUE; + else + surface->is_frontbuffer_mode = TPL_FALSE; +} void __cb_resistry_global_callback(void *data, struct wl_registry *wl_registry, -- 2.7.4 From 42cb0fa6816374ae01675d5dfecacfed3ae97bec Mon Sep 17 00:00:00 2001 From: Sangjin Lee Date: Wed, 7 Jun 2017 07:59:01 +0900 Subject: [PATCH 11/16] tpl_wayland_egl: implement free_flush protocol Implement free_flush of tizen_surface_shm_flusher. Just flush free_buffer when receive free_flush event from server. If this protocol is active in server, it can reduce quick_panel buffer 3 to 1 in idle time. Change-Id: I165af89f6030b651f4417e260e1dcb6115acaa44 --- src/protocol/tizen-surface-client.h | 55 ++++++++++++++++++++++------------- src/protocol/tizen-surface-protocol.c | 5 ++-- src/protocol/tizen-surface.xml | 16 ++++++++++ src/tpl_wayland_egl.c | 40 ++++++++++++++++++++++++- 4 files changed, 93 insertions(+), 23 deletions(-) create mode 100644 src/protocol/tizen-surface.xml diff --git a/src/protocol/tizen-surface-client.h b/src/protocol/tizen-surface-client.h index 6159a82..6eaa459 100644 --- a/src/protocol/tizen-surface-client.h +++ b/src/protocol/tizen-surface-client.h @@ -14,15 +14,17 @@ struct wl_resource; struct tizen_surface_shm; struct tizen_surface_shm_flusher; +struct wl_surface; extern const struct wl_interface tizen_surface_shm_interface; extern const struct wl_interface tizen_surface_shm_flusher_interface; #define TIZEN_SURFACE_SHM_GET_FLUSHER 0 +#define TIZEN_SURFACE_SHM_GET_FLUSHER_SINCE_VERSION 1 + static inline void -tizen_surface_shm_set_user_data(struct tizen_surface_shm *tizen_surface_shm, - void *user_data) +tizen_surface_shm_set_user_data(struct tizen_surface_shm *tizen_surface_shm, void *user_data) { wl_proxy_set_user_data((struct wl_proxy *) tizen_surface_shm, user_data); } @@ -33,6 +35,12 @@ tizen_surface_shm_get_user_data(struct tizen_surface_shm *tizen_surface_shm) return wl_proxy_get_user_data((struct wl_proxy *) tizen_surface_shm); } +static inline uint32_t +tizen_surface_shm_get_version(struct tizen_surface_shm *tizen_surface_shm) +{ + return wl_proxy_get_version((struct wl_proxy *) tizen_surface_shm); +} + static inline void tizen_surface_shm_destroy(struct tizen_surface_shm *tizen_surface_shm) { @@ -40,14 +48,12 @@ tizen_surface_shm_destroy(struct tizen_surface_shm *tizen_surface_shm) } static inline struct tizen_surface_shm_flusher * -tizen_surface_shm_get_flusher(struct tizen_surface_shm *tizen_surface_shm, - struct wl_surface *surface) +tizen_surface_shm_get_flusher(struct tizen_surface_shm *tizen_surface_shm, struct wl_surface *surface) { struct wl_proxy *id; id = wl_proxy_marshal_constructor((struct wl_proxy *) tizen_surface_shm, - TIZEN_SURFACE_SHM_GET_FLUSHER, &tizen_surface_shm_flusher_interface, NULL, - surface); + TIZEN_SURFACE_SHM_GET_FLUSHER, &tizen_surface_shm_flusher_interface, NULL, surface); return (struct tizen_surface_shm_flusher *) id; } @@ -57,41 +63,50 @@ struct tizen_surface_shm_flusher_listener { * flush - (none) */ void (*flush)(void *data, - struct tizen_surface_shm_flusher *tizen_surface_shm_flusher); + struct tizen_surface_shm_flusher *tizen_surface_shm_flusher); + /** + * free_flush - (none) + * @since: 2 + */ + void (*free_flush)(void *data, + struct tizen_surface_shm_flusher *tizen_surface_shm_flusher); }; static inline int -tizen_surface_shm_flusher_add_listener(struct tizen_surface_shm_flusher - *tizen_surface_shm_flusher, - const struct tizen_surface_shm_flusher_listener *listener, void *data) +tizen_surface_shm_flusher_add_listener(struct tizen_surface_shm_flusher *tizen_surface_shm_flusher, + const struct tizen_surface_shm_flusher_listener *listener, void *data) { return wl_proxy_add_listener((struct wl_proxy *) tizen_surface_shm_flusher, - (void (* *)(void)) listener, data); + (void (**)(void)) listener, data); } #define TIZEN_SURFACE_SHM_FLUSHER_DESTROY 0 +#define TIZEN_SURFACE_SHM_FLUSHER_DESTROY_SINCE_VERSION 1 + static inline void -tizen_surface_shm_flusher_set_user_data(struct tizen_surface_shm_flusher - *tizen_surface_shm_flusher, void *user_data) +tizen_surface_shm_flusher_set_user_data(struct tizen_surface_shm_flusher *tizen_surface_shm_flusher, void *user_data) { - wl_proxy_set_user_data((struct wl_proxy *) tizen_surface_shm_flusher, - user_data); + wl_proxy_set_user_data((struct wl_proxy *) tizen_surface_shm_flusher, user_data); } static inline void * -tizen_surface_shm_flusher_get_user_data(struct tizen_surface_shm_flusher - *tizen_surface_shm_flusher) +tizen_surface_shm_flusher_get_user_data(struct tizen_surface_shm_flusher *tizen_surface_shm_flusher) { return wl_proxy_get_user_data((struct wl_proxy *) tizen_surface_shm_flusher); } +static inline uint32_t +tizen_surface_shm_flusher_get_version(struct tizen_surface_shm_flusher *tizen_surface_shm_flusher) +{ + return wl_proxy_get_version((struct wl_proxy *) tizen_surface_shm_flusher); +} + static inline void -tizen_surface_shm_flusher_destroy(struct tizen_surface_shm_flusher - *tizen_surface_shm_flusher) +tizen_surface_shm_flusher_destroy(struct tizen_surface_shm_flusher *tizen_surface_shm_flusher) { wl_proxy_marshal((struct wl_proxy *) tizen_surface_shm_flusher, - TIZEN_SURFACE_SHM_FLUSHER_DESTROY); + TIZEN_SURFACE_SHM_FLUSHER_DESTROY); wl_proxy_destroy((struct wl_proxy *) tizen_surface_shm_flusher); } diff --git a/src/protocol/tizen-surface-protocol.c b/src/protocol/tizen-surface-protocol.c index 8420280..90da268 100644 --- a/src/protocol/tizen-surface-protocol.c +++ b/src/protocol/tizen-surface-protocol.c @@ -26,11 +26,12 @@ static const struct wl_message tizen_surface_shm_flusher_requests[] = { static const struct wl_message tizen_surface_shm_flusher_events[] = { { "flush", "", types + 0 }, + { "free_flush", "2", types + 0 }, }; WL_EXPORT const struct wl_interface tizen_surface_shm_flusher_interface = { - "tizen_surface_shm_flusher", 1, + "tizen_surface_shm_flusher", 2, 1, tizen_surface_shm_flusher_requests, - 1, tizen_surface_shm_flusher_events, + 2, tizen_surface_shm_flusher_events, }; diff --git a/src/protocol/tizen-surface.xml b/src/protocol/tizen-surface.xml new file mode 100644 index 0000000..ad516c0 --- /dev/null +++ b/src/protocol/tizen-surface.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 5e83345..f71b046 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -1556,9 +1556,47 @@ static void __cb_tizen_surface_shm_flusher_flush_callback(void *data, } } +static void __cb_tizen_surface_shm_flusher_free_flush_callback(void *data, + struct tizen_surface_shm_flusher *tizen_surface_shm_flusher) +{ + tpl_surface_t *surface = data; + tpl_wayland_egl_surface_t *wayland_egl_surface; + tpl_wayland_egl_display_t *wayland_egl_display; + int ret; + + TPL_CHECK_ON_NULL_RETURN(surface); + wayland_egl_surface = surface->backend.data; + TPL_CHECK_ON_NULL_RETURN(wayland_egl_surface); + TPL_CHECK_ON_NULL_RETURN(surface->display); + wayland_egl_display = surface->display->backend.data; + TPL_CHECK_ON_NULL_RETURN(wayland_egl_display); + + TPL_CHECK_ON_NULL_RETURN(wayland_egl_display->wl_dpy); + 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 + */ + ret = wl_display_dispatch_queue_pending(wayland_egl_display->wl_dpy, + wayland_egl_display->wl_tbm_event_queue); + if (ret == -1) { + TPL_ERR("Failed to wl_display_dispatch_queue_pending ret:%d, err:%d", ret, + errno); + return; + } + + tbm_surface_queue_free_flush(wayland_egl_surface->tbm_queue); +} + static const struct tizen_surface_shm_flusher_listener tizen_surface_shm_flusher_listener = { - __cb_tizen_surface_shm_flusher_flush_callback + __cb_tizen_surface_shm_flusher_flush_callback, + __cb_tizen_surface_shm_flusher_free_flush_callback }; static void -- 2.7.4 From 53ad3dd935abe10491ef2e397f2320b074452a1d Mon Sep 17 00:00:00 2001 From: Sangjin Lee Date: Fri, 9 Jun 2017 16:22:13 +0900 Subject: [PATCH 12/16] tpl_wayland_egl: change version of shm_flusher Change-Id: Id0d73a50953a8d2c07430ddf18386dec91e9e636 --- src/protocol/tizen-surface-protocol.c | 2 +- src/tpl_wayland_egl.c | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/protocol/tizen-surface-protocol.c b/src/protocol/tizen-surface-protocol.c index 90da268..bd5e8a6 100644 --- a/src/protocol/tizen-surface-protocol.c +++ b/src/protocol/tizen-surface-protocol.c @@ -15,7 +15,7 @@ static const struct wl_message tizen_surface_shm_requests[] = { }; WL_EXPORT const struct wl_interface tizen_surface_shm_interface = { - "tizen_surface_shm", 1, + "tizen_surface_shm", 2, 1, tizen_surface_shm_requests, 0, NULL, }; diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index f71b046..3328f35 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -1419,6 +1419,8 @@ __cb_client_window_set_frontbuffer_mode(struct wl_egl_window *wl_egl_window, surface->is_frontbuffer_mode = TPL_FALSE; } +#define IMPL_TIZEN_SURFACE_SHM_VERSION 2 + void __cb_resistry_global_callback(void *data, struct wl_registry *wl_registry, uint32_t name, const char *interface, @@ -1431,10 +1433,12 @@ __cb_resistry_global_callback(void *data, struct wl_registry *wl_registry, wl_registry_bind(wl_registry, name, &tizen_surface_shm_interface, - version); + ((version < IMPL_TIZEN_SURFACE_SHM_VERSION) ? + version : IMPL_TIZEN_SURFACE_SHM_VERSION)); } } + void __cb_resistry_global_remove_callback(void *data, struct wl_registry *wl_registry, -- 2.7.4 From 6a85a832601403b487e996f744ee39816618963e Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 11 Apr 2017 16:07:37 +0900 Subject: [PATCH 13/16] wayland_egl: Added new APIs related with wl_surface_set_buffer_transform. - If wayland_egl provides the following function, the client can set the correct transform value, and tpl_wayland_egl can pass the transform value to the server at the appropriate time (befor wl_surface_attach). - New wayland_egl API: void wl_egl_window_set_buffer_transform(struct wl_egl_window *egl_window, int wl_output_transform) - egl_window cannot be NULL. - wl_output_transform is a value of WL_OUTPUT_TRANSFORM enum. (See wayland.xml) Change-Id: Ibf4d1b8eee90ee75f519a6ad6bb680299d780d26 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl.c | 49 +++++++++++++++++++++++++++++++------- src/wayland-egl/wayland-egl-priv.h | 2 +- src/wayland-egl/wayland-egl.c | 19 +++++++++++++++ 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 3328f35..0404064 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -60,8 +60,9 @@ struct _tpl_wayland_egl_buffer { tpl_wayland_egl_surface_t *wayland_egl_surface; int dx, dy; int width, height; - int rotation; + int transform; tbm_bo bo; + tpl_bool_t rotated; /* TRUE if need to call wl_surface_set_buffer_transform */ tpl_bool_t reset; /* TRUE if queue reseted by external */ tpl_bool_t is_new; /* for frontbuffer mode */ struct wl_proxy *wl_proxy; /* wl_buffer proxy */ @@ -724,6 +725,7 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, tpl_wayland_egl_surface_t *wayland_egl_surface = (tpl_wayland_egl_surface_t *) surface->backend.data; tdm_error tdm_err = 0; + uint32_t version; wayland_egl_buffer = __tpl_wayland_egl_get_wayland_buffer_from_tbm_surface(tbm_surface); @@ -734,6 +736,13 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, TPL_IMAGE_DUMP(tbm_surface, surface->width, surface->height); + version = wl_proxy_get_version((struct wl_proxy *)wl_egl_window->surface); + + if (wayland_egl_buffer->rotated == TPL_TRUE) { + wl_surface_set_buffer_transform(wl_egl_window->surface, + wayland_egl_buffer->transform); + } + wl_surface_attach(wl_egl_window->surface, (void *)wayland_egl_buffer->wl_proxy, wayland_egl_buffer->dx, wayland_egl_buffer->dy); @@ -741,9 +750,19 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, wl_egl_window->attached_height = wayland_egl_buffer->height; if (num_rects < 1 || rects == NULL) { - wl_surface_damage(wl_egl_window->surface, - wayland_egl_buffer->dx, wayland_egl_buffer->dy, - wayland_egl_buffer->width, wayland_egl_buffer->height); + if (version < 4) { + wl_surface_damage(wl_egl_window->surface, + wayland_egl_buffer->dx, + wayland_egl_buffer->dy, + wayland_egl_buffer->width, + wayland_egl_buffer->height); + } else { + wl_surface_damage_buffer(wl_egl_window->surface, + wayland_egl_buffer->dx, + wayland_egl_buffer->dy, + wayland_egl_buffer->width, + wayland_egl_buffer->height); + } } else { int i; @@ -754,9 +773,15 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, * y = [WINDOW.HEIGHT] - (RECT.Y + RECT.HEIGHT) */ int inverted_y = wayland_egl_buffer->height - (rects[i * 4 + 1] + rects[i * 4 + 3]); - wl_surface_damage(wl_egl_window->surface, - rects[i * 4 + 0], inverted_y, - rects[i * 4 + 2], rects[i * 4 + 3]); + if (version < 4) { + wl_surface_damage(wl_egl_window->surface, + rects[i * 4 + 0], inverted_y, + rects[i * 4 + 2], rects[i * 4 + 3]); + } else { + wl_surface_damage_buffer(wl_egl_window->surface, + rects[i * 4 + 0], inverted_y, + rects[i * 4 + 2], rects[i * 4 + 3]); + } } } @@ -1133,7 +1158,12 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou wayland_egl_buffer->dy = wl_egl_window->dy; wayland_egl_buffer->width = wl_egl_window->width; wayland_egl_buffer->height = wl_egl_window->height; - wayland_egl_buffer->rotation = wl_egl_window->rotation; + if (wayland_egl_buffer->transform != wl_egl_window->transform) { + wayland_egl_buffer->transform = wl_egl_window->transform; + wayland_egl_buffer->rotated = TPL_TRUE; + } else { + wayland_egl_buffer->rotated = TPL_FALSE; + } wayland_egl_buffer->reset = TPL_FALSE; if (wayland_egl_surface->is_activated != is_activated) @@ -1180,7 +1210,8 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou wayland_egl_buffer->dy = wl_egl_window->dy; wayland_egl_buffer->width = wl_egl_window->width; wayland_egl_buffer->height = wl_egl_window->height; - wayland_egl_buffer->rotation = wl_egl_window->rotation; + wayland_egl_buffer->transform = wl_egl_window->transform; + wayland_egl_buffer->rotated = TPL_FALSE; wayland_egl_buffer->display = wayland_egl_display; wayland_egl_buffer->wl_proxy = wl_proxy; wayland_egl_buffer->bo = tbm_surface_internal_get_bo(tbm_surface, 0); diff --git a/src/wayland-egl/wayland-egl-priv.h b/src/wayland-egl/wayland-egl-priv.h index 619fa99..f2b2d05 100644 --- a/src/wayland-egl/wayland-egl-priv.h +++ b/src/wayland-egl/wayland-egl-priv.h @@ -27,8 +27,8 @@ struct wl_egl_window { int attached_height; wl_egl_window_rotation rotation; - int frontbuffer_mode; + int transform; void *private; void (*resize_callback)(struct wl_egl_window *, void *); diff --git a/src/wayland-egl/wayland-egl.c b/src/wayland-egl/wayland-egl.c index 8c03f04..37e81d5 100644 --- a/src/wayland-egl/wayland-egl.c +++ b/src/wayland-egl/wayland-egl.c @@ -159,6 +159,25 @@ wl_egl_window_set_rotation(struct wl_egl_window *egl_window, egl_window->rotate_callback(egl_window, egl_window->private); } +WL_EGL_EXPORT void +wl_egl_window_set_buffer_transform(struct wl_egl_window *egl_window, + int wl_output_transform) +{ + if (egl_window == NULL) { + WL_EGL_ERR("egl_window is NULL"); + return; + } + + if (egl_window->transform == wl_output_transform) { + WL_EGL_LOG(2, + "wl_output_transform(%d) egl_window->transform(%d) already rotated", + wl_output_transform, egl_window->transform); + return; + } + + egl_window->transform = wl_output_transform; +} + WL_EGL_EXPORT int wl_egl_window_get_capabilities(struct wl_egl_window *egl_window) { -- 2.7.4 From 8d96f176903731eb3724cb8840f36401eddf8d52 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Thu, 15 Jun 2017 17:53:28 +0900 Subject: [PATCH 14/16] tpl_wayland_egl: Deleted unused listener to resolve build warning. Change-Id: I10a524f2a1a452a31c3089f68dfc36ebbf04ff4c Signed-off-by: joonbum.ko --- src/tpl_wayland_egl.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 0404064..2943ab7 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -68,7 +68,6 @@ struct _tpl_wayland_egl_buffer { struct wl_proxy *wl_proxy; /* wl_buffer proxy */ }; -static const struct wl_callback_listener sync_listener; static const struct wl_buffer_listener buffer_release_listener; static int tpl_wayland_egl_buffer_key; @@ -1314,24 +1313,6 @@ __tpl_surface_init_backend_wayland_egl(tpl_surface_backend_t *backend) } static void -__cb_client_sync_callback(void *data, struct wl_callback *callback, - uint32_t serial) -{ - int *done; - - TPL_ASSERT(data); - - done = data; - *done = 1; - - wl_callback_destroy(callback); -} - -static const struct wl_callback_listener sync_listener = { - __cb_client_sync_callback -}; - -static void __cb_client_buffer_release_callback(void *data, struct wl_proxy *proxy) { tbm_surface_h tbm_surface = NULL; -- 2.7.4 From 5bc8a55ae095df3d5182d118fcbf90bd2c4cb0ae Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Thu, 15 Jun 2017 18:01:16 +0900 Subject: [PATCH 15/16] package version up to 1.1.0 Change-Id: I748a032a7fc41501c0ac43294c083d252f78cbeb Signed-off-by: joonbum.ko --- packaging/libtpl-egl.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/libtpl-egl.spec b/packaging/libtpl-egl.spec index f0998a5..0d24806 100644 --- a/packaging/libtpl-egl.spec +++ b/packaging/libtpl-egl.spec @@ -1,6 +1,6 @@ #TPL VERSION MACROS %define TPL_VER_MAJOR 1 -%define TPL_VER_MINOR 0 +%define TPL_VER_MINOR 1 %define TPL_RELEASE 0 %define TPL_VERSION %{TPL_VER_MAJOR}.%{TPL_VER_MINOR} %define TPL_VER_FULL %{TPL_VERSION}.%{TPL_RELEASE} @@ -19,7 +19,7 @@ %define ENABLE_TPL_TEST 0 #WAYLAND-EGL VERSION MACROS -%define WL_EGL_VERSION 1.0.0 +%define WL_EGL_VERSION 1.1.0 #TPL WINDOW SYSTEM CHECK %if "%{TPL_WINSYS}" != "DRI2" && "%{TPL_WINSYS}" != "DRI3" && "%{TPL_WINSYS}" != "WL" -- 2.7.4 From e8ff7221c3ec05347c3c007c24a1ccc1bb41a6c8 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Fri, 16 Jun 2017 14:00:16 +0900 Subject: [PATCH 16/16] tpl_wayland_egl: Fixed errors in managing the transform value. - package version up to 1.1.1 Change-Id: I93b2cb8fd7c2b0f0957ee4e45a9a1c744b4cc75f Signed-off-by: joonbum.ko --- packaging/libtpl-egl.spec | 2 +- src/tpl_wayland_egl.c | 37 +++++++++++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/packaging/libtpl-egl.spec b/packaging/libtpl-egl.spec index 0d24806..064e1ea 100644 --- a/packaging/libtpl-egl.spec +++ b/packaging/libtpl-egl.spec @@ -1,7 +1,7 @@ #TPL VERSION MACROS %define TPL_VER_MAJOR 1 %define TPL_VER_MINOR 1 -%define TPL_RELEASE 0 +%define TPL_RELEASE 1 %define TPL_VERSION %{TPL_VER_MAJOR}.%{TPL_VER_MINOR} %define TPL_VER_FULL %{TPL_VERSION}.%{TPL_RELEASE} diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 2943ab7..8877eef 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -50,6 +50,7 @@ struct _tpl_wayland_egl_surface { tdm_client_vblank *tdm_vblank; /* vblank object for each wl_surface */ tpl_bool_t vblank_done; tpl_bool_t is_activated; + int latest_transform; tpl_list_t *attached_buffers; /* list for tracking [ACQ]~[REL] buffers */ tpl_list_t *dequeued_buffers; /* list for tracking [DEQ]~[ENQ] buffers */ struct tizen_surface_shm_flusher *tizen_surface_shm_flusher; /* wl_proxy for buffer flush */ @@ -507,6 +508,7 @@ __tpl_wayland_egl_surface_init(tpl_surface_t *surface) wayland_egl_surface->vblank_done = TPL_TRUE; wayland_egl_surface->is_activated = TPL_FALSE; wayland_egl_surface->current_buffer = NULL; + wayland_egl_surface->latest_transform = wl_egl_window->transform; wayland_egl_surface->attached_buffers = __tpl_list_alloc(); if (!wayland_egl_surface->attached_buffers) { @@ -1147,17 +1149,13 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou TRACE_MARK("[DEQ][REUSED]BO_NAME:%d", tbm_bo_export(wayland_egl_buffer->bo)); TRACE_ASYNC_BEGIN((int)wayland_egl_buffer, "[DEQ]~[ENQ] BO_NAME:%d", tbm_bo_export(wayland_egl_buffer->bo)); - TPL_LOG_B("WL_EGL", - "[DEQ][R] tpl_wayland_surface_t(%p) wl_buffer(%p) tbm_surface(%p) bo(%d)", - wayland_egl_surface, - wayland_egl_buffer->wl_proxy, - tbm_surface, tbm_bo_export(wayland_egl_buffer->bo)); wayland_egl_buffer->dx = wl_egl_window->dx; wayland_egl_buffer->dy = wl_egl_window->dy; wayland_egl_buffer->width = wl_egl_window->width; wayland_egl_buffer->height = wl_egl_window->height; - if (wayland_egl_buffer->transform != wl_egl_window->transform) { + if (wayland_egl_surface->latest_transform != wl_egl_window->transform) { + wayland_egl_surface->latest_transform = wl_egl_window->transform; wayland_egl_buffer->transform = wl_egl_window->transform; wayland_egl_buffer->rotated = TPL_TRUE; } else { @@ -1179,6 +1177,17 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou TPL_OBJECT_UNLOCK(&wayland_egl_surface->base); } + TPL_LOG_B("WL_EGL", + "[DEQ][R] tpl_wayland_surface_t(%p) wl_buffer(%p) tbm_surface(%p) bo(%d)", + wayland_egl_surface, + wayland_egl_buffer->wl_proxy, + tbm_surface, tbm_bo_export(wayland_egl_buffer->bo)); + TPL_LOG_B("WL_EGL", + "[DEQ] size(%dx%d) transform(%d) rotated(%s)", + wayland_egl_buffer->width, wayland_egl_buffer->height, + wayland_egl_buffer->transform, + wayland_egl_buffer->rotated ? "[TRUE]" : "[FALSE]"); + return tbm_surface; } @@ -1209,12 +1218,18 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou wayland_egl_buffer->dy = wl_egl_window->dy; wayland_egl_buffer->width = wl_egl_window->width; wayland_egl_buffer->height = wl_egl_window->height; - wayland_egl_buffer->transform = wl_egl_window->transform; - wayland_egl_buffer->rotated = TPL_FALSE; wayland_egl_buffer->display = wayland_egl_display; wayland_egl_buffer->wl_proxy = wl_proxy; wayland_egl_buffer->bo = tbm_surface_internal_get_bo(tbm_surface, 0); wayland_egl_buffer->wayland_egl_surface = wayland_egl_surface; + wayland_egl_buffer->transform = wl_egl_window->transform; + + if (wayland_egl_surface->latest_transform != wl_egl_window->transform) { + wayland_egl_surface->latest_transform = wl_egl_window->transform; + wayland_egl_buffer->rotated = TPL_TRUE; + } else { + wayland_egl_buffer->rotated = TPL_FALSE; + } /* reset flag is to check whether it is the buffer before * tbm_surface_queue is reset or not. */ @@ -1239,6 +1254,12 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou wayland_egl_buffer, wayland_egl_buffer->wl_proxy, tbm_surface, tbm_bo_export(wayland_egl_buffer->bo)); + TPL_LOG_B("WL_EGL", + "[DEQ] size(%dx%d) transform(%d) rotated(%s)", + wayland_egl_buffer->width, wayland_egl_buffer->height, + wayland_egl_buffer->transform, + wayland_egl_buffer->rotated ? "[TRUE]" : "[FALSE]"); + if (wayland_egl_surface->dequeued_buffers) { TPL_OBJECT_LOCK(&wayland_egl_surface->base); __tpl_list_push_back(wayland_egl_surface->dequeued_buffers, -- 2.7.4