From e09597f41f31ee1a7bc953b78b5fb4a25e00e915 Mon Sep 17 00:00:00 2001 From: Sangjin Lee Date: Wed, 2 Dec 2015 11:03:51 +0900 Subject: [PATCH 01/16] Enable wayland-tbm buffer cache feature. Change-Id: Ifde1adc4975f9087a351c0a414ad5506c19b5504 --- src/tpl_wayland.c | 131 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 83 insertions(+), 48 deletions(-) diff --git a/src/tpl_wayland.c b/src/tpl_wayland.c index 5bd9557..1f40d41 100644 --- a/src/tpl_wayland.c +++ b/src/tpl_wayland.c @@ -52,7 +52,7 @@ enum wayland_buffer_status { IDLE = 0, BUSY = 1, - READY = 2, /* redering done */ + READY = 2, /* redering done */ POSTED = 3 /* gbm locked */ }; @@ -84,17 +84,17 @@ struct _tpl_wayland_display struct _tpl_wayland_surface { tpl_buffer_t *current_rendering_buffer; - tpl_list_t done_rendering_queue; - int current_back_idx; + tpl_list_t done_rendering_queue; + int current_back_idx; tpl_buffer_t *back_buffers[TPL_BUFFER_ALLOC_SIZE_MAX]; }; struct _tpl_wayland_buffer { - tpl_display_t *display; - tbm_surface_h tbm_surface; - tbm_bo bo; - int reused; + tpl_display_t *display; + tbm_surface_h tbm_surface; + tbm_bo bo; + int reused; enum wayland_buffer_status status; union @@ -102,12 +102,13 @@ struct _tpl_wayland_buffer struct { struct wl_proxy *wl_proxy; - tpl_bool_t resized; + tpl_bool_t resized; } app; struct { - struct gbm_bo *gbm_bo; - tpl_bool_t posted; + struct gbm_bo *gbm_bo; + tpl_bool_t posted; + struct wl_listener destroy_listener; } comp; } proc; }; @@ -1466,6 +1467,21 @@ __tpl_wayland_surface_create_buffer_from_wl_drm(tpl_surface_t *surface, tpl_bool return buffer; } #else +static void +__tpl_wayland_buffer_destroy_notify(struct wl_listener *listener, void *data) +{ + tpl_display_t *display; + tpl_wayland_display_t *wayland_display; + tpl_wayland_buffer_t *wayland_buffer = NULL; + size_t key = 0; + + wayland_buffer = wl_container_of(listener, wayland_buffer, proc.comp.destroy_listener); + display = wayland_buffer->display; + key = tbm_bo_export(wayland_buffer->bo); + wayland_display = (tpl_wayland_display_t *)display->backend.data; + __tpl_wayland_surface_buffer_cache_remove(&wayland_display->proc.comp.cached_buffers, key); +} + static tpl_buffer_t * __tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool_t *reset_buffers) { @@ -1498,53 +1514,72 @@ __tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool bo = tbm_surface_internal_get_bo(tbm_surface, 0); key = tbm_bo_export(bo); - /*TODO add tpl_wayland_surface_buffer_cache routine */ - if (TPL_TRUE != __tpl_wayland_display_get_pixmap_info(surface->display, surface->native_handle, - &width, &height, &format)) + buffer = __tpl_wayland_surface_buffer_cache_find(&wayland_display->proc.comp.cached_buffers, key); + if (buffer != NULL) { - TPL_ERR("Failed to get pixmap info!"); - return NULL; + __tpl_buffer_set_surface(buffer, surface); + tpl_object_reference((tpl_object_t *) buffer); } - - if (tbm_surface_get_info(tbm_surface, &tbm_surf_info) != 0) + else { - TPL_ERR("Failed to get stride info!"); - return NULL; - } + if (TPL_TRUE != __tpl_wayland_display_get_pixmap_info(surface->display, surface->native_handle, + &width, &height, &format)) + { + TPL_ERR("Failed to get pixmap info!"); + return NULL; + } - depth = __tpl_wayland_get_depth_from_format(format); - stride = tbm_surf_info.planes[0].stride; + if (tbm_surface_get_info(tbm_surface, &tbm_surf_info) != 0) + { + TPL_ERR("Failed to get stride info!"); + return NULL; + } - /* Create tpl buffer. */ - bo_handle = tbm_bo_get_handle(bo, TBM_DEVICE_3D); - if (NULL == bo_handle.ptr) - { - TPL_ERR("Failed to get bo handle!"); - return NULL; - } + depth = __tpl_wayland_get_depth_from_format(format); + stride = tbm_surf_info.planes[0].stride; - buffer = __tpl_buffer_alloc(surface, key, - (int) bo_handle.u32, width, height, depth, stride); - if (buffer == NULL) - { - TPL_ERR("Failed to alloc TPL buffer!"); - return NULL; - } + /* Create tpl buffer. */ + bo_handle = tbm_bo_get_handle(bo, TBM_DEVICE_3D); + if (NULL == bo_handle.ptr) + { + TPL_ERR("Failed to get bo handle!"); + return NULL; + } - wayland_buffer = (tpl_wayland_buffer_t *) calloc(1, sizeof(tpl_wayland_buffer_t)); - if (wayland_buffer == NULL) - { - TPL_ERR("Mem alloc failed for wayland buffer!"); - tpl_object_unreference((tpl_object_t *) buffer); - return NULL; - } + buffer = __tpl_buffer_alloc(surface, key, + (int) bo_handle.u32, width, height, depth, stride); + if (buffer == NULL) + { + TPL_ERR("Failed to alloc TPL buffer!"); + return NULL; + } - wayland_buffer->display = surface->display; - wayland_buffer->bo = bo; - wayland_buffer->tbm_surface = tbm_surface; + wayland_buffer = (tpl_wayland_buffer_t *) calloc(1, sizeof(tpl_wayland_buffer_t)); + if (wayland_buffer == NULL) + { + TPL_ERR("Mem alloc failed for wayland buffer!"); + tpl_object_unreference((tpl_object_t *) buffer); + return NULL; + } - buffer->backend.data = (void *)wayland_buffer; - buffer->key = key; + wayland_buffer->display = surface->display; + wayland_buffer->bo = bo; + wayland_buffer->tbm_surface = tbm_surface; + + buffer->backend.data = (void *)wayland_buffer; + buffer->key = key; + + if (TPL_TRUE != __tpl_wayland_surface_buffer_cache_add(&wayland_display->proc.comp.cached_buffers, buffer)) + { + TPL_ERR("Adding surface to buffer cache failed!"); + tpl_object_unreference((tpl_object_t *) buffer); + free(wayland_buffer); + return NULL; + } + + wayland_buffer->proc.comp.destroy_listener.notify = __tpl_wayland_buffer_destroy_notify; + wl_resource_add_destroy_listener((struct wl_resource*)surface->native_handle, &wayland_buffer->proc.comp.destroy_listener); + } if (reset_buffers != NULL) *reset_buffers = TPL_FALSE; -- 2.7.4 From 34293c3b41bb2f2972f9e377c3b7454cd619e423 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Wed, 25 Nov 2015 22:34:18 +0900 Subject: [PATCH 02/16] Apply tbm_surface_queue. (default:disabled) Change-Id: Ie82458a69cd254da25746960258a3a4bfcf78db5 --- Makefile | 4 + packaging/libtpl-egl.spec | 15 ++-- src/tpl_wayland.c | 181 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 184 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index 514eaff..8aaec80 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,11 @@ ifneq ($(call is-feature-enabled,wl_tbm),) else LDFLAGS += `pkg-config --libs wayland-drm` endif +ifneq ($(call is-feature-enabled,tbm_surface_queue),) + CFLAGS += -DTBM_SURFACE_QUEUE endif +endif + ifneq ($(call is-feature-enabled,ttrace),) CFLAGS += -DTTRACE_ENABLE endif diff --git a/packaging/libtpl-egl.spec b/packaging/libtpl-egl.spec index d822a43..34eb7a3 100644 --- a/packaging/libtpl-egl.spec +++ b/packaging/libtpl-egl.spec @@ -1,19 +1,19 @@ #TPL VERSION MACROS %define TPL_VER_MAJOR 0 %define TPL_VER_MINOR 8 -%define TPL_RELEASE 9 -%define TPL_VERSION %{TPL_VER_MAJOR}.%{TPL_VER_MINOR} +%define TPL_RELEASE 9 +%define TPL_VERSION %{TPL_VER_MAJOR}.%{TPL_VER_MINOR} %define TPL_VER_FULL %{TPL_VERSION}.%{TPL_RELEASE} #TPL WINDOW SYSTEM DEFINITION -%define TPL_WINSYS WL +%define TPL_WINSYS WL #TPL FEATURE OPTION %define ENABLE_TTRACE 0 -%define ENABLE_DLOG 0 -%define ENABLE_PNG_DUMP 0 +%define ENABLE_DLOG 0 +%define ENABLE_PNG_DUMP 0 %define ENABLE_WL_TBM 1 - +%define ENABLE_TBM_SURFACE_QUEUE 0 #WAYLAND-EGL VERSION MACROS %define WL_EGL_VERSION 1.0.0 @@ -122,6 +122,9 @@ TPL_OPTIONS=${TPL_OPTIONS}-winsys_wl %if "%{ENABLE_WL_TBM}" == "1" TPL_OPTIONS=${TPL_OPTIONS}-wl_tbm %endif +%if "%{ENABLE_TBM_SURFACE_QUEUE}" == "1" +TPL_OPTIONS=${TPL_OPTIONS}-tbm_surface_queue +%endif %endif %if "%{ENABLE_TTRACE}" == "1" diff --git a/src/tpl_wayland.c b/src/tpl_wayland.c index 1f40d41..19702fa 100644 --- a/src/tpl_wayland.c +++ b/src/tpl_wayland.c @@ -38,6 +38,10 @@ #include #endif +#ifdef TBM_SURFACE_QUEUE +#include +#endif + typedef struct _tpl_wayland_display tpl_wayland_display_t; typedef struct _tpl_wayland_surface tpl_wayland_surface_t; typedef struct _tpl_wayland_buffer tpl_wayland_buffer_t; @@ -87,6 +91,9 @@ struct _tpl_wayland_surface tpl_list_t done_rendering_queue; int current_back_idx; tpl_buffer_t *back_buffers[TPL_BUFFER_ALLOC_SIZE_MAX]; +#ifdef TBM_SURFACE_QUEUE + tbm_surface_queue_h tbm_queue; +#endif }; struct _tpl_wayland_buffer @@ -118,9 +125,11 @@ 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; +#ifndef TBM_SURFACE_QUEUE static struct gbm_bo *__cb_server_gbm_surface_lock_front_buffer(struct gbm_surface *gbm_surf); static void __cb_server_gbm_surface_release_buffer(struct gbm_surface *gbm_surf, struct gbm_bo *gbm_bo); static int __cb_server_gbm_surface_has_free_buffers(struct gbm_surface *gbm_surf); +#endif #ifdef EGL_BIND_WL_DISPLAY unsigned int __tpl_wayland_display_bind_client_display(tpl_display_t *tpl_display, tpl_handle_t native_dpy); @@ -361,12 +370,13 @@ __tpl_wayland_display_init(tpl_display_t *display) wayland_display->type = SERVER; +#ifndef TBM_SURFACE_QUEUE /* Hook gbm backend callbacks. If the compositor calls gbm APIs to get a buffer, then we return a suitable buffer to the compositor instead of gbm does. */ gbm_tbm_device_set_callback_surface_has_free_buffers(gbm_tbm, __cb_server_gbm_surface_has_free_buffers); gbm_tbm_device_set_callback_surface_lock_front_buffer(gbm_tbm, __cb_server_gbm_surface_lock_front_buffer); gbm_tbm_device_set_callback_surface_release_buffer(gbm_tbm, __cb_server_gbm_surface_release_buffer); - +#endif __tpl_list_init(&wayland_display->proc.comp.cached_buffers); } else @@ -413,12 +423,13 @@ __tpl_wayland_display_fini(tpl_display_t *display) struct gbm_tbm_device *gbm_tbm = (struct gbm_tbm_device *)gbm; if (wayland_display->proc.comp.bound_client_display) - __tpl_wayland_display_unbind_client_display(display, NULL); + __tpl_wayland_display_unbind_client_display(display, NULL); +#ifndef TBM_SURFACE_QUEUE gbm_tbm_device_set_callback_surface_has_free_buffers(gbm_tbm, NULL); gbm_tbm_device_set_callback_surface_lock_front_buffer(gbm_tbm, NULL); gbm_tbm_device_set_callback_surface_release_buffer(gbm_tbm, NULL); - +#endif __tpl_list_fini(&wayland_display->proc.comp.cached_buffers, (tpl_free_func_t) tpl_object_unreference); } @@ -544,6 +555,7 @@ __tpl_wayland_display_get_window_info(tpl_display_t *display, tpl_handle_t windo } else if (wayland_display->type == SERVER) { +#ifndef TBM_SURFACE_QUEUE struct gbm_surface *gbm_surface = (struct gbm_surface *)window; struct gbm_tbm_surface *gbm_tbm_surface = (struct gbm_tbm_surface *)gbm_surface; @@ -559,7 +571,23 @@ __tpl_wayland_display_get_window_info(tpl_display_t *display, tpl_handle_t windo } if (width != NULL) *width = gbm_tbm_surface_get_width(gbm_tbm_surface); if (height != NULL) *height = gbm_tbm_surface_get_height(gbm_tbm_surface); +#else + struct gbm_surface *gbm_surface = (struct gbm_surface *)window; + tbm_surface_queue_h surf_queue = gbm_tbm_get_surface_queue(gbm_surface); + if (format != NULL) + { + switch (tbm_surface_queue_get_format(surf_queue)) + { + case TBM_FORMAT_ARGB8888: *format = TPL_FORMAT_ARGB8888; break; + case TBM_FORMAT_XRGB8888: *format = TPL_FORMAT_XRGB8888; break; + case TBM_FORMAT_RGB565: *format = TPL_FORMAT_RGB565; break; + default: *format = TPL_FORMAT_INVALID; break; + } + } + if (width != NULL) *width = tbm_surface_queue_get_width(surf_queue); + if (height != NULL) *height = tbm_surface_queue_get_height(surf_queue); +#endif return TPL_TRUE; } @@ -655,6 +683,9 @@ __tpl_wayland_surface_init(tpl_surface_t *surface) surface->backend.data = (void *)wayland_surface; wayland_surface->current_back_idx = 0; +#ifdef TBM_SURFACE_QUEUE + wayland_surface->tbm_queue = NULL; +#endif __tpl_list_init(&wayland_surface->done_rendering_queue); wayland_display = (tpl_wayland_display_t*)surface->display->backend.data; @@ -674,6 +705,7 @@ __tpl_wayland_surface_init(tpl_surface_t *surface) } if (wayland_display->type == SERVER) { +#ifndef TBM_SURFACE_QUEUE struct gbm_surface *gbm_surface = surface->native_handle; struct gbm_tbm_surface *gbm_tbm_surface = (struct gbm_tbm_surface *)gbm_surface; gbm_tbm_surface_set_user_data(gbm_tbm_surface, surface); @@ -683,6 +715,10 @@ __tpl_wayland_surface_init(tpl_surface_t *surface) { wayland_surface->back_buffers[i] = NULL; } +#else + struct gbm_surface *gbm_surface = (struct gbm_surface*)surface->native_handle; + wayland_surface->tbm_queue = gbm_tbm_get_surface_queue(gbm_surface); +#endif } if (TPL_TRUE != __tpl_wayland_display_get_window_info(surface->display, surface->native_handle, @@ -821,10 +857,12 @@ __tpl_wayland_surface_fini(tpl_surface_t *surface) if (wayland_display->type == SERVER) { +#ifndef TBM_SURFACE_QUEUE struct gbm_surface *gbm_surface = surface->native_handle; struct gbm_tbm_surface *gbm_tbm_surface = (struct gbm_tbm_surface *)gbm_surface; gbm_tbm_surface_set_user_data(gbm_tbm_surface, NULL); +#endif } } @@ -842,12 +880,13 @@ __tpl_wayland_surface_post(tpl_surface_t *surface, tpl_frame_t *frame) TPL_ASSERT(frame->buffer); tpl_wayland_display_t *wayland_display = (tpl_wayland_display_t*) surface->display->backend.data; + tpl_wayland_buffer_t *wayland_buffer = NULL; TPL_LOG(3, "window(%p, %p)", surface, surface->native_handle); if (wayland_display->type == CLIENT) { - tpl_wayland_buffer_t *wayland_buffer = (tpl_wayland_buffer_t *)frame->buffer->backend.data; + wayland_buffer = (tpl_wayland_buffer_t *)frame->buffer->backend.data; struct wl_egl_window *wl_egl_window = NULL; int i; tbm_bo_handle bo_handle = tbm_bo_get_handle(wayland_buffer->bo , TBM_DEVICE_CPU); @@ -896,6 +935,30 @@ __tpl_wayland_surface_post(tpl_surface_t *surface, tpl_frame_t *frame) TPL_LOG(7, "BO:%d", tbm_bo_export(wayland_buffer->bo)); } +#ifdef TBM_SURFACE_QUEUE + else if (wayland_display->type == SERVER) + { + tpl_wayland_surface_t *wayland_surface = (tpl_wayland_surface_t*)surface->backend.data; + tpl_buffer_t *buffer = NULL; + + if (!__tpl_list_is_empty(&wayland_surface->done_rendering_queue)) + { + buffer = __tpl_list_pop_front(&wayland_surface->done_rendering_queue, NULL); + + TPL_ASSERT(buffer); + + wayland_buffer = (tpl_wayland_buffer_t *) buffer->backend.data; + } + + tbm_surface_internal_unref(wayland_buffer->tbm_surface); + + if (wayland_surface->tbm_queue && wayland_buffer->tbm_surface) + { + tbm_surface_queue_enqueue(wayland_surface->tbm_queue, wayland_buffer->tbm_surface); + TPL_LOG(6, "tbm_surface ENQUEUED!!"); + } + } +#endif } static tpl_bool_t @@ -932,6 +995,7 @@ __tpl_wayland_surface_begin_frame(tpl_surface_t *surface) TPL_OBJECT_LOCK(surface); } +#ifndef TBM_SURFACE_QUEUE else if (wayland_display->type == SERVER) { while (__tpl_wayland_surface_get_idle_buffer_idx(wayland_surface, TPL_BUFFER_ALLOC_SIZE_COMPOSITOR) == -1) @@ -942,10 +1006,12 @@ __tpl_wayland_surface_begin_frame(tpl_surface_t *surface) TPL_OBJECT_LOCK(surface); } } +#else + if (wayland_display->type == CLIENT) +#endif + wayland_surface->current_rendering_buffer = wayland_surface->back_buffers[wayland_surface->current_back_idx]; - wayland_surface->current_rendering_buffer = wayland_surface->back_buffers[wayland_surface->current_back_idx]; - - if ( wayland_surface->current_rendering_buffer ) + if ( wayland_display->type == CLIENT && wayland_surface->current_rendering_buffer ) { tpl_wayland_buffer_t *wayland_buffer = (tpl_wayland_buffer_t*)wayland_surface->current_rendering_buffer->backend.data; wayland_buffer->status = BUSY; @@ -1276,8 +1342,12 @@ __tpl_wayland_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl tpl_buffer_t *buffer = NULL; tpl_wayland_buffer_t *wayland_buffer = NULL; tbm_bo bo; +#ifdef TBM_SURFACE_QUEUE + tbm_surface_h tbm_surface = NULL; + tbm_surface_queue_error_e tsq_err = 0; +#endif tbm_bo_handle bo_handle; - int width, height, depth, stride; + int width, height, depth, stride, size, offset; tpl_format_t format; tpl_wayland_surface_t *wayland_surface; @@ -1285,12 +1355,13 @@ __tpl_wayland_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl struct gbm_tbm_surface *gbm_tbm_surface; struct gbm_bo *gbm_bo = NULL; struct gbm_tbm_bo *gbm_tbm_bo = NULL; - + struct gbm_surface *gbm_surface = NULL; TPL_ASSERT(surface); TPL_ASSERT(surface->native_handle); TPL_ASSERT(surface->display); TPL_ASSERT(surface->display->native_handle); +#ifndef TBM_SURFACE_QUEUE gbm = (struct gbm_device *)surface->display->native_handle; gbm_tbm_surface = (struct gbm_tbm_surface *) surface->native_handle; @@ -1361,6 +1432,92 @@ __tpl_wayland_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl TPL_LOG(3, "buffer:%p gbm_bo:%p bo_hnd:%d, %dx%d", buffer, gbm_bo, (int) bo_handle.u32, width, height); return buffer; +#else + gbm_surface = (struct gbm_surface*) surface->native_handle; + wayland_surface = (tpl_wayland_surface_t*)surface->backend.data; + + tsq_err = tbm_surface_queue_dequeue(wayland_surface->tbm_queue, &tbm_surface); + + if (tbm_surface == NULL) + { + TPL_LOG(6, "Wait until dequeable | tsq_err = %d", tsq_err); + tbm_surface_queue_can_dequeue(wayland_surface->tbm_queue, 1); + + tsq_err = tbm_surface_queue_dequeue(wayland_surface->tbm_queue, &tbm_surface); + if (tbm_surface == NULL) + { + TPL_ERR("Failed to get tbm_surface from tbm_surface_queue | tsq_err = %d",tsq_err); + return NULL; + } + } + + tbm_surface_internal_ref(tbm_surface); + + width = tbm_surface_get_width(tbm_surface); + height = tbm_surface_get_height(tbm_surface); + + switch(tbm_surface_get_format(tbm_surface)) + { + case TBM_FORMAT_ARGB8888: format = TPL_FORMAT_ARGB8888; break; + case TBM_FORMAT_XRGB8888: format = TPL_FORMAT_XRGB8888; break; + case TBM_FORMAT_RGB565: format = TPL_FORMAT_RGB565; break; + default: + format = TPL_FORMAT_INVALID; + TPL_ERR("No matched format!!"); + tbm_surface_internal_unref(tbm_surface); + return NULL; + } + + depth = __tpl_wayland_get_depth_from_format(format); + + /* Get pitch stride from tbm_surface */ + tbm_surface_internal_get_plane_data(tbm_surface, 0, &size, &offset, &stride); + + if ((bo = tbm_surface_internal_get_bo(tbm_surface, 0)) == NULL) + { + TPL_ERR("Failed to get tbm_bo from tbm_surface"); + tbm_surface_internal_unref(tbm_surface); + return NULL; + } + + /* Create tpl buffer. */ + bo_handle = tbm_bo_get_handle(bo, TBM_DEVICE_3D); + + buffer = __tpl_buffer_alloc(surface, (size_t) bo_handle.u32, + (int)bo_handle.u32, width, height, depth, stride); + + if (buffer == NULL) + { + TPL_ERR("Failed to allocate tpl buffer | surf:%p bo_hnd:%d WxHxD:%dx%dx%d", + surface, (int) bo_handle.u32, width, height, depth); + tbm_surface_internal_unref(tbm_surface); + return NULL; + } + + wayland_buffer = (tpl_wayland_buffer_t *) calloc(1, sizeof(tpl_wayland_buffer_t)); + if (wayland_buffer == NULL) + { + TPL_ERR("Mem alloc for wayland_buffer failed!"); + tbm_surface_internal_unref(tbm_surface); + tpl_object_unreference((tpl_object_t *) buffer); + return NULL; + } + + buffer->backend.data = (void *)wayland_buffer; + + /* Post process */ + wayland_buffer->display = surface->display; + wayland_buffer->bo = bo; + wayland_buffer->tbm_surface = tbm_surface; + wayland_buffer->proc.comp.gbm_bo = gbm_bo; + + if (reset_buffers != NULL) + *reset_buffers = TPL_FALSE; + + TPL_LOG(3, "buffer:%p bo_hnd:%d, %dx%d", buffer, (int) bo_handle.u32, width, height); + + return buffer; +#endif } #ifndef TPL_USING_WAYLAND_TBM @@ -1733,6 +1890,7 @@ __tpl_wayland_buffer_fini(tpl_buffer_t *buffer) wl_buffer_destroy((void *)wayland_buffer->proc.app.wl_proxy); #endif } +#ifndef TBM_SURFACE_QUEUE if (wayland_display->type == SERVER) { if (wayland_buffer->proc.comp.gbm_bo != NULL) @@ -1740,7 +1898,7 @@ __tpl_wayland_buffer_fini(tpl_buffer_t *buffer) gbm_bo_destroy(wayland_buffer->proc.comp.gbm_bo); } } - +#endif buffer->backend.data = NULL; free(wayland_buffer); } @@ -2127,6 +2285,7 @@ static const struct wl_buffer_listener buffer_release_listener = { (void *)__cb_client_buffer_release_callback, }; +#ifndef TBM_SURFACE_QUEUE static struct gbm_bo * __cb_server_gbm_surface_lock_front_buffer(struct gbm_surface *gbm_surf) { @@ -2271,6 +2430,8 @@ __cb_server_gbm_surface_has_free_buffers(struct gbm_surface *gbm_surf) return 0; } +#endif + #ifndef TPL_USING_WAYLAND_TBM static struct wayland_drm_callbacks wl_drm_server_listener; -- 2.7.4 From 457654ba55a696624a7cfe95d85c810f963b165f Mon Sep 17 00:00:00 2001 From: "Mun, Gwan-gyeong" Date: Wed, 2 Dec 2015 17:20:58 +0900 Subject: [PATCH 03/16] Add arm architecture build feature : ARM_ATOMIC_OPERATION Change-Id: I395898836f364e7d3b13b1005aa9090972cbc996 --- Makefile | 4 ++++ packaging/libtpl-egl.spec | 4 ++++ src/tpl_utils.h | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/Makefile b/Makefile index 514eaff..b3e6c61 100644 --- a/Makefile +++ b/Makefile @@ -51,6 +51,10 @@ ifneq ($(call is-feature-enabled,pngdump),) LDFLAGS += `pkg-config libpng` endif +ifneq ($(call is-feature-enabled,arm_atomic_operation),) + CFLAGS += -DARM_ATOMIC_OPERATION +endif + TPL_HEADERS += $(SRC_DIR)/tpl.h TPL_HEADERS += $(SRC_DIR)/tpl_internal.h TPL_HEADERS += $(SRC_DIR)/tpl_utils.h diff --git a/packaging/libtpl-egl.spec b/packaging/libtpl-egl.spec index d822a43..beab6ca 100644 --- a/packaging/libtpl-egl.spec +++ b/packaging/libtpl-egl.spec @@ -136,6 +136,10 @@ TPL_OPTIONS=${TPL_OPTIONS}-dlog TPL_OPTIONS=${TPL_OPTIONS}-pngdump %endif +%ifarch %arm aarch64 +TPL_OPTIONS=${TPL_OPTIONS}-arm_atomic_operation +%endif + TPL_OPTIONS=${TPL_OPTIONS}-egl_bind_wl_display # do not change the following line diff --git a/src/tpl_utils.h b/src/tpl_utils.h index f22a03c..28cbd55 100644 --- a/src/tpl_utils.h +++ b/src/tpl_utils.h @@ -11,7 +11,11 @@ #define TPL_INLINE __inline__ #define TPL_IGNORE(x) (void)x +#ifdef ARM_ATOMIC_OPERATION #define TPL_DMB() __asm__ volatile("dmb sy" : : : "memory") +#else +#define TPL_DMB() +#endif #if (TTRACE_ENABLE) #include -- 2.7.4 From dfb6853236b47e001386ffe60632a2297090b37c Mon Sep 17 00:00:00 2001 From: Sangjin Lee Date: Fri, 4 Dec 2015 21:17:10 +0900 Subject: [PATCH 04/16] tpl_wayland: Fix memory leak Change-Id: I9765c65c40e297d4cb8f488def5db29920b80516 Signed-off-by: Sangjin Lee --- packaging/libtpl-egl.spec | 2 +- src/tpl_wayland.c | 65 +++++++++++++++++++++++++++++++++++++---------- 2 files changed, 52 insertions(+), 15 deletions(-) diff --git a/packaging/libtpl-egl.spec b/packaging/libtpl-egl.spec index 34eb7a3..9d6ed77 100644 --- a/packaging/libtpl-egl.spec +++ b/packaging/libtpl-egl.spec @@ -13,7 +13,7 @@ %define ENABLE_DLOG 0 %define ENABLE_PNG_DUMP 0 %define ENABLE_WL_TBM 1 -%define ENABLE_TBM_SURFACE_QUEUE 0 +%define ENABLE_TBM_SURFACE_QUEUE 1 #WAYLAND-EGL VERSION MACROS %define WL_EGL_VERSION 1.0.0 diff --git a/src/tpl_wayland.c b/src/tpl_wayland.c index 19702fa..a4e733b 100644 --- a/src/tpl_wayland.c +++ b/src/tpl_wayland.c @@ -102,6 +102,7 @@ struct _tpl_wayland_buffer tbm_surface_h tbm_surface; tbm_bo bo; int reused; + tpl_buffer_t *tpl_buffer; enum wayland_buffer_status status; union @@ -1336,6 +1337,33 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool return buffer; } +#ifdef TBM_SURFACE_QUEUE +static int tpl_buffer_key; +#define KEY_TPL_BUFFER (unsigned long)(&tpl_buffer_key) + +static inline tpl_buffer_t * +__tpl_wayland_surface_get_buffer_from_tbm_surface(tbm_surface_h surface) +{ + tbm_bo bo; + tpl_buffer_t* buf=NULL; + + bo = tbm_surface_internal_get_bo(surface, 0); + tbm_bo_get_user_data(bo, KEY_TPL_BUFFER, (void **)&buf); + + return buf; +} + +static inline void +__tpl_wayland_buffer_set_tbm_surface(tbm_surface_h surface, tpl_buffer_t *buf) +{ + tbm_bo bo; + + bo = tbm_surface_internal_get_bo(surface, 0); + tbm_bo_add_user_data(bo, KEY_TPL_BUFFER, NULL); + tbm_bo_set_user_data(bo, KEY_TPL_BUFFER, buf); +} +#endif + static tpl_buffer_t * __tpl_wayland_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl_bool_t *reset_buffers) { @@ -1437,22 +1465,26 @@ __tpl_wayland_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl wayland_surface = (tpl_wayland_surface_t*)surface->backend.data; tsq_err = tbm_surface_queue_dequeue(wayland_surface->tbm_queue, &tbm_surface); - - if (tbm_surface == NULL) - { - TPL_LOG(6, "Wait until dequeable | tsq_err = %d", tsq_err); - tbm_surface_queue_can_dequeue(wayland_surface->tbm_queue, 1); - - tsq_err = tbm_surface_queue_dequeue(wayland_surface->tbm_queue, &tbm_surface); - if (tbm_surface == NULL) - { - TPL_ERR("Failed to get tbm_surface from tbm_surface_queue | tsq_err = %d",tsq_err); - return NULL; - } - } - + if (tbm_surface == NULL) + { + TPL_LOG(6, "Wait until dequeable | tsq_err = %d", tsq_err); + tbm_surface_queue_can_dequeue(wayland_surface->tbm_queue, 1); + + tsq_err = tbm_surface_queue_dequeue(wayland_surface->tbm_queue, &tbm_surface); + if (tbm_surface == NULL) + { + TPL_ERR("Failed to get tbm_surface from tbm_surface_queue | tsq_err = %d",tsq_err); + return NULL; + } + } tbm_surface_internal_ref(tbm_surface); + buffer = __tpl_wayland_surface_get_buffer_from_tbm_surface(tbm_surface); + if (buffer) + { + return buffer; + } + width = tbm_surface_get_width(tbm_surface); height = tbm_surface_get_height(tbm_surface); @@ -1515,6 +1547,7 @@ __tpl_wayland_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl *reset_buffers = TPL_FALSE; TPL_LOG(3, "buffer:%p bo_hnd:%d, %dx%d", buffer, (int) bo_handle.u32, width, height); + __tpl_wayland_buffer_set_tbm_surface(tbm_surface, buffer); return buffer; #endif @@ -1631,12 +1664,15 @@ __tpl_wayland_buffer_destroy_notify(struct wl_listener *listener, void *data) tpl_wayland_display_t *wayland_display; tpl_wayland_buffer_t *wayland_buffer = NULL; size_t key = 0; + int ref; wayland_buffer = wl_container_of(listener, wayland_buffer, proc.comp.destroy_listener); display = wayland_buffer->display; key = tbm_bo_export(wayland_buffer->bo); wayland_display = (tpl_wayland_display_t *)display->backend.data; __tpl_wayland_surface_buffer_cache_remove(&wayland_display->proc.comp.cached_buffers, key); + + while( 0 < (ref = tpl_object_unreference(wayland_buffer->tpl_buffer))); } static tpl_buffer_t * @@ -1722,6 +1758,7 @@ __tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool wayland_buffer->display = surface->display; wayland_buffer->bo = bo; wayland_buffer->tbm_surface = tbm_surface; + wayland_buffer->tpl_buffer = buffer; buffer->backend.data = (void *)wayland_buffer; buffer->key = key; -- 2.7.4 From a826e0979dfa9590d3ef42ec38bdbfa9eff752e5 Mon Sep 17 00:00:00 2001 From: "Mun, Gwan-gyeong" Date: Tue, 8 Dec 2015 16:44:23 +0900 Subject: [PATCH 05/16] TPL_WAYLAND: replace tbm_surface_get_info() to tbm_surface_internal_get_plane_data() for non supportig hw of gem memory size get. Change-Id: I4569715e00f35468a8d775b4909950b78f0220e5 --- src/tpl_wayland.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/tpl_wayland.c b/src/tpl_wayland.c index a4e733b..f5f6aa4 100644 --- a/src/tpl_wayland.c +++ b/src/tpl_wayland.c @@ -1108,15 +1108,19 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool tpl_wayland_surface_t *wayland_surface = NULL; tbm_bo bo; tbm_bo_handle bo_handle; - int width, height, depth, stride; + int width, height, depth, stride, size, offset; tpl_format_t format; tpl_wayland_display_t *wayland_display; #ifdef TPL_USING_WAYLAND_TBM tbm_surface_h tbm_surface = NULL; +/* TODO: If HW support getting of gem memory size, + use tbm_surface_get_info() with tbm_surface_info_s */ +#if 0 tbm_surface_info_s tbm_surf_info; #endif +#endif struct wl_proxy *wl_proxy = NULL; unsigned int name = -1; uint32_t wl_format = 0; @@ -1184,13 +1188,22 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool tbm_surface_destroy(tbm_surface); return NULL; } - + /* TODO: If HW support getting of gem memory size, + then replace tbm_surface_internal_get_plane_data() to tbm_surface_get_info() */ +#if 0 if (tbm_surface_get_info(tbm_surface, &tbm_surf_info) != 0) { TPL_ERR("Failed to get tbm_surface info!"); return NULL; } stride = tbm_surf_info.planes[0].stride; +#else + if (!tbm_surface_internal_get_plane_data(tbm_surface, 0, &size, &offset, &stride)) + { + TPL_ERR("Failed to get tbm_surface stride info!"); + return NULL; + } +#endif name = tbm_bo_export(bo); TPL_LOG(7, "Client back buffer is new alloced | BO:%d",name); @@ -1681,11 +1694,15 @@ __tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool tpl_buffer_t *buffer = NULL; tpl_wayland_buffer_t *wayland_buffer = NULL; tbm_surface_h tbm_surface = NULL; + /* TODO: If HW support getting of gem memory size, + use tbm_surface_get_info() with tbm_surface_info_s */ +#if 0 tbm_surface_info_s tbm_surf_info; +#endif tbm_bo bo; tbm_bo_handle bo_handle; - int width = 0, height = 0, depth, stride; + int width = 0, height = 0, depth, stride, size, offset; tpl_format_t format = TPL_FORMAT_INVALID; size_t key = 0; @@ -1721,15 +1738,23 @@ __tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool TPL_ERR("Failed to get pixmap info!"); return NULL; } - + /* TODO: If HW support getting of gem memory size, + then replace tbm_surface_internal_get_plane_data() to tbm_surface_get_info() */ +#if 0 if (tbm_surface_get_info(tbm_surface, &tbm_surf_info) != 0) { TPL_ERR("Failed to get stride info!"); return NULL; } - - depth = __tpl_wayland_get_depth_from_format(format); stride = tbm_surf_info.planes[0].stride; +#else + if (!tbm_surface_internal_get_plane_data(tbm_surface, 0, &size, &offset, &stride)) + { + TPL_ERR("Failed to get tbm_surface stride info!"); + return NULL; + } +#endif + depth = __tpl_wayland_get_depth_from_format(format); /* Create tpl buffer. */ bo_handle = tbm_bo_get_handle(bo, TBM_DEVICE_3D); -- 2.7.4 From c362e3431ef7ce751b3a7a38b9e8460f6c0b118d Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Mon, 7 Dec 2015 14:40:32 +0900 Subject: [PATCH 06/16] Delete unnecessary code about wayland-drm. - Change default protocol of wl_buffer wayland-drm to wayland-tbm. - Delete build dependency about libwayland-drm. - Delete unnecessary and unused code. Change-Id: I3c47d646642cca0afb0b12b3332947b8d06f766a --- Makefile | 11 +- packaging/libtpl-egl.spec | 12 - src/tpl_wayland.c | 986 +++------------------------------------------- 3 files changed, 50 insertions(+), 959 deletions(-) diff --git a/Makefile b/Makefile index c9e26ec..0e4a537 100644 --- a/Makefile +++ b/Makefile @@ -29,16 +29,7 @@ endif ifneq ($(call is-feature-enabled,winsys_wl),) CFLAGS += -DTPL_WINSYS_WL -DEGL_BIND_WL_DISPLAY CFLAGS += `pkg-config --cflags gbm` - LDFLAGS += `pkg-config --libs gbm` -ifneq ($(call is-feature-enabled,wl_tbm),) - LDFLAGS += `pkg-config --libs wayland-tbm-client wayland-tbm-server` - CFLAGS += -DTPL_USING_WAYLAND_TBM -else - LDFLAGS += `pkg-config --libs wayland-drm` -endif -ifneq ($(call is-feature-enabled,tbm_surface_queue),) - CFLAGS += -DTBM_SURFACE_QUEUE -endif + LDFLAGS += `pkg-config --libs gbm wayland-tbm-client wayland-tbm-server` endif ifneq ($(call is-feature-enabled,ttrace),) diff --git a/packaging/libtpl-egl.spec b/packaging/libtpl-egl.spec index 607edd5..b047e4c 100644 --- a/packaging/libtpl-egl.spec +++ b/packaging/libtpl-egl.spec @@ -12,8 +12,6 @@ %define ENABLE_TTRACE 0 %define ENABLE_DLOG 0 %define ENABLE_PNG_DUMP 0 -%define ENABLE_WL_TBM 1 -%define ENABLE_TBM_SURFACE_QUEUE 1 #WAYLAND-EGL VERSION MACROS %define WL_EGL_VERSION 1.0.0 @@ -60,12 +58,8 @@ BuildRequires: pkgconfig(xshmfence) BuildRequires: libtool BuildRequires: wayland-devel BuildRequires: pkgconfig(gbm) -%if "%{ENABLE_WL_TBM}" == "1" BuildRequires: pkgconfig(wayland-tbm-client) BuildRequires: pkgconfig(wayland-tbm-server) -%else -BuildRequires: pkgconfig(wayland-drm) -%endif %endif %if "%{ENABLE_PNG_DUMP}" == "1" @@ -119,12 +113,6 @@ TPL_OPTIONS=${TPL_OPTIONS}-winsys_dri3 %endif %if "%{TPL_WINSYS}" == "WL" TPL_OPTIONS=${TPL_OPTIONS}-winsys_wl -%if "%{ENABLE_WL_TBM}" == "1" -TPL_OPTIONS=${TPL_OPTIONS}-wl_tbm -%endif -%if "%{ENABLE_TBM_SURFACE_QUEUE}" == "1" -TPL_OPTIONS=${TPL_OPTIONS}-tbm_surface_queue -%endif %endif %if "%{ENABLE_TTRACE}" == "1" diff --git a/src/tpl_wayland.c b/src/tpl_wayland.c index f5f6aa4..a7d88ed 100644 --- a/src/tpl_wayland.c +++ b/src/tpl_wayland.c @@ -2,11 +2,6 @@ #include -#ifndef TPL_USING_WAYLAND_TBM -#include -#include -#endif - #include "wayland-egl/wayland-egl-priv.h" #include @@ -24,23 +19,16 @@ #include #include -/* In wayland, application and compositor create its own drawing buffers. Recommend size is more than 2. */ -#define TPL_BUFFER_ALLOC_SIZE_APP 3 -#define TPL_BUFFER_ALLOC_SIZE_COMPOSITOR 4 -#define TPL_BUFFER_ALLOC_SIZE_MAX (((TPL_BUFFER_ALLOC_SIZE_APP) > (TPL_BUFFER_ALLOC_SIZE_COMPOSITOR))?(TPL_BUFFER_ALLOC_SIZE_APP):(TPL_BUFFER_ALLOC_SIZE_COMPOSITOR)) -#define TPL_BUFFER_ALLOC_PITCH_ALIGNMENT 64 -#define ALIGN_TO_64BYTE(byte) (((byte) + TPL_BUFFER_ALLOC_PITCH_ALIGNMENT - 1) & ~(TPL_BUFFER_ALLOC_PITCH_ALIGNMENT - 1)) - -#ifdef TPL_USING_WAYLAND_TBM #include #include +#include #include #include -#endif -#ifdef TBM_SURFACE_QUEUE -#include -#endif +/* In wayland, application and compositor create its own drawing buffers. Recommend size is more than 2. */ +#define TPL_BUFFER_ALLOC_SIZE_APP 3 +#define TPL_BUFFER_ALLOC_SIZE_COMPOSITOR 4 +#define TPL_BUFFER_ALLOC_SIZE_MAX (((TPL_BUFFER_ALLOC_SIZE_APP) > (TPL_BUFFER_ALLOC_SIZE_COMPOSITOR))?(TPL_BUFFER_ALLOC_SIZE_APP):(TPL_BUFFER_ALLOC_SIZE_COMPOSITOR)) typedef struct _tpl_wayland_display tpl_wayland_display_t; typedef struct _tpl_wayland_surface tpl_wayland_surface_t; @@ -63,11 +51,7 @@ enum wayland_buffer_status struct _tpl_wayland_display { tbm_bufmgr bufmgr; -#ifdef TPL_USING_WAYLAND_TBM struct wayland_tbm_client *wl_tbm_client; -#else - struct wl_drm *wl_drm; -#endif enum wayland_display_type type; union { @@ -91,9 +75,7 @@ struct _tpl_wayland_surface tpl_list_t done_rendering_queue; int current_back_idx; tpl_buffer_t *back_buffers[TPL_BUFFER_ALLOC_SIZE_MAX]; -#ifdef TBM_SURFACE_QUEUE tbm_surface_queue_h tbm_queue; -#endif }; struct _tpl_wayland_buffer @@ -126,12 +108,6 @@ 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; -#ifndef TBM_SURFACE_QUEUE -static struct gbm_bo *__cb_server_gbm_surface_lock_front_buffer(struct gbm_surface *gbm_surf); -static void __cb_server_gbm_surface_release_buffer(struct gbm_surface *gbm_surf, struct gbm_bo *gbm_bo); -static int __cb_server_gbm_surface_has_free_buffers(struct gbm_surface *gbm_surf); -#endif - #ifdef EGL_BIND_WL_DISPLAY unsigned int __tpl_wayland_display_bind_client_display(tpl_display_t *tpl_display, tpl_handle_t native_dpy); unsigned int __tpl_wayland_display_unbind_client_display(tpl_display_t *tpl_display, tpl_handle_t native_dpy); @@ -139,8 +115,6 @@ unsigned int __tpl_wayland_display_unbind_client_display(tpl_display_t *tpl_dis #define TPL_BUFFER_CACHE_MAX_ENTRIES 40 -static int dump_count = 0; - static TPL_INLINE tpl_bool_t __tpl_wayland_surface_buffer_cache_add(tpl_list_t *buffer_cache, tpl_buffer_t *buffer) { @@ -318,7 +292,6 @@ __tpl_wayland_display_init(tpl_display_t *display) struct wl_display *wl_dpy = (struct wl_display *)display->native_handle; wayland_display->type = CLIENT; -#ifdef TPL_USING_WAYLAND_TBM wayland_display->wl_tbm_client = wayland_tbm_client_init((struct wl_display *) wl_dpy); if (wayland_display->wl_tbm_client == NULL) @@ -336,58 +309,17 @@ __tpl_wayland_display_init(tpl_display_t *display) goto destroy_queue; wl_proxy_set_queue((struct wl_proxy *)wayland_display->proc.app.wl_registry, wayland_display->proc.app.wl_queue); -#else - wayland_display->proc.app.wl_queue = wl_display_create_queue(wl_dpy); - if (NULL == wayland_display->proc.app.wl_queue) - goto free_wl_display; - - wayland_display->proc.app.wl_registry = wl_display_get_registry(wl_dpy); - if (NULL == wayland_display->proc.app.wl_registry) - goto destroy_queue; - - wl_proxy_set_queue((struct wl_proxy *)wayland_display->proc.app.wl_registry, wayland_display->proc.app.wl_queue); - if (0 != wl_registry_add_listener(wayland_display->proc.app.wl_registry, ®istry_listener, display)) - goto reset_queue; - - /* Initialization roundtrip steps */ - if (__tpl_wayland_display_roundtrip(display) < 0 || wayland_display->wl_drm == NULL) - goto reset_queue; - - if (__tpl_wayland_display_roundtrip(display) < 0 || display->bufmgr_fd == -1) - goto reset_queue; - - if (__tpl_wayland_display_roundtrip(display) < 0 || wayland_display->proc.app.authenticated == TPL_FALSE) - goto reset_queue; - - wayland_display->bufmgr = tbm_bufmgr_init(display->bufmgr_fd); - if (NULL == wayland_display->bufmgr) - goto reset_queue; -#endif } else if (__tpl_wayland_display_is_gbm_device(display->native_handle)) { - struct gbm_device *gbm = (struct gbm_device *)display->native_handle; - struct gbm_tbm_device *gbm_tbm = (struct gbm_tbm_device *)gbm; - wayland_display->type = SERVER; -#ifndef TBM_SURFACE_QUEUE - /* Hook gbm backend callbacks. If the compositor calls gbm APIs to get a buffer, - then we return a suitable buffer to the compositor instead of gbm does. */ - gbm_tbm_device_set_callback_surface_has_free_buffers(gbm_tbm, __cb_server_gbm_surface_has_free_buffers); - gbm_tbm_device_set_callback_surface_lock_front_buffer(gbm_tbm, __cb_server_gbm_surface_lock_front_buffer); - gbm_tbm_device_set_callback_surface_release_buffer(gbm_tbm, __cb_server_gbm_surface_release_buffer); -#endif __tpl_list_init(&wayland_display->proc.comp.cached_buffers); } else goto free_wl_display; return TPL_TRUE; -#ifndef TPL_USING_WAYLAND_TBM -reset_queue: - wl_proxy_set_queue((struct wl_proxy *) wayland_display->proc.app.wl_registry, NULL); -#endif destroy_queue: wl_event_queue_destroy(wayland_display->proc.app.wl_queue); free_wl_display: @@ -411,26 +343,13 @@ __tpl_wayland_display_fini(tpl_display_t *display) { if (wayland_display->type == CLIENT) { -#ifdef TPL_USING_WAYLAND_TBM wayland_tbm_client_deinit(wayland_display->wl_tbm_client); -#else - tbm_bufmgr_deinit(wayland_display->bufmgr); - close(display->bufmgr_fd); -#endif } if (wayland_display->type == SERVER) { - struct gbm_device *gbm = (struct gbm_device *)display->native_handle; - struct gbm_tbm_device *gbm_tbm = (struct gbm_tbm_device *)gbm; - if (wayland_display->proc.comp.bound_client_display) __tpl_wayland_display_unbind_client_display(display, NULL); -#ifndef TBM_SURFACE_QUEUE - gbm_tbm_device_set_callback_surface_has_free_buffers(gbm_tbm, NULL); - gbm_tbm_device_set_callback_surface_lock_front_buffer(gbm_tbm, NULL); - gbm_tbm_device_set_callback_surface_release_buffer(gbm_tbm, NULL); -#endif __tpl_list_fini(&wayland_display->proc.comp.cached_buffers, (tpl_free_func_t) tpl_object_unreference); } @@ -458,11 +377,7 @@ __tpl_wayland_display_query_config(tpl_display_t *display, tpl_surface_type_t su { if (wayland_display->type == CLIENT) { -#ifdef TPL_USING_WAYLAND_TBM if (native_visual_id != NULL) *native_visual_id = TBM_FORMAT_ARGB8888; -#else - if (native_visual_id != NULL) *native_visual_id = WL_DRM_FORMAT_ARGB8888; -#endif } else if (wayland_display->type == SERVER && gbm_device_is_format_supported((struct gbm_device *)display->native_handle, @@ -481,11 +396,7 @@ __tpl_wayland_display_query_config(tpl_display_t *display, tpl_surface_type_t su { if (wayland_display->type == CLIENT) { -#ifdef TPL_USING_WAYLAND_TBM if (native_visual_id != NULL) *native_visual_id = TBM_FORMAT_XRGB8888; -#else - if (native_visual_id != NULL) *native_visual_id = WL_DRM_FORMAT_XRGB8888; -#endif } else if (wayland_display->type == SERVER && gbm_device_is_format_supported((struct gbm_device *)display->native_handle, @@ -556,25 +467,8 @@ __tpl_wayland_display_get_window_info(tpl_display_t *display, tpl_handle_t windo } else if (wayland_display->type == SERVER) { -#ifndef TBM_SURFACE_QUEUE - struct gbm_surface *gbm_surface = (struct gbm_surface *)window; - struct gbm_tbm_surface *gbm_tbm_surface = (struct gbm_tbm_surface *)gbm_surface; - - if (format != NULL) - { - switch (gbm_tbm_surface_get_format(gbm_tbm_surface)) - { - case GBM_FORMAT_ARGB8888: *format = TPL_FORMAT_ARGB8888; break; - case GBM_FORMAT_XRGB8888: *format = TPL_FORMAT_XRGB8888; break; - case GBM_FORMAT_RGB565: *format = TPL_FORMAT_RGB565; break; - default: *format = TPL_FORMAT_INVALID; break; - } - } - if (width != NULL) *width = gbm_tbm_surface_get_width(gbm_tbm_surface); - if (height != NULL) *height = gbm_tbm_surface_get_height(gbm_tbm_surface); -#else struct gbm_surface *gbm_surface = (struct gbm_surface *)window; - tbm_surface_queue_h surf_queue = gbm_tbm_get_surface_queue(gbm_surface); + tbm_surface_queue_h surf_queue = (tbm_surface_queue_h)gbm_tbm_get_surface_queue(gbm_surface); if (format != NULL) { @@ -588,7 +482,6 @@ __tpl_wayland_display_get_window_info(tpl_display_t *display, tpl_handle_t windo } if (width != NULL) *width = tbm_surface_queue_get_width(surf_queue); if (height != NULL) *height = tbm_surface_queue_get_height(surf_queue); -#endif return TPL_TRUE; } @@ -599,7 +492,6 @@ static tpl_bool_t __tpl_wayland_display_get_pixmap_info(tpl_display_t *display, tpl_handle_t pixmap, int *width, int *height, tpl_format_t *format) { -#ifdef TPL_USING_WAYLAND_TBM tbm_surface_h tbm_surface = NULL; int tbm_format = -1; @@ -624,40 +516,6 @@ __tpl_wayland_display_get_pixmap_info(tpl_display_t *display, tpl_handle_t pixma } return TPL_TRUE; - -#else - tpl_wayland_display_t *wayland_display; - struct wl_drm_buffer *drm_buffer = NULL; - - TPL_ASSERT(display); - TPL_ASSERT(display->backend.data); - - wayland_display = (tpl_wayland_display_t *)display->backend.data; - - if (wayland_display->wl_drm == NULL) - return TPL_FALSE; - - drm_buffer = wayland_drm_buffer_get(wayland_display->wl_drm, (struct wl_resource *)pixmap); - - if (drm_buffer != NULL) - { - if (format != NULL) - { - switch (drm_buffer->format) - { - case WL_DRM_FORMAT_ARGB8888: *format = TPL_FORMAT_ARGB8888; break; - case WL_DRM_FORMAT_XRGB8888: *format = TPL_FORMAT_XRGB8888; break; - case WL_DRM_FORMAT_RGB565: *format = TPL_FORMAT_RGB565; break; - default: *format = TPL_FORMAT_INVALID; break; - } - } - if (width != NULL) *width = drm_buffer->width; - if (height != NULL) *height = drm_buffer->height; - - return TPL_TRUE; - } -#endif - return TPL_FALSE; } static void @@ -683,10 +541,8 @@ __tpl_wayland_surface_init(tpl_surface_t *surface) surface->backend.data = (void *)wayland_surface; wayland_surface->current_back_idx = 0; - -#ifdef TBM_SURFACE_QUEUE wayland_surface->tbm_queue = NULL; -#endif + __tpl_list_init(&wayland_surface->done_rendering_queue); wayland_display = (tpl_wayland_display_t*)surface->display->backend.data; @@ -706,20 +562,8 @@ __tpl_wayland_surface_init(tpl_surface_t *surface) } if (wayland_display->type == SERVER) { -#ifndef TBM_SURFACE_QUEUE - struct gbm_surface *gbm_surface = surface->native_handle; - struct gbm_tbm_surface *gbm_tbm_surface = (struct gbm_tbm_surface *)gbm_surface; - gbm_tbm_surface_set_user_data(gbm_tbm_surface, surface); - - /* Create renderable buffer queue. Fill with empty(=NULL) buffers. */ - for (i = 0; i < TPL_BUFFER_ALLOC_SIZE_COMPOSITOR; i++) - { - wayland_surface->back_buffers[i] = NULL; - } -#else struct gbm_surface *gbm_surface = (struct gbm_surface*)surface->native_handle; - wayland_surface->tbm_queue = gbm_tbm_get_surface_queue(gbm_surface); -#endif + wayland_surface->tbm_queue = (tbm_surface_queue_h)gbm_tbm_get_surface_queue(gbm_surface); } if (TPL_TRUE != __tpl_wayland_display_get_window_info(surface->display, surface->native_handle, @@ -855,16 +699,6 @@ __tpl_wayland_surface_fini(tpl_surface_t *surface) wl_display_flush(surface->display->native_handle); __tpl_wayland_display_roundtrip(surface->display); } - - if (wayland_display->type == SERVER) - { -#ifndef TBM_SURFACE_QUEUE - struct gbm_surface *gbm_surface = surface->native_handle; - struct gbm_tbm_surface *gbm_tbm_surface = (struct gbm_tbm_surface *)gbm_surface; - - gbm_tbm_surface_set_user_data(gbm_tbm_surface, NULL); -#endif - } } free(wayland_surface); @@ -936,7 +770,6 @@ __tpl_wayland_surface_post(tpl_surface_t *surface, tpl_frame_t *frame) TPL_LOG(7, "BO:%d", tbm_bo_export(wayland_buffer->bo)); } -#ifdef TBM_SURFACE_QUEUE else if (wayland_display->type == SERVER) { tpl_wayland_surface_t *wayland_surface = (tpl_wayland_surface_t*)surface->backend.data; @@ -959,7 +792,6 @@ __tpl_wayland_surface_post(tpl_surface_t *surface, tpl_frame_t *frame) TPL_LOG(6, "tbm_surface ENQUEUED!!"); } } -#endif } static tpl_bool_t @@ -996,20 +828,7 @@ __tpl_wayland_surface_begin_frame(tpl_surface_t *surface) TPL_OBJECT_LOCK(surface); } -#ifndef TBM_SURFACE_QUEUE - else if (wayland_display->type == SERVER) - { - while (__tpl_wayland_surface_get_idle_buffer_idx(wayland_surface, TPL_BUFFER_ALLOC_SIZE_COMPOSITOR) == -1) - { - /* Compositor over-drawed all buffers, but no buffer has done yet. Wait for frame post. */ - TPL_OBJECT_UNLOCK(surface); - __tpl_util_sys_yield(); - TPL_OBJECT_LOCK(surface); - } - } -#else if (wayland_display->type == CLIENT) -#endif wayland_surface->current_rendering_buffer = wayland_surface->back_buffers[wayland_surface->current_back_idx]; if ( wayland_display->type == CLIENT && wayland_surface->current_rendering_buffer ) @@ -1113,14 +932,12 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool tpl_wayland_display_t *wayland_display; -#ifdef TPL_USING_WAYLAND_TBM tbm_surface_h tbm_surface = NULL; /* TODO: If HW support getting of gem memory size, use tbm_surface_get_info() with tbm_surface_info_s */ #if 0 tbm_surface_info_s tbm_surf_info; #endif -#endif struct wl_proxy *wl_proxy = NULL; unsigned int name = -1; uint32_t wl_format = 0; @@ -1140,9 +957,7 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool } depth = __tpl_wayland_get_depth_from_format(format); - stride = ALIGN_TO_64BYTE(width * depth / 8); -#ifdef TPL_USING_WAYLAND_TBM if (surface->format == TPL_FORMAT_INVALID) surface->format = format; @@ -1226,71 +1041,9 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool tpl_object_unreference((tpl_object_t *) buffer); return NULL; } -#else - /* Allocate a buffer */ - bo = tbm_bo_alloc(wayland_display->bufmgr, stride * height, TBM_BO_DEFAULT); - if (NULL == bo) - { - TPL_ERR("TBM bo alloc failed!"); - return NULL; - } - /* Create tpl buffer. */ - bo_handle = tbm_bo_get_handle(bo, TBM_DEVICE_3D); - if (bo_handle.ptr == NULL) - { - TPL_ERR("TBM bo get handle failed!"); - TPL_LOG(7, "TBM bo get handle failed!"); - tbm_bo_unref(bo); - return NULL; - } - - name = tbm_bo_export(bo); - - TPL_LOG(7, "Client back buffer is new alloced | BO:%d",name); - - buffer = __tpl_buffer_alloc(surface, (size_t) name, (int) bo_handle.u32, width, height, depth, stride); - if (NULL == buffer) - { - TPL_ERR("TPL buffer alloc failed!"); - tbm_bo_unref(bo); - return NULL; - } - - wayland_buffer = (tpl_wayland_buffer_t *) calloc(1, sizeof(tpl_wayland_buffer_t)); - if (wayland_buffer == NULL) - { - TPL_ERR("Mem alloc for wayland_buffer failed!"); - tbm_bo_unref(bo); - tpl_object_unreference((tpl_object_t *) buffer); - return NULL; - } - - buffer->backend.data = (void *) wayland_buffer; - surface->format = format; - /* Post process : Create a wl_drm_buffer and notify the buffer to the server. */ - switch (surface->format) - { - case TPL_FORMAT_ARGB8888: - wl_format = WL_DRM_FORMAT_ARGB8888; - break; - case TPL_FORMAT_XRGB8888: - wl_format = WL_DRM_FORMAT_XRGB8888; - break; - case TPL_FORMAT_RGB565: - wl_format = WL_DRM_FORMAT_RGB565; - break; - default: - TPL_ERR("Unsupported format found in surface!"); - tbm_bo_unref(bo); - tpl_object_unreference((tpl_object_t *)buffer); - free(wayland_buffer); - return NULL; - } -#endif buffer->backend.data = (void *) wayland_buffer; -#ifdef TPL_USING_WAYLAND_TBM wl_proxy = (struct wl_proxy *)wayland_tbm_client_create_buffer(wayland_display->wl_tbm_client, tbm_surface); @@ -1306,36 +1059,13 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool wl_proxy_set_queue(wl_proxy, wayland_display->proc.app.wl_queue); wl_buffer_add_listener((void *)wl_proxy, &buffer_release_listener, buffer); -#else - wl_proxy = (struct wl_proxy *) wl_drm_create_buffer(wayland_display->wl_drm, - (uint32_t)name, width, height, stride, wl_format); - - if (wl_proxy == NULL) - { - TPL_ERR("Failed to create DRM buffer!"); - tbm_bo_unref(bo); - tpl_object_unreference((tpl_object_t *)buffer); - free(wayland_buffer); - return NULL; - } - - wl_proxy_set_queue(wl_proxy, wayland_display->proc.app.wl_queue); - wl_buffer_add_listener((void *)wl_proxy, &buffer_release_listener, buffer); -#endif - wl_display_flush((struct wl_display *)surface->display->native_handle); wayland_buffer->display = surface->display; -#ifdef TPL_USING_WAYLAND_TBM wayland_buffer->tbm_surface = tbm_surface; wayland_buffer->proc.app.wl_proxy = wl_proxy; wayland_buffer->bo = bo; -#else - wayland_buffer->bo = bo; - wayland_buffer->proc.app.wl_proxy = wl_proxy; - wayland_buffer->proc.app.resized = TPL_FALSE; -#endif wayland_buffer->status = BUSY; wayland_surface = (tpl_wayland_surface_t*) surface->backend.data; @@ -1350,7 +1080,6 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool return buffer; } -#ifdef TBM_SURFACE_QUEUE static int tpl_buffer_key; #define KEY_TPL_BUFFER (unsigned long)(&tpl_buffer_key) @@ -1375,7 +1104,6 @@ __tpl_wayland_buffer_set_tbm_surface(tbm_surface_h surface, tpl_buffer_t *buf) tbm_bo_add_user_data(bo, KEY_TPL_BUFFER, NULL); tbm_bo_set_user_data(bo, KEY_TPL_BUFFER, buf); } -#endif static tpl_buffer_t * __tpl_wayland_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl_bool_t *reset_buffers) @@ -1383,130 +1111,52 @@ __tpl_wayland_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl tpl_buffer_t *buffer = NULL; tpl_wayland_buffer_t *wayland_buffer = NULL; tbm_bo bo; -#ifdef TBM_SURFACE_QUEUE tbm_surface_h tbm_surface = NULL; tbm_surface_queue_error_e tsq_err = 0; -#endif + tbm_bo_handle bo_handle; - int width, height, depth, stride, size, offset; + int width, height, depth; + uint32_t size, offset, stride; tpl_format_t format; tpl_wayland_surface_t *wayland_surface; - struct gbm_device *gbm; - struct gbm_tbm_surface *gbm_tbm_surface; - struct gbm_bo *gbm_bo = NULL; - struct gbm_tbm_bo *gbm_tbm_bo = NULL; - struct gbm_surface *gbm_surface = NULL; TPL_ASSERT(surface); TPL_ASSERT(surface->native_handle); TPL_ASSERT(surface->display); TPL_ASSERT(surface->display->native_handle); -#ifndef TBM_SURFACE_QUEUE - gbm = (struct gbm_device *)surface->display->native_handle; - gbm_tbm_surface = (struct gbm_tbm_surface *) surface->native_handle; - - if (TPL_TRUE != __tpl_wayland_display_get_window_info(surface->display, surface->native_handle, - &width, &height, &format, 0, 0)) - { - TPL_ERR("Failed to get window info!"); - return NULL; - } - - depth = __tpl_wayland_get_depth_from_format(format); + wayland_surface = (tpl_wayland_surface_t*)surface->backend.data; - /* Allocate a buffer */ - gbm_bo = gbm_bo_create(gbm, width, height, - gbm_tbm_surface_get_format(gbm_tbm_surface), - gbm_tbm_surface_get_flags(gbm_tbm_surface)); - if (gbm_bo == NULL) + tsq_err = tbm_surface_queue_dequeue(wayland_surface->tbm_queue, &tbm_surface); + if (tbm_surface == NULL) { - TPL_ERR("Failed to allocate gbm_bo | gbm:%p %dx%d", gbm, width, height); - return NULL; - } - - gbm_tbm_bo = (struct gbm_tbm_bo *) gbm_bo; - bo = tbm_bo_ref(gbm_tbm_bo_get_tbm_bo(gbm_tbm_bo)); - - /* Get stride info from gbm_tbm_bo */ - stride = gbm_tbm_bo_get_stride(gbm_tbm_bo); + TPL_LOG(6, "Wait until dequeable | tsq_err = %d", tsq_err); + tbm_surface_queue_can_dequeue(wayland_surface->tbm_queue, 1); - /* Create tpl buffer. */ - bo_handle = tbm_bo_get_handle(bo, TBM_DEVICE_3D); - - buffer = __tpl_buffer_alloc(surface, (size_t) bo_handle.u32, - (int)bo_handle.u32, width, height, depth, stride); - if (buffer == NULL) - { - TPL_ERR("Failed to allocate tpl buffer | surf:%p bo_hnd:%d WxHxD:%dx%dx%d", - surface, (int) bo_handle.u32, width, height, depth); - tbm_bo_unref(bo); - return NULL; + tsq_err = tbm_surface_queue_dequeue(wayland_surface->tbm_queue, &tbm_surface); + if (tbm_surface == NULL) + { + TPL_ERR("Failed to get tbm_surface from tbm_surface_queue | tsq_err = %d",tsq_err); + return NULL; + } } + tbm_surface_internal_ref(tbm_surface); - wayland_buffer = (tpl_wayland_buffer_t *) calloc(1, sizeof(tpl_wayland_buffer_t)); - if (wayland_buffer == NULL) + buffer = __tpl_wayland_surface_get_buffer_from_tbm_surface(tbm_surface); + if (buffer) { - TPL_ERR("Mem alloc for wayland_buffer failed!"); - tbm_bo_unref(bo); - tpl_object_unreference((tpl_object_t *) buffer); - return NULL; + return buffer; } - buffer->backend.data = (void *)wayland_buffer; - - wayland_surface = (tpl_wayland_surface_t*)surface->backend.data; - if (wayland_surface) - { - wayland_surface->back_buffers[wayland_surface->current_back_idx] = buffer; - wayland_buffer->status = BUSY; - } - - /* Post process */ - wayland_buffer->display = surface->display; - wayland_buffer->bo = bo; - wayland_buffer->proc.comp.gbm_bo = gbm_bo; - - if (reset_buffers != NULL) - *reset_buffers = TPL_FALSE; - - TPL_LOG(3, "buffer:%p gbm_bo:%p bo_hnd:%d, %dx%d", buffer, gbm_bo, (int) bo_handle.u32, width, height); - - return buffer; -#else - gbm_surface = (struct gbm_surface*) surface->native_handle; - wayland_surface = (tpl_wayland_surface_t*)surface->backend.data; - - tsq_err = tbm_surface_queue_dequeue(wayland_surface->tbm_queue, &tbm_surface); - if (tbm_surface == NULL) - { - TPL_LOG(6, "Wait until dequeable | tsq_err = %d", tsq_err); - tbm_surface_queue_can_dequeue(wayland_surface->tbm_queue, 1); - - tsq_err = tbm_surface_queue_dequeue(wayland_surface->tbm_queue, &tbm_surface); - if (tbm_surface == NULL) - { - TPL_ERR("Failed to get tbm_surface from tbm_surface_queue | tsq_err = %d",tsq_err); - return NULL; - } - } - tbm_surface_internal_ref(tbm_surface); - - buffer = __tpl_wayland_surface_get_buffer_from_tbm_surface(tbm_surface); - if (buffer) - { - return buffer; - } - width = tbm_surface_get_width(tbm_surface); height = tbm_surface_get_height(tbm_surface); switch(tbm_surface_get_format(tbm_surface)) { - case TBM_FORMAT_ARGB8888: format = TPL_FORMAT_ARGB8888; break; - case TBM_FORMAT_XRGB8888: format = TPL_FORMAT_XRGB8888; break; - case TBM_FORMAT_RGB565: format = TPL_FORMAT_RGB565; break; - default: + case TBM_FORMAT_ARGB8888: format = TPL_FORMAT_ARGB8888; break; + case TBM_FORMAT_XRGB8888: format = TPL_FORMAT_XRGB8888; break; + case TBM_FORMAT_RGB565: format = TPL_FORMAT_RGB565; break; + default: format = TPL_FORMAT_INVALID; TPL_ERR("No matched format!!"); tbm_surface_internal_unref(tbm_surface); @@ -1554,139 +1204,33 @@ __tpl_wayland_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl wayland_buffer->display = surface->display; wayland_buffer->bo = bo; wayland_buffer->tbm_surface = tbm_surface; - wayland_buffer->proc.comp.gbm_bo = gbm_bo; if (reset_buffers != NULL) *reset_buffers = TPL_FALSE; TPL_LOG(3, "buffer:%p bo_hnd:%d, %dx%d", buffer, (int) bo_handle.u32, width, height); - __tpl_wayland_buffer_set_tbm_surface(tbm_surface, buffer); + __tpl_wayland_buffer_set_tbm_surface(tbm_surface, buffer); return buffer; -#endif } -#ifndef TPL_USING_WAYLAND_TBM -static tpl_buffer_t * -__tpl_wayland_surface_create_buffer_from_wl_drm(tpl_surface_t *surface, tpl_bool_t *reset_buffers) +static void +__tpl_wayland_buffer_destroy_notify(struct wl_listener *listener, void *data) { - tpl_buffer_t *buffer = NULL; + tpl_display_t *display; + tpl_wayland_display_t *wayland_display; tpl_wayland_buffer_t *wayland_buffer = NULL; - tbm_bo bo; - tbm_bo_handle bo_handle; - int width = 0, height = 0, depth, stride; - tpl_format_t format = TPL_FORMAT_INVALID; size_t key = 0; + int ref; - tpl_wayland_display_t *wayland_display; - struct wl_drm_buffer *drm_buffer = NULL; + wayland_buffer = wl_container_of(listener, wayland_buffer, proc.comp.destroy_listener); + display = wayland_buffer->display; + key = tbm_bo_export(wayland_buffer->bo); + wayland_display = (tpl_wayland_display_t *)display->backend.data; + __tpl_wayland_surface_buffer_cache_remove(&wayland_display->proc.comp.cached_buffers, key); - TPL_ASSERT(surface); - TPL_ASSERT(surface->display); - - wayland_display = (tpl_wayland_display_t *) surface->display->backend.data; - - TPL_ASSERT(wayland_display->wl_drm); - /* Get the allocated buffer */ - drm_buffer = wayland_drm_buffer_get(wayland_display->wl_drm, (struct wl_resource *)surface->native_handle); - if (NULL == drm_buffer) - { - TPL_ERR("Failed to get DRM buffer!"); - return NULL; - } - - buffer = __tpl_wayland_surface_buffer_cache_find(&wayland_display->proc.comp.cached_buffers, (size_t) drm_buffer); - if (buffer != NULL) - { - __tpl_buffer_set_surface(buffer, surface); - tpl_object_reference((tpl_object_t *) buffer); - } - else - { - if (TPL_TRUE != __tpl_wayland_display_get_pixmap_info(surface->display, surface->native_handle, - &width, &height, &format)) - { - TPL_ERR("Failed to get window info!"); - return NULL; - } - - depth = 32; /* TPL_FORMAT_GET_DEPTH(format); */ - stride = drm_buffer->stride[0]; - - bo = (tbm_bo)wayland_drm_buffer_get_buffer(drm_buffer); - if (NULL == bo) - { - TPL_ERR("Failed to reference bo!"); - return NULL; - } - - /* Create tpl buffer. */ - bo_handle = tbm_bo_get_handle(bo, TBM_DEVICE_3D); - if (NULL == bo_handle.ptr) - { - TPL_ERR("Failed to get bo handle!"); - tbm_bo_unref(bo); - return NULL; - } - - key = (size_t) drm_buffer; - buffer = __tpl_buffer_alloc(surface, key, - (int) bo_handle.u32, width, height, depth, stride); - if (buffer == NULL) - { - TPL_ERR("Failed to alloc TPL buffer!"); - tbm_bo_unref(bo); - return NULL; - } - - wayland_buffer = (tpl_wayland_buffer_t *) calloc(1, sizeof(tpl_wayland_buffer_t)); - if (wayland_buffer == NULL) - { - TPL_ERR("Mem alloc failed for wayland buffer!"); - tbm_bo_unref(bo); - tpl_object_unreference((tpl_object_t *) buffer); - return NULL; - } - buffer->backend.data = (void *)wayland_buffer; - - /* Post process */ - wayland_buffer->display = surface->display; - wayland_buffer->bo = bo; - buffer->key = key; - - if (TPL_TRUE != __tpl_wayland_surface_buffer_cache_add(&wayland_display->proc.comp.cached_buffers, buffer)) - { - TPL_ERR("Adding surface to buffer cache failed!"); - tbm_bo_unref(bo); - tpl_object_unreference((tpl_object_t *) buffer); - free(wayland_buffer); - return NULL; - } - } - - if (reset_buffers != NULL) - *reset_buffers = TPL_FALSE; - - return buffer; -} -#else -static void -__tpl_wayland_buffer_destroy_notify(struct wl_listener *listener, void *data) -{ - tpl_display_t *display; - tpl_wayland_display_t *wayland_display; - tpl_wayland_buffer_t *wayland_buffer = NULL; - size_t key = 0; - int ref; - - wayland_buffer = wl_container_of(listener, wayland_buffer, proc.comp.destroy_listener); - display = wayland_buffer->display; - key = tbm_bo_export(wayland_buffer->bo); - wayland_display = (tpl_wayland_display_t *)display->backend.data; - __tpl_wayland_surface_buffer_cache_remove(&wayland_display->proc.comp.cached_buffers, key); - - while( 0 < (ref = tpl_object_unreference(wayland_buffer->tpl_buffer))); -} + while( 0 < (ref = tpl_object_unreference((tpl_object_t*)wayland_buffer->tpl_buffer))); +} static tpl_buffer_t * __tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool_t *reset_buffers) @@ -1695,14 +1239,15 @@ __tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool tpl_wayland_buffer_t *wayland_buffer = NULL; tbm_surface_h tbm_surface = NULL; /* TODO: If HW support getting of gem memory size, - use tbm_surface_get_info() with tbm_surface_info_s */ + use tbm_surface_get_info() with tbm_surface_info_s */ #if 0 tbm_surface_info_s tbm_surf_info; #endif tbm_bo bo; tbm_bo_handle bo_handle; - int width = 0, height = 0, depth, stride, size, offset; + int width = 0, height = 0, depth; + uint32_t size, offset, stride; tpl_format_t format = TPL_FORMAT_INVALID; size_t key = 0; @@ -1739,7 +1284,7 @@ __tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool return NULL; } /* TODO: If HW support getting of gem memory size, - then replace tbm_surface_internal_get_plane_data() to tbm_surface_get_info() */ + then replace tbm_surface_internal_get_plane_data() to tbm_surface_get_info() */ #if 0 if (tbm_surface_get_info(tbm_surface, &tbm_surf_info) != 0) { @@ -1805,35 +1350,8 @@ __tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool return buffer; } -#endif static tpl_buffer_t * -__tpl_wayland_surface_get_buffer_from_tbm_bo(tpl_surface_t *surface, tbm_bo bo, int num_max_back_buf) -{ - tpl_wayland_surface_t *wayland_surface = NULL; - tpl_buffer_t *tpl_buffer = NULL; - tpl_wayland_buffer_t *wayland_buffer = NULL; - int i = 0; - - TPL_ASSERT(surface); - TPL_ASSERT(bo); - - wayland_surface = (tpl_wayland_surface_t*) surface->backend.data; - - for (i = 0; i < num_max_back_buf; i++) - { - tpl_buffer = wayland_surface->back_buffers[i]; - if (tpl_buffer) - { - wayland_buffer = (tpl_wayland_buffer_t*)tpl_buffer->backend.data; - if (tbm_bo_export(bo) == tbm_bo_export(wayland_buffer->bo)) - return tpl_buffer; - } - } - return NULL; - -} -static tpl_buffer_t * __tpl_wayland_surface_get_buffer(tpl_surface_t *surface, tpl_bool_t *reset_buffers) { int width, height; @@ -1891,13 +1409,8 @@ __tpl_wayland_surface_get_buffer(tpl_surface_t *surface, tpl_bool_t *reset_buffe } if (surface->type == TPL_SURFACE_TYPE_PIXMAP) { -#ifdef TPL_USING_WAYLAND_TBM wayland_surface->current_rendering_buffer = __tpl_wayland_surface_create_buffer_from_wl_tbm(surface, reset_buffers); -#else - wayland_surface->current_rendering_buffer = - __tpl_wayland_surface_create_buffer_from_wl_drm(surface, reset_buffers); -#endif } TPL_LOG(3, "window(%p, %p), current(%p)", surface, surface->native_handle, wayland_surface->current_rendering_buffer); @@ -1946,21 +1459,9 @@ __tpl_wayland_buffer_fini(tpl_buffer_t *buffer) wl_display_flush((struct wl_display *)wayland_buffer->display->native_handle); if (wayland_buffer->proc.app.wl_proxy != NULL) -#ifdef TPL_USING_WAYLAND_TBM wayland_tbm_client_destroy_buffer(wayland_display->wl_tbm_client, (void *)wayland_buffer->proc.app.wl_proxy); -#else - wl_buffer_destroy((void *)wayland_buffer->proc.app.wl_proxy); -#endif - } -#ifndef TBM_SURFACE_QUEUE - if (wayland_display->type == SERVER) - { - if (wayland_buffer->proc.comp.gbm_bo != NULL) - { - gbm_bo_destroy(wayland_buffer->proc.comp.gbm_bo); - } } -#endif + buffer->backend.data = NULL; free(wayland_buffer); } @@ -2053,64 +1554,6 @@ __tpl_wayland_buffer_unlock(tpl_buffer_t *buffer) TPL_OBJECT_LOCK(buffer); } -static void * -__tpl_wayland_buffer_create_native_buffer(tpl_buffer_t *buffer) -{ -#ifdef TPL_USING_WAYLAND_TBM - TPL_IGNORE(buffer); - return NULL; -#else - tpl_surface_t *surface; - tpl_wayland_display_t *wayland_display; - tpl_wayland_buffer_t *wayland_buffer; - struct wl_resource *wl_resource = NULL; - uint32_t wl_format = 0; - unsigned int name = 0; - - TPL_ASSERT(buffer); - TPL_ASSERT(buffer->surface); - TPL_ASSERT(buffer->surface->display); - TPL_ASSERT(buffer->backend.data); - - surface = buffer->surface; - wayland_display = (tpl_wayland_display_t *)surface->display->backend.data; - wayland_buffer = (tpl_wayland_buffer_t *)buffer->backend.data; - - if (wayland_display->wl_drm == NULL) - { - TPL_ERR("Wayland DRM is NULL!"); - return NULL; - } - - switch (surface->format) - { - case TPL_FORMAT_ARGB8888: - wl_format = WL_DRM_FORMAT_ARGB8888; - break; - case TPL_FORMAT_XRGB8888: - wl_format = WL_DRM_FORMAT_XRGB8888; -break; - case TPL_FORMAT_RGB565: - wl_format = WL_DRM_FORMAT_RGB565; - break; - default: - TPL_ERR("Unsupported surface format!"); - return NULL; - } - - name = tbm_bo_export(wayland_buffer->bo); - - wl_resource = (struct wl_resource *)wl_drm_create_buffer(wayland_display->wl_drm, (uint32_t)name, - buffer->width, buffer->height, buffer->pitch, wl_format); - - /* Remove from the default queue. */ - if (wl_resource) - wl_proxy_set_queue((struct wl_proxy *)wl_resource, NULL); - - return (void *)wl_resource; -#endif -} - tpl_bool_t __tpl_display_choose_backend_wayland(tpl_handle_t native_dpy) { @@ -2178,106 +1621,9 @@ __tpl_buffer_init_backend_wayland(tpl_buffer_backend_t *backend) backend->unmap = __tpl_wayland_buffer_unmap; backend->lock = __tpl_wayland_buffer_lock; backend->unlock = __tpl_wayland_buffer_unlock; - backend->create_native_buffer = __tpl_wayland_buffer_create_native_buffer; + backend->create_native_buffer = NULL; } -#ifndef TPL_USING_WAYLAND_TBM -static void -__cb_client_wayland_drm_handle_device(void *user_data, struct wl_drm *drm, const char *device) -{ - tpl_display_t *display; - tpl_wayland_display_t *wayland_display; - drm_magic_t magic; - - TPL_ASSERT(user_data); - - display = (tpl_display_t *) user_data; - wayland_display = (tpl_wayland_display_t *) display->backend.data; - - TPL_ASSERT(wayland_display); - - TPL_IGNORE(drm); - - display->bufmgr_fd = open(device, O_RDWR | O_CLOEXEC); - - drmGetMagic(display->bufmgr_fd, &magic); - wl_drm_authenticate(wayland_display->wl_drm, magic); -} - -static void -__cb_client_wayland_drm_handle_format(void *data, struct wl_drm *drm, uint32_t format) -{ - TPL_IGNORE(data); - TPL_IGNORE(drm); - TPL_IGNORE(format); - - return; -} - -static void -__cb_client_wayland_drm_handle_authenticated(void *user_data, struct wl_drm *drm) -{ - tpl_display_t *display; - tpl_wayland_display_t *wayland_display; - - TPL_ASSERT(user_data); - - display = (tpl_display_t *) user_data; - wayland_display = (tpl_wayland_display_t *) display->backend.data; - - TPL_ASSERT(wayland_display); - - TPL_IGNORE(drm); - - wayland_display->proc.app.authenticated = TPL_TRUE; -} - -static void -__cb_client_wayland_drm_handle_capabilities(void *data, struct wl_drm *drm, uint32_t value) -{ - TPL_IGNORE(data); - TPL_IGNORE(drm); - TPL_IGNORE(value); - - return; -} - -static const struct wl_drm_listener wl_drm_client_listener = -{ - __cb_client_wayland_drm_handle_device, - __cb_client_wayland_drm_handle_format, - __cb_client_wayland_drm_handle_authenticated, - __cb_client_wayland_drm_handle_capabilities -}; - -static void -__cb_client_registry_handle_global(void *user_data, struct wl_registry *registry, uint32_t name, - const char *interface, uint32_t version) -{ - tpl_display_t *display; - tpl_wayland_display_t *wayland_display; - - TPL_ASSERT(user_data); - - display = (tpl_display_t *) user_data; - wayland_display = (tpl_wayland_display_t *) display->backend.data; - - TPL_ASSERT(wayland_display); - - if (strcmp(interface, "wl_drm") == 0) - { - wayland_display->wl_drm = wl_registry_bind(registry, name, &wl_drm_interface, (version > 2) ? 2 : version); - wl_drm_add_listener(wayland_display->wl_drm, &wl_drm_client_listener, display); - } -} - -static const struct wl_registry_listener registry_listener = -{ - __cb_client_registry_handle_global, - NULL -}; - -#endif static void __cb_client_sync_callback(void *data, struct wl_callback *callback, uint32_t serial) { @@ -2347,225 +1693,10 @@ static const struct wl_buffer_listener buffer_release_listener = { (void *)__cb_client_buffer_release_callback, }; -#ifndef TBM_SURFACE_QUEUE -static struct gbm_bo * -__cb_server_gbm_surface_lock_front_buffer(struct gbm_surface *gbm_surf) -{ - struct gbm_tbm_surface *gbm_tbm_surf; - tpl_surface_t *surface; - tpl_wayland_surface_t *wayland_surface = NULL; - tpl_buffer_t *buffer = NULL; - tpl_wayland_buffer_t *wayland_buffer = NULL; - tbm_bo_handle bo_handle; - - TPL_ASSERT(gbm_surf); - - gbm_tbm_surf = (struct gbm_tbm_surface *) gbm_surf; - surface = (tpl_surface_t *)gbm_tbm_surface_get_user_data(gbm_tbm_surf); - - TPL_ASSERT(surface); - - TPL_OBJECT_LOCK(surface); - - wayland_surface = (tpl_wayland_surface_t *)surface->backend.data; - - while (1) - { - /* Wait for posted to prevent locking not-rendered buffer. */ - if (!__tpl_list_is_empty(&wayland_surface->done_rendering_queue)) - { - buffer = __tpl_list_pop_front(&wayland_surface->done_rendering_queue, NULL); - - TPL_ASSERT(buffer); - - wayland_buffer = (tpl_wayland_buffer_t *) buffer->backend.data; - - if (wayland_buffer && wayland_buffer->status == READY) - break; - } - TPL_OBJECT_UNLOCK(surface); - __tpl_util_sys_yield(); - TPL_OBJECT_LOCK(surface); - } - - TPL_ASSERT(buffer != NULL); - - /* why?? */ - wayland_buffer = (tpl_wayland_buffer_t *)buffer->backend.data; - if (NULL == wayland_buffer) - { - TPL_ERR("Wayland buffer is NULL!"); - TPL_OBJECT_UNLOCK(surface); - return NULL; - } - - TPL_LOG(6, "DONE QUEUE:%d | [LOCK] BO:%d", __tpl_list_get_count(&wayland_surface->done_rendering_queue), tbm_bo_export(wayland_buffer->bo)); - - wayland_buffer->status = POSTED; - - bo_handle = tbm_bo_get_handle(wayland_buffer->bo, TBM_DEVICE_CPU); - if (bo_handle.ptr != NULL) - TPL_IMAGE_DUMP(bo_handle.ptr, surface->width, surface->height, surface->dump_count++); - - TPL_OBJECT_UNLOCK(surface); - - return wayland_buffer->proc.comp.gbm_bo; -} - -static void -__cb_server_gbm_surface_release_buffer(struct gbm_surface *gbm_surf, struct gbm_bo *gbm_bo) -{ - struct gbm_tbm_surface *gbm_tbm_surf; - tpl_surface_t *surface; - tpl_wayland_surface_t *wayland_surface = NULL; - tpl_buffer_t *buffer = NULL; - tpl_wayland_buffer_t *wayland_buffer = NULL; - - struct gbm_tbm_bo *gbm_tbm_bo; - tbm_bo bo; - - TPL_ASSERT(gbm_bo); - TPL_ASSERT(gbm_surf); - - gbm_tbm_bo = (struct gbm_tbm_bo *) gbm_bo; - - bo = gbm_tbm_bo_get_tbm_bo(gbm_tbm_bo); - TPL_ASSERT(bo); - - gbm_tbm_surf = (struct gbm_tbm_surface *) gbm_surf; - - surface = (tpl_surface_t *) gbm_tbm_surface_get_user_data(gbm_tbm_surf); - - TPL_ASSERT(surface); - TPL_ASSERT(surface->backend.data); - - TPL_OBJECT_LOCK(surface); - - buffer = __tpl_wayland_surface_get_buffer_from_tbm_bo(surface, bo, TPL_BUFFER_ALLOC_SIZE_COMPOSITOR); - if (buffer) - { - wayland_buffer = (tpl_wayland_buffer_t*) buffer->backend.data; - wayland_buffer->status = IDLE; - } - - wayland_surface = (tpl_wayland_surface_t*) surface->backend.data; - TPL_LOG(6, "DONE QUEUE:%d | [UNLOCK] BO:%d", __tpl_list_get_count(&wayland_surface->done_rendering_queue), tbm_bo_export(bo)); - - TPL_OBJECT_UNLOCK(surface); -} - -static int -__cb_server_gbm_surface_has_free_buffers(struct gbm_surface *gbm_surf) -{ - struct gbm_tbm_surface *gbm_tbm_surf; - tpl_surface_t *surface; - tpl_wayland_surface_t *wayland_surface = NULL; - tpl_buffer_t *buffer = NULL; - tpl_wayland_buffer_t *wayland_buffer = NULL; - - TPL_ASSERT(gbm_surf); - - gbm_tbm_surf = (struct gbm_tbm_surface *) gbm_surf; - surface = (tpl_surface_t *) gbm_tbm_surface_get_user_data(gbm_tbm_surf); - - TPL_ASSERT(surface); - TPL_ASSERT(surface->backend.data); - - TPL_OBJECT_LOCK(surface); - - wayland_surface = (tpl_wayland_surface_t *) surface->backend.data; - - if (__tpl_list_is_empty(&wayland_surface->done_rendering_queue)) { - TPL_OBJECT_UNLOCK(surface); - return 0; - } - - buffer = __tpl_list_get_front(&wayland_surface->done_rendering_queue); - wayland_buffer = (tpl_wayland_buffer_t *)buffer->backend.data; - - if (wayland_buffer->status == POSTED) { - TPL_OBJECT_UNLOCK(surface); - return 1; - } - - TPL_OBJECT_UNLOCK(surface); - - return 0; -} -#endif - - -#ifndef TPL_USING_WAYLAND_TBM -static struct wayland_drm_callbacks wl_drm_server_listener; - -static int -__cb_server_wayland_drm_display_authenticate(void *user_data, uint32_t magic) -{ - tpl_display_t *display; - - TPL_ASSERT(user_data); - - display = (tpl_display_t *) user_data; - - return drmAuthMagic(display->bufmgr_fd, magic); -} - -static void -__cb_server_wayland_drm_reference_buffer(void *user_data, uint32_t name, int fd, struct wl_drm_buffer *buffer) -{ - tpl_display_t *display; - tpl_wayland_display_t *wayland_display; - - TPL_ASSERT(user_data); - - display = (tpl_display_t *)user_data; - wayland_display = (tpl_wayland_display_t *) display->backend.data; - - TPL_IGNORE(fd); - - buffer->driver_buffer = tbm_bo_import(wayland_display->bufmgr, name); - if (NULL == buffer->driver_buffer) - { - TPL_ERR("TBM bo import failed!"); - return; - } -} - -static void -__cb_server_wayland_drm_unreference_buffer(void *user_data, struct wl_drm_buffer *buffer) -{ - tpl_display_t *display; - tpl_wayland_display_t *wayland_display; - - TPL_ASSERT(user_data); - TPL_ASSERT(buffer); - - display = (tpl_display_t *) user_data; - wayland_display = (tpl_wayland_display_t *) display->backend.data; - - tbm_bo_unref(buffer->driver_buffer); - buffer->driver_buffer = NULL; - - /* TODO: tpl_buffer is NULL, it's not right */ - __tpl_wayland_surface_buffer_cache_remove(&wayland_display->proc.comp.cached_buffers, (size_t)buffer); -} - -static struct wayland_drm_callbacks wl_drm_server_listener = -{ - __cb_server_wayland_drm_display_authenticate, - __cb_server_wayland_drm_reference_buffer, - __cb_server_wayland_drm_unreference_buffer -}; -#endif - #ifdef EGL_BIND_WL_DISPLAY unsigned int __tpl_wayland_display_bind_client_display(tpl_display_t *tpl_display, tpl_handle_t native_dpy) { tpl_wayland_display_t *tpl_wayland_display; -#ifndef TPL_USING_WAYLAND_TBM /* USING WAYLAND_DRM */ - struct wl_display *wayland_display; - char *device_name = NULL; -#endif TPL_ASSERT(tpl_display); TPL_ASSERT(native_dpy); @@ -2579,16 +1710,6 @@ unsigned int __tpl_wayland_display_bind_client_display(tpl_display_t *tpl_displa return TPL_FALSE; } -#ifndef TPL_USING_WAYLAND_TBM /* USING WAYLAND_DRM */ - wayland_display = (struct wl_display *) native_dpy; - device_name = drmGetDeviceNameFromFd(tpl_display->bufmgr_fd); - tpl_wayland_display->wl_drm = wayland_drm_init((struct wl_display *) wayland_display, device_name, &wl_drm_server_listener, tpl_display, 0); - if (NULL == tpl_wayland_display->wl_drm) - { - TPL_ERR("Wayland DRM initialization failed!"); - return TPL_FALSE; - } -#endif tpl_wayland_display->proc.comp.bound_client_display = TPL_TRUE; return TPL_TRUE; } @@ -2601,15 +1722,6 @@ unsigned int __tpl_wayland_display_unbind_client_display(tpl_display_t *tpl_disp tpl_wayland_display = (tpl_wayland_display_t *) tpl_display->backend.data; -#ifndef TPL_USING_WAYLAND_TBM /* USING WAYLAND_DRM */ - if (tpl_wayland_display->wl_drm == NULL) - { - TPL_ERR("Wayland DRM is NULL!"); - return TPL_FALSE; - } - - wayland_drm_uninit(tpl_wayland_display->wl_drm); -#endif tbm_bufmgr_deinit(tpl_wayland_display->bufmgr); close(tpl_display->bufmgr_fd); tpl_wayland_display->proc.comp.bound_client_display = TPL_FALSE; -- 2.7.4 From f46b143250a22a9747a156d5b0c79e1f1a3c865a Mon Sep 17 00:00:00 2001 From: "Mun, Gwan-gyeong" Date: Thu, 10 Dec 2015 17:36:43 +0900 Subject: [PATCH 07/16] TPL_WAYLAND: Add USE_TBM_QUEUE Macro for gbm_tbm_get_surface_queue function prototype. Fix incorrect function argument type. Change-Id: If56e7813cf21042257a54896aa6ae84852ab3848 --- src/tpl_wayland.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tpl_wayland.c b/src/tpl_wayland.c index a7d88ed..82a5f85 100644 --- a/src/tpl_wayland.c +++ b/src/tpl_wayland.c @@ -7,6 +7,9 @@ #include #include #include +#ifndef USE_TBM_QUEUE +#define USE_TBM_QUEUE +#endif #include #include #include @@ -927,7 +930,8 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool tpl_wayland_surface_t *wayland_surface = NULL; tbm_bo bo; tbm_bo_handle bo_handle; - int width, height, depth, stride, size, offset; + int width, height, depth; + uint32_t stride, size, offset; tpl_format_t format; tpl_wayland_display_t *wayland_display; -- 2.7.4 From 2be710c7e076822ea2a35525932da6e7f4f64e91 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Wed, 9 Dec 2015 14:02:12 +0900 Subject: [PATCH 08/16] Replace tbm_bo_ref/unref with tbm_surface_internal_ref/unref. - TPL is using only tbm_surface. so replaced tbm_bo_ref/unref functions with tbm_surface_internal_ref/unref functions. Change-Id: I3e604629cf881029d889bebbc7b775a2de1c78d2 --- src/tpl_wayland.c | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/tpl_wayland.c b/src/tpl_wayland.c index 82a5f85..1cc4e73 100644 --- a/src/tpl_wayland.c +++ b/src/tpl_wayland.c @@ -989,11 +989,16 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool return NULL; } + /* Inc ref count about tbm_surface */ + /* It will be dec when wayland_buffer_fini called*/ + tbm_surface_internal_ref(tbm_surface); + /* Get tbm_bo from tbm_surface_h */ - bo = tbm_bo_ref(tbm_surface_internal_get_bo(tbm_surface, 0)); + bo = tbm_surface_internal_get_bo(tbm_surface, 0); if (NULL == bo) { TPL_ERR("TBM get bo failed!"); + tbm_surface_internal_unref(tbm_surface); tbm_surface_destroy(tbm_surface); return NULL; } @@ -1003,7 +1008,7 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool if (bo_handle.ptr == NULL) { TPL_ERR("TBM bo get handle failed!"); - tbm_bo_unref(bo); + tbm_surface_internal_unref(tbm_surface); tbm_surface_destroy(tbm_surface); return NULL; } @@ -1013,6 +1018,8 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool if (tbm_surface_get_info(tbm_surface, &tbm_surf_info) != 0) { TPL_ERR("Failed to get tbm_surface info!"); + tbm_surface_internal_unref(tbm_surface); + tbm_surface_destroy(tbm_surface); return NULL; } stride = tbm_surf_info.planes[0].stride; @@ -1020,6 +1027,8 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool if (!tbm_surface_internal_get_plane_data(tbm_surface, 0, &size, &offset, &stride)) { TPL_ERR("Failed to get tbm_surface stride info!"); + tbm_surface_internal_unref(tbm_surface); + tbm_surface_destroy(tbm_surface); return NULL; } #endif @@ -1031,7 +1040,7 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool if (NULL == buffer) { TPL_ERR("TPL buffer alloc failed!"); - tbm_bo_unref(bo); + tbm_surface_internal_unref(tbm_surface); tbm_surface_destroy(tbm_surface); return NULL; } @@ -1040,7 +1049,7 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool if (wayland_buffer == NULL) { TPL_ERR("Mem alloc for wayland_buffer failed!"); - tbm_bo_unref(bo); + tbm_surface_internal_unref(tbm_surface); tbm_surface_destroy(tbm_surface); tpl_object_unreference((tpl_object_t *) buffer); return NULL; @@ -1054,7 +1063,7 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool if (wl_proxy == NULL) { TPL_ERR("Failed to create TBM client buffer!"); - tbm_bo_unref(bo); + tbm_surface_internal_unref(tbm_surface); tbm_surface_destroy(tbm_surface); tpl_object_unreference((tpl_object_t *)buffer); free(wayland_buffer); @@ -1144,6 +1153,9 @@ __tpl_wayland_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl return NULL; } } + + /* Inc ref count about tbm_surface */ + /* It will be dec when before tbm_surface_queue_enqueue called */ tbm_surface_internal_ref(tbm_surface); buffer = __tpl_wayland_surface_get_buffer_from_tbm_surface(tbm_surface); @@ -1197,8 +1209,8 @@ __tpl_wayland_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl if (wayland_buffer == NULL) { TPL_ERR("Mem alloc for wayland_buffer failed!"); - tbm_surface_internal_unref(tbm_surface); tpl_object_unreference((tpl_object_t *) buffer); + tbm_surface_internal_unref(tbm_surface); return NULL; } @@ -1270,6 +1282,10 @@ __tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool return NULL; } + /* Inc ref count about tbm_surface */ + /* It will be dec when wayland_buffer_fini called*/ + tbm_surface_internal_ref(tbm_surface); + bo = tbm_surface_internal_get_bo(tbm_surface, 0); key = tbm_bo_export(bo); @@ -1285,6 +1301,7 @@ __tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool &width, &height, &format)) { TPL_ERR("Failed to get pixmap info!"); + tbm_surface_internal_unref(tbm_surface); return NULL; } /* TODO: If HW support getting of gem memory size, @@ -1293,6 +1310,7 @@ __tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool if (tbm_surface_get_info(tbm_surface, &tbm_surf_info) != 0) { TPL_ERR("Failed to get stride info!"); + tbm_surface_internal_unref(tbm_surface); return NULL; } stride = tbm_surf_info.planes[0].stride; @@ -1300,6 +1318,7 @@ __tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool if (!tbm_surface_internal_get_plane_data(tbm_surface, 0, &size, &offset, &stride)) { TPL_ERR("Failed to get tbm_surface stride info!"); + tbm_surface_internal_unref(tbm_surface); return NULL; } #endif @@ -1310,6 +1329,7 @@ __tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool if (NULL == bo_handle.ptr) { TPL_ERR("Failed to get bo handle!"); + tbm_surface_internal_unref(tbm_surface); return NULL; } @@ -1318,6 +1338,7 @@ __tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool if (buffer == NULL) { TPL_ERR("Failed to alloc TPL buffer!"); + tbm_surface_internal_unref(tbm_surface); return NULL; } @@ -1326,6 +1347,7 @@ __tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool { TPL_ERR("Mem alloc failed for wayland buffer!"); tpl_object_unreference((tpl_object_t *) buffer); + tbm_surface_internal_unref(tbm_surface); return NULL; } @@ -1341,6 +1363,7 @@ __tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool { TPL_ERR("Adding surface to buffer cache failed!"); tpl_object_unreference((tpl_object_t *) buffer); + tbm_surface_internal_unref(tbm_surface); free(wayland_buffer); return NULL; } @@ -1446,15 +1469,12 @@ __tpl_wayland_buffer_fini(tpl_buffer_t *buffer) tpl_wayland_display_t *wayland_display = (tpl_wayland_display_t *)wayland_buffer->display->backend.data; - if (wayland_buffer->bo != NULL) - { - tbm_bo_unref(wayland_buffer->bo); - wayland_buffer->bo = NULL; - } - if (wayland_buffer->tbm_surface != NULL) + if (wayland_buffer->bo != NULL && wayland_buffer->tbm_surface != NULL) { + tbm_surface_internal_unref(wayland_buffer->tbm_surface); tbm_surface_destroy(wayland_buffer->tbm_surface); + wayland_buffer->bo = NULL; wayland_buffer->tbm_surface = NULL; } -- 2.7.4 From c07f19f3a00d5f52128a538da0b75990ca6133f7 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Sun, 13 Dec 2015 23:03:19 +0900 Subject: [PATCH 09/16] Wayland server can use buffer_cache for their render buffer. - and fix some memory leak. Change-Id: I616be5365fd3c2b6979581a880279faa2643389f --- src/tpl_wayland.c | 55 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/src/tpl_wayland.c b/src/tpl_wayland.c index 1cc4e73..41cb13e 100644 --- a/src/tpl_wayland.c +++ b/src/tpl_wayland.c @@ -1129,9 +1129,10 @@ __tpl_wayland_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl tbm_bo_handle bo_handle; int width, height, depth; - uint32_t size, offset, stride; + uint32_t size, offset, stride, key; tpl_format_t format; - tpl_wayland_surface_t *wayland_surface; + tpl_wayland_surface_t *wayland_surface = NULL; + tpl_wayland_display_t *wayland_display = NULL; TPL_ASSERT(surface); TPL_ASSERT(surface->native_handle); @@ -1139,6 +1140,7 @@ __tpl_wayland_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl TPL_ASSERT(surface->display->native_handle); wayland_surface = (tpl_wayland_surface_t*)surface->backend.data; + wayland_display = (tpl_wayland_display_t*)surface->display->backend.data; tsq_err = tbm_surface_queue_dequeue(wayland_surface->tbm_queue, &tbm_surface); if (tbm_surface == NULL) @@ -1158,8 +1160,17 @@ __tpl_wayland_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl /* It will be dec when before tbm_surface_queue_enqueue called */ tbm_surface_internal_ref(tbm_surface); - buffer = __tpl_wayland_surface_get_buffer_from_tbm_surface(tbm_surface); - if (buffer) + if ((bo = tbm_surface_internal_get_bo(tbm_surface, 0)) == NULL) + { + TPL_ERR("Failed to get tbm_bo from tbm_surface"); + tbm_surface_internal_unref(tbm_surface); + return NULL; + } + + key = tbm_bo_export(bo); + + buffer = __tpl_wayland_surface_buffer_cache_find(&wayland_display->proc.comp.cached_buffers, key); + if (buffer != NULL) { return buffer; } @@ -1184,17 +1195,10 @@ __tpl_wayland_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl /* Get pitch stride from tbm_surface */ tbm_surface_internal_get_plane_data(tbm_surface, 0, &size, &offset, &stride); - if ((bo = tbm_surface_internal_get_bo(tbm_surface, 0)) == NULL) - { - TPL_ERR("Failed to get tbm_bo from tbm_surface"); - tbm_surface_internal_unref(tbm_surface); - return NULL; - } - /* Create tpl buffer. */ bo_handle = tbm_bo_get_handle(bo, TBM_DEVICE_3D); - buffer = __tpl_buffer_alloc(surface, (size_t) bo_handle.u32, + buffer = __tpl_buffer_alloc(surface, (size_t) key, (int)bo_handle.u32, width, height, depth, stride); if (buffer == NULL) @@ -1221,6 +1225,15 @@ __tpl_wayland_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl wayland_buffer->bo = bo; wayland_buffer->tbm_surface = tbm_surface; + if (TPL_TRUE != __tpl_wayland_surface_buffer_cache_add(&wayland_display->proc.comp.cached_buffers, buffer)) + { + TPL_ERR("Adding surface to buffer cache failed!"); + tpl_object_unreference((tpl_object_t *) buffer); + tbm_surface_internal_unref(tbm_surface); + free(wayland_buffer); + return NULL; + } + if (reset_buffers != NULL) *reset_buffers = TPL_FALSE; @@ -1243,9 +1256,8 @@ __tpl_wayland_buffer_destroy_notify(struct wl_listener *listener, void *data) display = wayland_buffer->display; key = tbm_bo_export(wayland_buffer->bo); wayland_display = (tpl_wayland_display_t *)display->backend.data; + tpl_object_unreference((tpl_object_t *)wayland_buffer->tpl_buffer); __tpl_wayland_surface_buffer_cache_remove(&wayland_display->proc.comp.cached_buffers, key); - - while( 0 < (ref = tpl_object_unreference((tpl_object_t*)wayland_buffer->tpl_buffer))); } static tpl_buffer_t * @@ -1282,10 +1294,6 @@ __tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool return NULL; } - /* Inc ref count about tbm_surface */ - /* It will be dec when wayland_buffer_fini called*/ - tbm_surface_internal_ref(tbm_surface); - bo = tbm_surface_internal_get_bo(tbm_surface, 0); key = tbm_bo_export(bo); @@ -1293,12 +1301,17 @@ __tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool if (buffer != NULL) { __tpl_buffer_set_surface(buffer, surface); - tpl_object_reference((tpl_object_t *) buffer); } else { - if (TPL_TRUE != __tpl_wayland_display_get_pixmap_info(surface->display, surface->native_handle, - &width, &height, &format)) + /* Inc ref count about tbm_surface */ + /* It will be dec when wayland_buffer_fini called*/ + tbm_surface_internal_ref(tbm_surface); + + if (TPL_TRUE != __tpl_wayland_display_get_pixmap_info( + surface->display, + surface->native_handle, + &width, &height, &format)) { TPL_ERR("Failed to get pixmap info!"); tbm_surface_internal_unref(tbm_surface); -- 2.7.4 From 57a6a7b4f6b380e98105835ed2dc770fbd05a86a Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Sun, 13 Dec 2015 23:23:26 +0900 Subject: [PATCH 10/16] Add tpl APIs for destroying/updating cached buffer of client Change-Id: I4d6d571e40eb39a8d2c5da80de9639ab767d13dc --- src/tpl.h | 4 ++++ src/tpl_internal.h | 2 ++ src/tpl_surface.c | 48 +++++++++++++++++++++++++++++++++++++ src/tpl_wayland.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 124 insertions(+) diff --git a/src/tpl.h b/src/tpl.h index bf049d4..7c08241 100644 --- a/src/tpl.h +++ b/src/tpl.h @@ -671,6 +671,10 @@ tpl_bool_t tpl_surface_get_damage(tpl_surface_t *surface, int *num_rects, const int **rects); +tpl_bool_t tpl_surface_destroy_cached_buffers(tpl_surface_t *surface); + +tpl_bool_t tpl_surface_update_cached_buffers(tpl_surface_t *surface); + /** * Map the given buffer to the user space address. * diff --git a/src/tpl_internal.h b/src/tpl_internal.h index d99a1c2..e574218 100644 --- a/src/tpl_internal.h +++ b/src/tpl_internal.h @@ -82,6 +82,8 @@ struct _tpl_surface_backend tpl_buffer_t * (*get_buffer)(tpl_surface_t *surface, tpl_bool_t *reset_buffers); void (*post)(tpl_surface_t *surface, tpl_frame_t *frame); + tpl_bool_t (*destroy_cached_buffers)(tpl_surface_t *surface); + tpl_bool_t (*update_cached_buffers)(tpl_surface_t *surface); }; struct _tpl_buffer_backend diff --git a/src/tpl_surface.c b/src/tpl_surface.c index 6de50d0..78da293 100644 --- a/src/tpl_surface.c +++ b/src/tpl_surface.c @@ -430,6 +430,54 @@ tpl_surface_get_buffer(tpl_surface_t *surface, tpl_bool_t *reset_buffers) } tpl_bool_t +tpl_surface_destroy_cached_buffers(tpl_surface_t *surface) +{ + tpl_bool_t retval = TPL_FALSE; + + if (NULL == surface) + { + TPL_ERR("Invalid surface!"); + return NULL; + } + + if (NULL == surface->backend.destroy_cached_buffers) + { + TPL_ERR("TPL surface has not been initialized correctly!"); + return NULL; + } + + TPL_OBJECT_LOCK(surface); + retval = surface->backend.destroy_cached_buffers(surface); + TPL_OBJECT_UNLOCK(surface); + + return retval; +} + +tpl_bool_t +tpl_surface_update_cached_buffers(tpl_surface_t *surface) +{ + tpl_bool_t retval = TPL_FALSE; + + if (NULL == surface) + { + TPL_ERR("Invalid surface!"); + return NULL; + } + + if (NULL == surface->backend.destroy_cached_buffers) + { + TPL_ERR("TPL surface has not been initialized correctly!"); + return NULL; + } + + TPL_OBJECT_LOCK(surface); + retval = surface->backend.update_cached_buffers(surface); + TPL_OBJECT_UNLOCK(surface); + + return retval; +} + +tpl_bool_t tpl_surface_post(tpl_surface_t *surface) { tpl_frame_t *frame; diff --git a/src/tpl_wayland.c b/src/tpl_wayland.c index 41cb13e..c46be5a 100644 --- a/src/tpl_wayland.c +++ b/src/tpl_wayland.c @@ -660,6 +660,74 @@ __tpl_wayland_surface_get_idle_buffer_idx(tpl_wayland_surface_t *wayland_surface return ret_id; } +static tpl_bool_t +__tpl_wayland_surface_destroy_cached_buffers(tpl_surface_t *surface) +{ + tpl_wayland_surface_t *wayland_surface = NULL; + tpl_wayland_display_t *wayland_display = NULL; + + if (surface == NULL) + { + TPL_ERR("tpl surface is invalid!!\n"); + return TPL_FALSE; + } + + wayland_surface = (tpl_wayland_surface_t*)surface->backend.data; + wayland_display = (tpl_wayland_display_t*)surface->display->backend.data; + + if (wayland_surface == NULL || wayland_display == NULL) + { + TPL_ERR("tpl surface has invalid members!!\n"); + return TPL_FALSE; + } + + if (wayland_display->type == CLIENT) + __tpl_wayland_surface_render_buffers_free(wayland_surface, TPL_BUFFER_ALLOC_SIZE_APP); + + return TPL_TRUE; +} + +static tpl_bool_t +__tpl_wayland_surface_update_cached_buffers(tpl_surface_t *surface) +{ + tpl_wayland_surface_t *wayland_surface = NULL; + tpl_wayland_display_t *wayland_display = NULL; + + if (surface == NULL) + { + TPL_ERR("tpl surface is invalid!!\n"); + return TPL_FALSE; + } + + wayland_surface = (tpl_wayland_surface_t*)surface->backend.data; + wayland_display = (tpl_wayland_display_t*)surface->display->backend.data; + + if (wayland_surface == NULL || wayland_display == NULL) + { + TPL_ERR("tpl surface has invalid members!!\n"); + return TPL_FALSE; + } + + if (wayland_display->type == CLIENT) + { + int i; + for (i = 0; i < TPL_BUFFER_ALLOC_SIZE_APP; i++) + { + tpl_buffer_t *cached_buffer = wayland_surface->back_buffers[i]; + + if (cached_buffer != NULL && + (surface->width != wayland_surface->back_buffers[i]->width || + surface->height != wayland_surface->back_buffers[i]->height)) + { + __tpl_wayland_surface_buffer_free(wayland_surface->back_buffers[i]); + wayland_surface->back_buffers[i] = NULL; + } + } + } + + return TPL_TRUE; +} + static void __tpl_wayland_surface_fini(tpl_surface_t *surface) { @@ -1642,6 +1710,8 @@ __tpl_surface_init_backend_wayland(tpl_surface_backend_t *backend) backend->validate_frame = __tpl_wayland_surface_validate_frame; backend->get_buffer = __tpl_wayland_surface_get_buffer; backend->post = __tpl_wayland_surface_post; + backend->destroy_cached_buffers = __tpl_wayland_surface_destroy_cached_buffers; + backend->update_cached_buffers = __tpl_wayland_surface_update_cached_buffers; } void -- 2.7.4 From f0439b620525cdda420955343dcc35e43618060b Mon Sep 17 00:00:00 2001 From: "Mun, Gwan-gyeong" Date: Fri, 18 Dec 2015 17:13:01 +0900 Subject: [PATCH 11/16] Seperate wayland backend : tpl_wayland and tpl_gbm Change-Id: I0e94240d16309086edaa35303c5f79050e132748 --- Makefile | 1 + src/tpl.c | 24 ++ src/tpl.h | 1 + src/tpl_gbm.c | 1210 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/tpl_internal.h | 4 + src/tpl_surface.c | 8 +- src/tpl_wayland.c | 768 ++++++++------------------------- 7 files changed, 1429 insertions(+), 587 deletions(-) create mode 100644 src/tpl_gbm.c diff --git a/Makefile b/Makefile index 0e4a537..2b53c86 100644 --- a/Makefile +++ b/Makefile @@ -65,6 +65,7 @@ TPL_SRCS += $(SRC_DIR)/tpl_utils_hlist.c ifneq ($(call is-feature-enabled,winsys_wl),) TPL_SRCS += $(SRC_DIR)/tpl_wayland.c +TPL_SRCS += $(SRC_DIR)/tpl_gbm.c endif ifneq ($(call is-feature-enabled,winsys_dri2),) diff --git a/src/tpl.c b/src/tpl.c index 0f3cccf..d2a1100 100644 --- a/src/tpl.c +++ b/src/tpl.c @@ -221,7 +221,22 @@ __tpl_runtime_flush_all_display() tpl_backend_type_t __tpl_display_choose_backend(tpl_handle_t native_dpy) { + const char *plat_name; + plat_name = getenv("EGL_PLATFORM"); +#ifdef TPL_WINSYS_DRI2 + if (strcmp(plat_name, "x11") == 0) return TPL_BACKEND_X11_DRI2; +#endif +#ifdef TPL_WINSYS_DRI3 + if (strcmp(plat_name, "x11") == 0) return TPL_BACKEND_X11_DRI3; +#endif +#ifdef TPL_WINSYS_WL + if (strcmp(plat_name, "wayland") == 0) return TPL_BACKEND_WAYLAND; + if (strcmp(plat_name, "drm") == 0) return TPL_BACKEND_GBM; +#endif + #ifdef TPL_WINSYS_WL + if (__tpl_display_choose_backend_gbm(native_dpy) == TPL_TRUE) + return TPL_BACKEND_GBM; if (__tpl_display_choose_backend_wayland(native_dpy) == TPL_TRUE) return TPL_BACKEND_WAYLAND; #endif @@ -245,6 +260,9 @@ __tpl_display_init_backend(tpl_display_t *display, tpl_backend_type_t type) switch (type) { #ifdef TPL_WINSYS_WL + case TPL_BACKEND_GBM: + __tpl_display_init_backend_gbm(&display->backend); + break; case TPL_BACKEND_WAYLAND: __tpl_display_init_backend_wayland(&display->backend); break; @@ -273,6 +291,9 @@ __tpl_surface_init_backend(tpl_surface_t *surface, tpl_backend_type_t type) switch (type) { #ifdef TPL_WINSYS_WL + case TPL_BACKEND_GBM: + __tpl_surface_init_backend_gbm(&surface->backend); + break; case TPL_BACKEND_WAYLAND: __tpl_surface_init_backend_wayland(&surface->backend); break; @@ -298,6 +319,9 @@ __tpl_buffer_init_backend(tpl_buffer_t *buffer, tpl_backend_type_t type) switch (type) { #ifdef TPL_WINSYS_WL + case TPL_BACKEND_GBM: + __tpl_buffer_init_backend_gbm(&buffer->backend); + break; case TPL_BACKEND_WAYLAND: __tpl_buffer_init_backend_wayland(&buffer->backend); break; diff --git a/src/tpl.h b/src/tpl.h index 7c08241..7a96ce4 100644 --- a/src/tpl.h +++ b/src/tpl.h @@ -238,6 +238,7 @@ typedef enum { TPL_BACKEND_ERROR = -1, TPL_BACKEND_WAYLAND, + TPL_BACKEND_GBM, TPL_BACKEND_X11_DRI2, TPL_BACKEND_X11_DRI3, TPL_BACKEND_COUNT, diff --git a/src/tpl_gbm.c b/src/tpl_gbm.c new file mode 100644 index 0000000..f59e765 --- /dev/null +++ b/src/tpl_gbm.c @@ -0,0 +1,1210 @@ +#define inline __inline__ + +#include + +#include "wayland-egl/wayland-egl-priv.h" + +#include +#include +#include +#ifndef USE_TBM_QUEUE +#define USE_TBM_QUEUE +#endif +#include +#include +#include + +#undef inline + +#include "tpl_internal.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +/* In wayland, application and compositor create its own drawing buffers. Recommend size is more than 2. */ +#define TPL_BUFFER_ALLOC_SIZE_APP 3 +#define TPL_BUFFER_ALLOC_SIZE_COMPOSITOR 4 +#define TPL_BUFFER_ALLOC_SIZE_MAX (((TPL_BUFFER_ALLOC_SIZE_APP) > (TPL_BUFFER_ALLOC_SIZE_COMPOSITOR))?(TPL_BUFFER_ALLOC_SIZE_APP):(TPL_BUFFER_ALLOC_SIZE_COMPOSITOR)) + +typedef struct _tpl_gbm_display tpl_gbm_display_t; +typedef struct _tpl_gbm_surface tpl_gbm_surface_t; +typedef struct _tpl_gbm_buffer tpl_gbm_buffer_t; + +enum gbm_buffer_status +{ + IDLE = 0, + BUSY = 1, + READY = 2, /* redering done */ + POSTED = 3 /* gbm locked */ +}; + +struct _tpl_gbm_display +{ + tbm_bufmgr bufmgr; + tpl_list_t cached_buffers; + tpl_bool_t bound_client_display; +}; + +struct _tpl_gbm_surface +{ + tpl_buffer_t *current_rendering_buffer; + tpl_list_t done_rendering_queue; + int current_back_idx; + tpl_buffer_t *back_buffers[TPL_BUFFER_ALLOC_SIZE_MAX]; + tbm_surface_queue_h tbm_queue; +}; + +struct _tpl_gbm_buffer +{ + tpl_display_t *display; + tbm_surface_h tbm_surface; + tbm_bo bo; + int reused; + tpl_buffer_t *tpl_buffer; + + enum gbm_buffer_status status; + struct gbm_bo *gbm_bo; + tpl_bool_t posted; + struct wl_listener destroy_listener; +}; + +#ifdef EGL_BIND_WL_DISPLAY +unsigned int __tpl_gbm_display_bind_client_wayland_display(tpl_display_t *tpl_display, tpl_handle_t native_dpy); +unsigned int __tpl_gbm_display_unbind_client_wayland_display(tpl_display_t *tpl_display, tpl_handle_t native_dpy); +#endif + +#define TPL_BUFFER_CACHE_MAX_ENTRIES 40 + +static TPL_INLINE tpl_bool_t +__tpl_gbm_surface_buffer_cache_add(tpl_list_t *buffer_cache, tpl_buffer_t *buffer) +{ + tpl_buffer_t *evict = NULL; + + TPL_ASSERT(buffer_cache); + TPL_ASSERT(buffer); + + if (__tpl_list_get_count(buffer_cache) >= TPL_BUFFER_CACHE_MAX_ENTRIES) + { + evict = __tpl_list_pop_front(buffer_cache, NULL); + + TPL_ASSERT(evict); + tpl_object_unreference(&evict->base); + } + + TPL_LOG(3, "buf:%10p buf->base:%10p evict:%10p", buffer, &buffer->base, evict); + + if (-1 == tpl_object_reference(&buffer->base)) + return TPL_FALSE; + + return __tpl_list_push_back(buffer_cache, (void *)buffer); +} + +static TPL_INLINE void +__tpl_gbm_surface_buffer_cache_remove(tpl_list_t *buffer_cache, size_t name) +{ + tpl_list_node_t *node; + + TPL_ASSERT(buffer_cache); + + node = __tpl_list_get_front_node(buffer_cache); + + while (node) + { + tpl_buffer_t *buffer = (tpl_buffer_t *)__tpl_list_node_get_data(node); + + TPL_ASSERT(buffer); + + if (buffer->key == name) + { + tpl_object_unreference(&buffer->base); + __tpl_list_remove(node, NULL); + TPL_LOG(3, "name:%zu buf:%10p buf->base:%10p", name, buffer, &buffer->base); + return; + } + + node = __tpl_list_node_next(node); + } + + TPL_LOG(3, "Buffer named %zu not found in cache", name); +} + +static TPL_INLINE tpl_buffer_t * +__tpl_gbm_surface_buffer_cache_find(tpl_list_t *buffer_cache, size_t name) +{ + tpl_list_node_t *node; + + TPL_ASSERT(buffer_cache); + + node = __tpl_list_get_front_node(buffer_cache); + + while (node) + { + tpl_buffer_t *buffer = (tpl_buffer_t *)__tpl_list_node_get_data(node); + + TPL_ASSERT(buffer); + + if (buffer->key == name) + { + TPL_LOG(3, "name:%zu buf:%10p buf->base:%10p", name, buffer, &buffer->base); + return buffer; + } + + node = __tpl_list_node_next(node); + } + + TPL_LOG(3, "Buffer named %zu not found in cache", name); + + return NULL; +} + + +static TPL_INLINE tpl_bool_t +__tpl_gbm_display_is_gbm_device(tpl_handle_t native_dpy) +{ + TPL_ASSERT(native_dpy); + + if (*(void **)native_dpy == &wl_display_interface) + return TPL_FALSE; + + /* MAGIC CHECK: A native display handle is a gbm_device if the de-referenced first value + is a memory address pointing gbm_create_surface(). */ + if (*(void **)native_dpy == gbm_create_device) + return TPL_TRUE; + + return TPL_FALSE; +} + +static tpl_bool_t +__tpl_gbm_display_init(tpl_display_t *display) +{ + tpl_gbm_display_t *gbm_display = NULL; + + TPL_ASSERT(display); + + /* Do not allow default display in gbm. */ + if (display->native_handle == NULL) + return TPL_FALSE; + + gbm_display = (tpl_gbm_display_t *) calloc(1, sizeof(tpl_gbm_display_t)); + if (gbm_display == NULL) + return TPL_FALSE; + + display->backend.data = gbm_display; + display->bufmgr_fd = -1; + + if (__tpl_gbm_display_is_gbm_device(display->native_handle)) + { + __tpl_list_init(&gbm_display->cached_buffers); + } + else + goto free_wl_display; + + return TPL_TRUE; +free_wl_display: + if (gbm_display != NULL) + { + free(gbm_display); + display->backend.data = NULL; + } + return TPL_FALSE; +} + +static void +__tpl_gbm_display_fini(tpl_display_t *display) +{ + tpl_gbm_display_t *gbm_display; + + TPL_ASSERT(display); + + gbm_display = (tpl_gbm_display_t *)display->backend.data; + if (gbm_display != NULL) + { + if (gbm_display->bound_client_display) + __tpl_gbm_display_unbind_client_wayland_display(display, NULL); + + __tpl_list_fini(&gbm_display->cached_buffers, (tpl_free_func_t) tpl_object_unreference); + + free(gbm_display); + } + display->backend.data = NULL; +} + +static tpl_bool_t +__tpl_gbm_display_query_config(tpl_display_t *display, tpl_surface_type_t surface_type, + int red_size, int green_size, int blue_size, int alpha_size, + int color_depth, int *native_visual_id, tpl_bool_t *is_slow) +{ + TPL_ASSERT(display); + + if (surface_type == TPL_SURFACE_TYPE_WINDOW && + red_size == 8 && + green_size == 8 && + blue_size == 8 && + (color_depth == 32 || color_depth == 24)) + { + if (alpha_size == 8) + { + if (gbm_device_is_format_supported((struct gbm_device *)display->native_handle, + GBM_FORMAT_ARGB8888, + GBM_BO_USE_RENDERING) == 1) + { + if (native_visual_id != NULL) *native_visual_id = GBM_FORMAT_ARGB8888; + } + else + return TPL_FALSE; + + if (is_slow != NULL) *is_slow = TPL_FALSE; + return TPL_TRUE; + } + if (alpha_size == 0) + { + if (gbm_device_is_format_supported((struct gbm_device *)display->native_handle, + GBM_FORMAT_XRGB8888, + GBM_BO_USE_RENDERING) == 1) + { + if (native_visual_id != NULL) *native_visual_id = GBM_FORMAT_XRGB8888; + } + else + return TPL_FALSE; + + if (is_slow != NULL) *is_slow = TPL_FALSE; + return TPL_TRUE; + } + } + + return TPL_FALSE; +} + +static tpl_bool_t +__tpl_gbm_display_filter_config(tpl_display_t *display, + int *visual_id, int alpha_size) +{ + TPL_IGNORE(display); + + if (visual_id != NULL && *visual_id == GBM_FORMAT_ARGB8888 && alpha_size == 0) + { + *visual_id = GBM_FORMAT_XRGB8888; + return TPL_TRUE; + } + + return TPL_FALSE; +} + +static tpl_bool_t +__tpl_gbm_display_get_window_info(tpl_display_t *display, tpl_handle_t window, + int *width, int *height, tpl_format_t *format, int depth, int a_size) +{ + TPL_ASSERT(display); + TPL_ASSERT(window); + + struct gbm_surface *gbm_surface = (struct gbm_surface *)window; + tbm_surface_queue_h surf_queue = (tbm_surface_queue_h)gbm_tbm_get_surface_queue(gbm_surface); + + if (format != NULL) + { + switch (tbm_surface_queue_get_format(surf_queue)) + { + case TBM_FORMAT_ARGB8888: *format = TPL_FORMAT_ARGB8888; break; + case TBM_FORMAT_XRGB8888: *format = TPL_FORMAT_XRGB8888; break; + case TBM_FORMAT_RGB565: *format = TPL_FORMAT_RGB565; break; + default: *format = TPL_FORMAT_INVALID; break; + } + } + if (width != NULL) *width = tbm_surface_queue_get_width(surf_queue); + if (height != NULL) *height = tbm_surface_queue_get_height(surf_queue); + return TPL_TRUE; + + return TPL_FALSE; +} + +static tpl_bool_t +__tpl_gbm_display_get_pixmap_info(tpl_display_t *display, tpl_handle_t pixmap, + int *width, int *height, tpl_format_t *format) +{ + tbm_surface_h tbm_surface = NULL; + int tbm_format = -1; + + tbm_surface = wayland_tbm_server_get_surface(NULL, (struct wl_resource*)pixmap); + if (tbm_surface == NULL) + return TPL_FALSE; + + if (width) *width = tbm_surface_get_width(tbm_surface); + if (height) *height = tbm_surface_get_height(tbm_surface); + if (format) + { + tbm_format = tbm_surface_get_format(tbm_surface); + switch(tbm_format) + { + case TBM_FORMAT_ARGB8888: *format = TPL_FORMAT_ARGB8888; break; + case TBM_FORMAT_XRGB8888: *format = TPL_FORMAT_XRGB8888; break; + case TBM_FORMAT_RGB565: *format = TPL_FORMAT_RGB565; break; + default: + *format = TPL_FORMAT_INVALID; + return TPL_FALSE; + } + } + + return TPL_TRUE; +} + +static void +__tpl_gbm_display_flush(tpl_display_t *display) +{ + TPL_IGNORE(display); + + /* Do nothing. */ +} + +static tpl_bool_t +__tpl_gbm_surface_init(tpl_surface_t *surface) +{ + tpl_gbm_surface_t *tpl_gbm_surface = NULL; + TPL_ASSERT(surface); + + tpl_gbm_surface = (tpl_gbm_surface_t *) calloc(1, sizeof(tpl_gbm_surface_t)); + if (NULL == tpl_gbm_surface) + return TPL_FALSE; + + surface->backend.data = (void *)tpl_gbm_surface; + tpl_gbm_surface->current_back_idx = 0; + tpl_gbm_surface->tbm_queue = NULL; + + __tpl_list_init(&tpl_gbm_surface->done_rendering_queue); + + if (surface->type == TPL_SURFACE_TYPE_WINDOW) + { + struct gbm_surface *gbm_surface = (struct gbm_surface*)surface->native_handle; + tpl_gbm_surface->tbm_queue = (tbm_surface_queue_h)gbm_tbm_get_surface_queue(gbm_surface); + + if (TPL_TRUE != __tpl_gbm_display_get_window_info(surface->display, surface->native_handle, + &surface->width, &surface->height, NULL, 0, 0)) + goto error; + + TPL_LOG(3, "window(%p, %p) %dx%d", surface, surface->native_handle, surface->width, surface->height); + return TPL_TRUE; + } + else if (surface->type == TPL_SURFACE_TYPE_PIXMAP) + { + if (TPL_TRUE != __tpl_gbm_display_get_pixmap_info(surface->display, surface->native_handle, + &surface->width, &surface->height, NULL)) + goto error; + + return TPL_TRUE; + } + +error: + free(tpl_gbm_surface); + + return TPL_FALSE; +} + +static void +__tpl_gbm_surface_buffer_free(tpl_buffer_t *buffer) +{ + TPL_LOG(3, "buffer(%p) key:%zu", buffer, buffer?buffer->key:-1); + if (buffer != NULL) + { + __tpl_buffer_set_surface(buffer, NULL); + tpl_object_unreference((tpl_object_t *) buffer); + } +} + +static void +__tpl_gbm_surface_render_buffers_free(tpl_gbm_surface_t *gbm_surface, int num_buffers) +{ + TPL_ASSERT(gbm_surface); + int i; + + for (i = 0; i < num_buffers; i++) + { + if ( gbm_surface->back_buffers[i] != NULL ) + __tpl_gbm_surface_buffer_free(gbm_surface->back_buffers[i]); + gbm_surface->back_buffers[i] = NULL; + } +} + +static tpl_bool_t +__tpl_gbm_surface_destroy_cached_buffers(tpl_surface_t *surface) +{ + tpl_gbm_surface_t *gbm_surface = NULL; + tpl_gbm_display_t *gbm_display = NULL; + + if (surface == NULL) + { + TPL_ERR("tpl surface is invalid!!\n"); + return TPL_FALSE; + } + + gbm_surface = (tpl_gbm_surface_t*)surface->backend.data; + gbm_display = (tpl_gbm_display_t*)surface->display->backend.data; + + if (gbm_surface == NULL || gbm_display == NULL) + { + TPL_ERR("tpl surface has invalid members!!\n"); + return TPL_FALSE; + } + + return TPL_TRUE; +} + +static tpl_bool_t +__tpl_gbm_surface_update_cached_buffers(tpl_surface_t *surface) +{ + tpl_gbm_surface_t *gbm_surface = NULL; + tpl_gbm_display_t *gbm_display = NULL; + + if (surface == NULL) + { + TPL_ERR("tpl surface is invalid!!\n"); + return TPL_FALSE; + } + + gbm_surface = (tpl_gbm_surface_t*)surface->backend.data; + gbm_display = (tpl_gbm_display_t*)surface->display->backend.data; + + if (gbm_surface == NULL || gbm_display == NULL) + { + TPL_ERR("tpl surface has invalid members!!\n"); + return TPL_FALSE; + } + + return TPL_TRUE; +} + +static void +__tpl_gbm_surface_fini(tpl_surface_t *surface) +{ + tpl_gbm_surface_t *gbm_surface = NULL; + + TPL_ASSERT(surface); + + gbm_surface = (tpl_gbm_surface_t *) surface->backend.data; + if (NULL == gbm_surface) + return; + + TPL_LOG(3, "window(%p, %p)", surface, surface->native_handle); + + /* all back buffers will be freed in this function */ + __tpl_gbm_surface_render_buffers_free(gbm_surface, TPL_BUFFER_ALLOC_SIZE_MAX); + + free(gbm_surface); + surface->backend.data = NULL; +} + +static void +__tpl_gbm_surface_post(tpl_surface_t *surface, tpl_frame_t *frame) +{ + TPL_ASSERT(surface); + TPL_ASSERT(surface->display); + TPL_ASSERT(surface->display->native_handle); + TPL_ASSERT(frame); + TPL_ASSERT(frame->buffer); + + tpl_gbm_buffer_t *gbm_buffer = NULL; + + TPL_LOG(3, "window(%p, %p)", surface, surface->native_handle); + + tpl_gbm_surface_t *gbm_surface = (tpl_gbm_surface_t*)surface->backend.data; + tpl_buffer_t *buffer = NULL; + + if (!__tpl_list_is_empty(&gbm_surface->done_rendering_queue)) + { + buffer = __tpl_list_pop_front(&gbm_surface->done_rendering_queue, NULL); + + TPL_ASSERT(buffer); + + gbm_buffer = (tpl_gbm_buffer_t *) buffer->backend.data; + } + + tbm_surface_internal_unref(gbm_buffer->tbm_surface); + + if (gbm_surface->tbm_queue && gbm_buffer->tbm_surface) + { + tbm_surface_queue_enqueue(gbm_surface->tbm_queue, gbm_buffer->tbm_surface); + TPL_LOG(6, "tbm_surface ENQUEUED!!"); + } +} + +static tpl_bool_t +__tpl_gbm_surface_begin_frame(tpl_surface_t *surface) +{ + tpl_gbm_surface_t *gbm_surface; + + TPL_ASSERT(surface); + TPL_ASSERT(surface->display); + + gbm_surface = (tpl_gbm_surface_t *) surface->backend.data; + + TPL_ASSERT(gbm_surface->current_rendering_buffer == NULL); + + TPL_LOG(3, "window(%p, %p)", surface, surface->native_handle); + + return TPL_TRUE; +} + +static tpl_bool_t +__tpl_gbm_surface_validate_frame(tpl_surface_t *surface) +{ + TPL_IGNORE(surface); + + return TPL_TRUE; +} + +static tpl_bool_t +__tpl_gbm_surface_end_frame(tpl_surface_t *surface) +{ + tpl_gbm_surface_t *gbm_surface = NULL; + tpl_gbm_buffer_t *gbm_buffer = NULL; + + TPL_ASSERT(surface); + TPL_ASSERT(surface->display); + + gbm_surface = (tpl_gbm_surface_t *) surface->backend.data; + + TPL_LOG(3, "window(%p, %p)", surface, surface->native_handle); + + if (gbm_surface->current_rendering_buffer != NULL) + { + gbm_buffer = (tpl_gbm_buffer_t *) gbm_surface->current_rendering_buffer->backend.data; + + gbm_buffer->status = READY; + + TPL_LOG(6, "current_rendering_buffer BO:%d", tbm_bo_export(gbm_buffer->bo)); + } + + /* MOVE BUFFER : (current buffer) --> [done queue] */ + if (TPL_TRUE != __tpl_list_push_back(&gbm_surface->done_rendering_queue, gbm_surface->current_rendering_buffer)) + return TPL_FALSE; + + gbm_surface->current_rendering_buffer = NULL; + + return TPL_TRUE; +} + +static int +__tpl_gbm_get_depth_from_format(tpl_format_t format) +{ + int depth = 0; + + switch(format) + { + case TPL_FORMAT_BGR565: + case TPL_FORMAT_RGB565: + case TPL_FORMAT_ABGR4444: + case TPL_FORMAT_ARGB4444: + case TPL_FORMAT_BGRA4444: + case TPL_FORMAT_RGBA4444: + case TPL_FORMAT_ABGR1555: + case TPL_FORMAT_ARGB1555: + case TPL_FORMAT_BGRA5551: + case TPL_FORMAT_RGBA5551: + depth = 16; + break; + case TPL_FORMAT_ABGR8888: + case TPL_FORMAT_ARGB8888: + case TPL_FORMAT_BGRA8888: + case TPL_FORMAT_RGBA8888: + case TPL_FORMAT_XBGR8888: + case TPL_FORMAT_XRGB8888: + case TPL_FORMAT_BGRX8888: + case TPL_FORMAT_RGBX8888: + depth = 32; + break; + case TPL_FORMAT_BGR888: + case TPL_FORMAT_RGB888: + depth = 24; + break; + default: + depth = 32; + } + + return depth; +} + +static int tpl_buffer_key; +#define KEY_TPL_BUFFER (unsigned long)(&tpl_buffer_key) + +static inline tpl_buffer_t * +__tpl_gbm_surface_get_buffer_from_tbm_surface(tbm_surface_h surface) +{ + tbm_bo bo; + tpl_buffer_t* buf=NULL; + + bo = tbm_surface_internal_get_bo(surface, 0); + tbm_bo_get_user_data(bo, KEY_TPL_BUFFER, (void **)&buf); + + return buf; +} + +static inline void +__tpl_gbm_buffer_set_tbm_surface(tbm_surface_h surface, tpl_buffer_t *buf) +{ + tbm_bo bo; + + bo = tbm_surface_internal_get_bo(surface, 0); + tbm_bo_add_user_data(bo, KEY_TPL_BUFFER, NULL); + tbm_bo_set_user_data(bo, KEY_TPL_BUFFER, buf); +} + +static tpl_buffer_t * +__tpl_gbm_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl_bool_t *reset_buffers) +{ + tpl_buffer_t *buffer = NULL; + tpl_gbm_buffer_t *gbm_buffer = NULL; + tbm_bo bo; + tbm_surface_h tbm_surface = NULL; + tbm_surface_queue_error_e tsq_err = 0; + + tbm_bo_handle bo_handle; + int width, height, depth; + uint32_t size, offset, stride, key; + tpl_format_t format; + tpl_gbm_surface_t *gbm_surface = NULL; + tpl_gbm_display_t *gbm_display = NULL; + + TPL_ASSERT(surface); + TPL_ASSERT(surface->native_handle); + TPL_ASSERT(surface->display); + TPL_ASSERT(surface->display->native_handle); + + gbm_surface = (tpl_gbm_surface_t*)surface->backend.data; + gbm_display = (tpl_gbm_display_t*)surface->display->backend.data; + + tsq_err = tbm_surface_queue_dequeue(gbm_surface->tbm_queue, &tbm_surface); + if (tbm_surface == NULL) + { + TPL_LOG(6, "Wait until dequeable | tsq_err = %d", tsq_err); + tbm_surface_queue_can_dequeue(gbm_surface->tbm_queue, 1); + + tsq_err = tbm_surface_queue_dequeue(gbm_surface->tbm_queue, &tbm_surface); + if (tbm_surface == NULL) + { + TPL_ERR("Failed to get tbm_surface from tbm_surface_queue | tsq_err = %d",tsq_err); + return NULL; + } + } + + /* Inc ref count about tbm_surface */ + /* It will be dec when before tbm_surface_queue_enqueue called */ + tbm_surface_internal_ref(tbm_surface); + + if ((bo = tbm_surface_internal_get_bo(tbm_surface, 0)) == NULL) + { + TPL_ERR("Failed to get tbm_bo from tbm_surface"); + tbm_surface_internal_unref(tbm_surface); + return NULL; + } + + key = tbm_bo_export(bo); + + buffer = __tpl_gbm_surface_buffer_cache_find(&gbm_display->cached_buffers, key); + if (buffer != NULL) + { + return buffer; + } + + width = tbm_surface_get_width(tbm_surface); + height = tbm_surface_get_height(tbm_surface); + + switch(tbm_surface_get_format(tbm_surface)) + { + case TBM_FORMAT_ARGB8888: format = TPL_FORMAT_ARGB8888; break; + case TBM_FORMAT_XRGB8888: format = TPL_FORMAT_XRGB8888; break; + case TBM_FORMAT_RGB565: format = TPL_FORMAT_RGB565; break; + default: + format = TPL_FORMAT_INVALID; + TPL_ERR("No matched format!!"); + tbm_surface_internal_unref(tbm_surface); + return NULL; + } + + depth = __tpl_gbm_get_depth_from_format(format); + + /* Get pitch stride from tbm_surface */ + tbm_surface_internal_get_plane_data(tbm_surface, 0, &size, &offset, &stride); + + /* Create tpl buffer. */ + bo_handle = tbm_bo_get_handle(bo, TBM_DEVICE_3D); + + buffer = __tpl_buffer_alloc(surface, (size_t) key, + (int)bo_handle.u32, width, height, depth, stride); + + if (buffer == NULL) + { + TPL_ERR("Failed to allocate tpl buffer | surf:%p bo_hnd:%d WxHxD:%dx%dx%d", + surface, (int) bo_handle.u32, width, height, depth); + tbm_surface_internal_unref(tbm_surface); + return NULL; + } + + gbm_buffer = (tpl_gbm_buffer_t *) calloc(1, sizeof(tpl_gbm_buffer_t)); + if (gbm_buffer == NULL) + { + TPL_ERR("Mem alloc for gbm_buffer failed!"); + tpl_object_unreference((tpl_object_t *) buffer); + tbm_surface_internal_unref(tbm_surface); + return NULL; + } + + buffer->backend.data = (void *)gbm_buffer; + + /* Post process */ + gbm_buffer->display = surface->display; + gbm_buffer->bo = bo; + gbm_buffer->tbm_surface = tbm_surface; + + if (TPL_TRUE != __tpl_gbm_surface_buffer_cache_add(&gbm_display->cached_buffers, buffer)) + { + TPL_ERR("Adding surface to buffer cache failed!"); + tpl_object_unreference((tpl_object_t *) buffer); + tbm_surface_internal_unref(tbm_surface); + free(gbm_buffer); + return NULL; + } + + if (reset_buffers != NULL) + *reset_buffers = TPL_FALSE; + + TPL_LOG(3, "buffer:%p bo_hnd:%d, %dx%d", buffer, (int) bo_handle.u32, width, height); + __tpl_gbm_buffer_set_tbm_surface(tbm_surface, buffer); + + return buffer; +} + +static void +__tpl_gbm_buffer_destroy_notify(struct wl_listener *listener, void *data) +{ + tpl_display_t *display; + tpl_gbm_display_t *gbm_display; + tpl_gbm_buffer_t *gbm_buffer = NULL; + size_t key = 0; + + gbm_buffer = wl_container_of(listener, gbm_buffer, destroy_listener); + display = gbm_buffer->display; + key = tbm_bo_export(gbm_buffer->bo); + gbm_display = (tpl_gbm_display_t *)display->backend.data; + tpl_object_unreference((tpl_object_t *)gbm_buffer->tpl_buffer); + __tpl_gbm_surface_buffer_cache_remove(&gbm_display->cached_buffers, key); +} + +static tpl_buffer_t * +__tpl_gbm_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool_t *reset_buffers) +{ + tpl_buffer_t *buffer = NULL; + tpl_gbm_buffer_t *gbm_buffer = NULL; + tbm_surface_h tbm_surface = NULL; + /* TODO: If HW support getting of gem memory size, + use tbm_surface_get_info() with tbm_surface_info_s */ +#if 0 + tbm_surface_info_s tbm_surf_info; +#endif + tbm_bo bo; + tbm_bo_handle bo_handle; + + int width = 0, height = 0, depth; + uint32_t size, offset, stride; + tpl_format_t format = TPL_FORMAT_INVALID; + size_t key = 0; + + tpl_gbm_display_t *gbm_display; + + TPL_ASSERT(surface); + TPL_ASSERT(surface->display); + TPL_ASSERT(surface->native_handle); + + gbm_display = (tpl_gbm_display_t *) surface->display->backend.data; + + tbm_surface = wayland_tbm_server_get_surface(NULL, (struct wl_resource*)surface->native_handle); + if (tbm_surface == NULL) + { + TPL_ERR("Failed to get tbm surface!"); + return NULL; + } + + bo = tbm_surface_internal_get_bo(tbm_surface, 0); + key = tbm_bo_export(bo); + + buffer = __tpl_gbm_surface_buffer_cache_find(&gbm_display->cached_buffers, key); + if (buffer != NULL) + { + __tpl_buffer_set_surface(buffer, surface); + } + else + { + /* Inc ref count about tbm_surface */ + /* It will be dec when gbm_buffer_fini called*/ + tbm_surface_internal_ref(tbm_surface); + + if (TPL_TRUE != __tpl_gbm_display_get_pixmap_info( + surface->display, + surface->native_handle, + &width, &height, &format)) + { + TPL_ERR("Failed to get pixmap info!"); + tbm_surface_internal_unref(tbm_surface); + return NULL; + } + /* TODO: If HW support getting of gem memory size, + then replace tbm_surface_internal_get_plane_data() to tbm_surface_get_info() */ +#if 0 + if (tbm_surface_get_info(tbm_surface, &tbm_surf_info) != 0) + { + TPL_ERR("Failed to get stride info!"); + tbm_surface_internal_unref(tbm_surface); + return NULL; + } + stride = tbm_surf_info.planes[0].stride; +#else + if (!tbm_surface_internal_get_plane_data(tbm_surface, 0, &size, &offset, &stride)) + { + TPL_ERR("Failed to get tbm_surface stride info!"); + tbm_surface_internal_unref(tbm_surface); + return NULL; + } +#endif + depth = __tpl_gbm_get_depth_from_format(format); + + /* Create tpl buffer. */ + bo_handle = tbm_bo_get_handle(bo, TBM_DEVICE_3D); + if (NULL == bo_handle.ptr) + { + TPL_ERR("Failed to get bo handle!"); + tbm_surface_internal_unref(tbm_surface); + return NULL; + } + + buffer = __tpl_buffer_alloc(surface, key, + (int) bo_handle.u32, width, height, depth, stride); + if (buffer == NULL) + { + TPL_ERR("Failed to alloc TPL buffer!"); + tbm_surface_internal_unref(tbm_surface); + return NULL; + } + + gbm_buffer = (tpl_gbm_buffer_t *) calloc(1, sizeof(tpl_gbm_buffer_t)); + if (gbm_buffer == NULL) + { + TPL_ERR("Mem alloc failed for gbm buffer!"); + tpl_object_unreference((tpl_object_t *) buffer); + tbm_surface_internal_unref(tbm_surface); + return NULL; + } + + gbm_buffer->display = surface->display; + gbm_buffer->bo = bo; + gbm_buffer->tbm_surface = tbm_surface; + gbm_buffer->tpl_buffer = buffer; + + buffer->backend.data = (void *)gbm_buffer; + buffer->key = key; + + if (TPL_TRUE != __tpl_gbm_surface_buffer_cache_add(&gbm_display->cached_buffers, buffer)) + { + TPL_ERR("Adding surface to buffer cache failed!"); + tpl_object_unreference((tpl_object_t *) buffer); + tbm_surface_internal_unref(tbm_surface); + free(gbm_buffer); + return NULL; + } + + gbm_buffer->destroy_listener.notify = __tpl_gbm_buffer_destroy_notify; + wl_resource_add_destroy_listener((struct wl_resource*)surface->native_handle, &gbm_buffer->destroy_listener); + } + + if (reset_buffers != NULL) + *reset_buffers = TPL_FALSE; + + return buffer; +} + +static tpl_buffer_t * +__tpl_gbm_surface_get_buffer(tpl_surface_t *surface, tpl_bool_t *reset_buffers) +{ + int width, height; + tpl_gbm_surface_t *gbm_surface; + + TPL_ASSERT(surface); + TPL_ASSERT(surface->backend.data); + + gbm_surface = (tpl_gbm_surface_t *)surface->backend.data; + + if (reset_buffers != NULL) + *reset_buffers = TPL_FALSE; + + TPL_LOG(3, "window(%p, %p), current(%p)", surface, surface->native_handle, + gbm_surface->current_rendering_buffer); + + if (surface->type != TPL_SURFACE_TYPE_PIXMAP && + TPL_TRUE != __tpl_gbm_display_get_window_info(surface->display, + surface->native_handle, &width, &height, NULL, 0, 0)) + { + TPL_ERR("Failed to get window info!"); + return NULL; + } + + /* Check whether the surface was resized by wayland_egl */ + if (surface->type != TPL_SURFACE_TYPE_PIXMAP && + gbm_surface->current_rendering_buffer != NULL && + (width != gbm_surface->current_rendering_buffer->width || + height != gbm_surface->current_rendering_buffer->height)) + { + __tpl_gbm_surface_buffer_free(gbm_surface->current_rendering_buffer); + gbm_surface->current_rendering_buffer = NULL; + gbm_surface->back_buffers[gbm_surface->current_back_idx] = NULL; + + if (reset_buffers != NULL) + *reset_buffers = TPL_TRUE; + } + + if (gbm_surface->current_rendering_buffer == NULL) + { + if (surface->type == TPL_SURFACE_TYPE_WINDOW) + { + gbm_surface->current_rendering_buffer = + __tpl_gbm_surface_create_buffer_from_gbm_surface(surface, reset_buffers); + } + if (surface->type == TPL_SURFACE_TYPE_PIXMAP) + { + gbm_surface->current_rendering_buffer = + __tpl_gbm_surface_create_buffer_from_wl_tbm(surface, reset_buffers); + } + TPL_LOG(3, "window(%p, %p), current(%p)", surface, surface->native_handle, + gbm_surface->current_rendering_buffer); + } + + TPL_ASSERT(gbm_surface->current_rendering_buffer); + + return gbm_surface->current_rendering_buffer; +} + +static tpl_bool_t +__tpl_gbm_buffer_init(tpl_buffer_t *buffer) +{ + TPL_IGNORE(buffer); + + return TPL_TRUE; +} + +static void +__tpl_gbm_buffer_fini(tpl_buffer_t *buffer) +{ + TPL_ASSERT(buffer); + + TPL_LOG(3, "tpl_buffer(%p) key:%zu fd:%d %dx%d", buffer, buffer->key, buffer->fd, buffer->width, buffer->height); + + if (buffer->backend.data) + { + tpl_gbm_buffer_t *gbm_buffer = (tpl_gbm_buffer_t *)buffer->backend.data; + + if (gbm_buffer->bo != NULL && gbm_buffer->tbm_surface != NULL) + { + tbm_surface_internal_unref(gbm_buffer->tbm_surface); + tbm_surface_destroy(gbm_buffer->tbm_surface); + gbm_buffer->bo = NULL; + gbm_buffer->tbm_surface = NULL; + } + + buffer->backend.data = NULL; + free(gbm_buffer); + } +} + +static void * +__tpl_gbm_buffer_map(tpl_buffer_t *buffer, int size) +{ + tpl_gbm_buffer_t *gbm_buffer; + tbm_bo_handle handle; + + TPL_ASSERT(buffer); + TPL_ASSERT(buffer->backend.data); + + gbm_buffer = (tpl_gbm_buffer_t *) buffer->backend.data; + + TPL_ASSERT(gbm_buffer->bo); + + handle = tbm_bo_get_handle(gbm_buffer->bo, TBM_DEVICE_CPU); + return handle.ptr; +} + +static void +__tpl_gbm_buffer_unmap(tpl_buffer_t *buffer, void *ptr, int size) +{ + TPL_IGNORE(buffer); + TPL_IGNORE(ptr); + TPL_IGNORE(size); + + /* Do nothing. */ +} + +static tpl_bool_t +__tpl_gbm_buffer_lock(tpl_buffer_t *buffer, tpl_lock_usage_t usage) +{ + tpl_gbm_buffer_t *gbm_buffer; + tbm_bo_handle handle; + + TPL_ASSERT(buffer); + TPL_ASSERT(buffer->backend.data); + + gbm_buffer = (tpl_gbm_buffer_t *) buffer->backend.data; + + TPL_ASSERT(gbm_buffer->bo); + + TPL_OBJECT_UNLOCK(buffer); + + switch (usage) + { + case TPL_LOCK_USAGE_GPU_READ: + handle = tbm_bo_map(gbm_buffer->bo, TBM_DEVICE_3D, TBM_OPTION_READ); + break; + case TPL_LOCK_USAGE_GPU_WRITE: + handle = tbm_bo_map(gbm_buffer->bo, TBM_DEVICE_3D, TBM_OPTION_WRITE); + break; + case TPL_LOCK_USAGE_CPU_READ: + handle = tbm_bo_map(gbm_buffer->bo, TBM_DEVICE_CPU, TBM_OPTION_READ); + break; + case TPL_LOCK_USAGE_CPU_WRITE: + handle = tbm_bo_map(gbm_buffer->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE); + break; + default: + TPL_ERR("Unsupported buffer usage!"); + TPL_OBJECT_LOCK(buffer); + return TPL_FALSE; + } + + TPL_OBJECT_LOCK(buffer); + + if (handle.u32 != 0 || handle.ptr != NULL) + return TPL_FALSE; + + return TPL_TRUE; +} + +static void +__tpl_gbm_buffer_unlock(tpl_buffer_t *buffer) +{ + tpl_gbm_buffer_t *gbm_buffer; + + TPL_ASSERT(buffer); + TPL_ASSERT(buffer->backend.data); + + gbm_buffer = (tpl_gbm_buffer_t *) buffer->backend.data; + + TPL_ASSERT(gbm_buffer->bo); + + TPL_OBJECT_UNLOCK(buffer); + tbm_bo_unmap(gbm_buffer->bo); + TPL_OBJECT_LOCK(buffer); +} + +tpl_bool_t +__tpl_display_choose_backend_gbm(tpl_handle_t native_dpy) +{ + if (native_dpy == NULL) + return TPL_FALSE; + + if (__tpl_gbm_display_is_gbm_device(native_dpy)) + return TPL_TRUE; + + return TPL_FALSE; +} + +void +__tpl_display_init_backend_gbm(tpl_display_backend_t *backend) +{ + TPL_ASSERT(backend); + + backend->type = TPL_BACKEND_GBM; + backend->data = NULL; + + backend->init = __tpl_gbm_display_init; + backend->fini = __tpl_gbm_display_fini; + backend->query_config = __tpl_gbm_display_query_config; + backend->filter_config = __tpl_gbm_display_filter_config; + backend->get_window_info = __tpl_gbm_display_get_window_info; + backend->get_pixmap_info = __tpl_gbm_display_get_pixmap_info; + backend->flush = __tpl_gbm_display_flush; +#ifdef EGL_BIND_WL_DISPLAY + backend->bind_client_display_handle = __tpl_gbm_display_bind_client_wayland_display; + backend->unbind_client_display_handle = __tpl_gbm_display_unbind_client_wayland_display; +#endif +} + +void +__tpl_surface_init_backend_gbm(tpl_surface_backend_t *backend) +{ + TPL_ASSERT(backend); + + backend->type = TPL_BACKEND_GBM; + backend->data = NULL; + + backend->init = __tpl_gbm_surface_init; + backend->fini = __tpl_gbm_surface_fini; + backend->begin_frame = __tpl_gbm_surface_begin_frame; + backend->end_frame = __tpl_gbm_surface_end_frame; + backend->validate_frame = __tpl_gbm_surface_validate_frame; + backend->get_buffer = __tpl_gbm_surface_get_buffer; + backend->post = __tpl_gbm_surface_post; + backend->destroy_cached_buffers = __tpl_gbm_surface_destroy_cached_buffers; + backend->update_cached_buffers = __tpl_gbm_surface_update_cached_buffers; +} + +void +__tpl_buffer_init_backend_gbm(tpl_buffer_backend_t *backend) +{ + TPL_ASSERT(backend); + + backend->type = TPL_BACKEND_GBM; + backend->data = NULL; + + backend->init = __tpl_gbm_buffer_init; + backend->fini = __tpl_gbm_buffer_fini; + backend->map = __tpl_gbm_buffer_map; + backend->unmap = __tpl_gbm_buffer_unmap; + backend->lock = __tpl_gbm_buffer_lock; + backend->unlock = __tpl_gbm_buffer_unlock; + backend->create_native_buffer = NULL; +} + +#ifdef EGL_BIND_WL_DISPLAY +unsigned int __tpl_gbm_display_bind_client_wayland_display(tpl_display_t *tpl_display, tpl_handle_t native_dpy) +{ + tpl_gbm_display_t *tpl_gbm_display; + + TPL_ASSERT(tpl_display); + TPL_ASSERT(native_dpy); + + tpl_gbm_display = (tpl_gbm_display_t *) tpl_display->backend.data; + tpl_display->bufmgr_fd = dup(gbm_device_get_fd(tpl_display->native_handle)); + tpl_gbm_display->bufmgr = tbm_bufmgr_init(tpl_display->bufmgr_fd); + if (tpl_gbm_display->bufmgr == NULL) + { + TPL_ERR("TBM buffer manager initialization failed!"); + return TPL_FALSE; + } + + tpl_gbm_display->bound_client_display = TPL_TRUE; + return TPL_TRUE; +} + +unsigned int __tpl_gbm_display_unbind_client_wayland_display(tpl_display_t *tpl_display, tpl_handle_t native_dpy) +{ + tpl_gbm_display_t *tpl_gbm_display; + + TPL_ASSERT(tpl_display); + + tpl_gbm_display = (tpl_gbm_display_t *) tpl_display->backend.data; + + tbm_bufmgr_deinit(tpl_gbm_display->bufmgr); + close(tpl_display->bufmgr_fd); + tpl_gbm_display->bound_client_display = TPL_FALSE; + return TPL_TRUE; +} +#endif diff --git a/src/tpl_internal.h b/src/tpl_internal.h index e574218..37fe7f6 100644 --- a/src/tpl_internal.h +++ b/src/tpl_internal.h @@ -234,6 +234,7 @@ void __tpl_runtime_flush_all_display(); /* Backend initialization functions. */ tpl_backend_type_t __tpl_display_choose_backend(tpl_handle_t native_dpy); +tpl_bool_t __tpl_display_choose_backend_gbm(tpl_handle_t native_dpy); tpl_bool_t __tpl_display_choose_backend_wayland(tpl_handle_t native_dpy); tpl_bool_t __tpl_display_choose_backend_x11_dri2(tpl_handle_t native_dpy); tpl_bool_t __tpl_display_choose_backend_x11_dri3(tpl_handle_t native_dpy); @@ -242,14 +243,17 @@ void __tpl_display_init_backend(tpl_display_t *display, tpl_backend_type_t type) void __tpl_surface_init_backend(tpl_surface_t *surface, tpl_backend_type_t type); void __tpl_buffer_init_backend(tpl_buffer_t *buffer, tpl_backend_type_t type); +void __tpl_display_init_backend_gbm(tpl_display_backend_t *backend); void __tpl_display_init_backend_wayland(tpl_display_backend_t *backend); void __tpl_display_init_backend_x11_dri2(tpl_display_backend_t *backend); void __tpl_display_init_backend_x11_dri3(tpl_display_backend_t *backend); +void __tpl_surface_init_backend_gbm(tpl_surface_backend_t *backend); void __tpl_surface_init_backend_wayland(tpl_surface_backend_t *backend); void __tpl_surface_init_backend_x11_dri2(tpl_surface_backend_t *backend); void __tpl_surface_init_backend_x11_dri3(tpl_surface_backend_t *backend); +void __tpl_buffer_init_backend_gbm(tpl_buffer_backend_t *backend); void __tpl_buffer_init_backend_wayland(tpl_buffer_backend_t *backend); void __tpl_buffer_init_backend_x11_dri2(tpl_buffer_backend_t *backend); void __tpl_buffer_init_backend_x11_dri3(tpl_buffer_backend_t *backend); diff --git a/src/tpl_surface.c b/src/tpl_surface.c index 78da293..c552f99 100644 --- a/src/tpl_surface.c +++ b/src/tpl_surface.c @@ -437,13 +437,13 @@ tpl_surface_destroy_cached_buffers(tpl_surface_t *surface) if (NULL == surface) { TPL_ERR("Invalid surface!"); - return NULL; + return TPL_FALSE; } if (NULL == surface->backend.destroy_cached_buffers) { TPL_ERR("TPL surface has not been initialized correctly!"); - return NULL; + return TPL_FALSE; } TPL_OBJECT_LOCK(surface); @@ -461,13 +461,13 @@ tpl_surface_update_cached_buffers(tpl_surface_t *surface) if (NULL == surface) { TPL_ERR("Invalid surface!"); - return NULL; + return TPL_FALSE; } if (NULL == surface->backend.destroy_cached_buffers) { TPL_ERR("TPL surface has not been initialized correctly!"); - return NULL; + return TPL_FALSE; } TPL_OBJECT_LOCK(surface); diff --git a/src/tpl_wayland.c b/src/tpl_wayland.c index c46be5a..b25e11d 100644 --- a/src/tpl_wayland.c +++ b/src/tpl_wayland.c @@ -37,12 +37,6 @@ typedef struct _tpl_wayland_display tpl_wayland_display_t; typedef struct _tpl_wayland_surface tpl_wayland_surface_t; typedef struct _tpl_wayland_buffer tpl_wayland_buffer_t; -enum wayland_display_type -{ - SERVER, - CLIENT -}; - enum wayland_buffer_status { IDLE = 0, @@ -55,21 +49,9 @@ struct _tpl_wayland_display { tbm_bufmgr bufmgr; struct wayland_tbm_client *wl_tbm_client; - enum wayland_display_type type; - union - { - struct - { - tpl_bool_t authenticated; - struct wl_event_queue *wl_queue; - struct wl_registry *wl_registry; - } app; - struct - { - tpl_list_t cached_buffers; - tpl_bool_t bound_client_display; - } comp; - } proc; + tpl_bool_t authenticated; + struct wl_event_queue *wl_queue; + struct wl_registry *wl_registry; }; struct _tpl_wayland_surface @@ -88,22 +70,9 @@ struct _tpl_wayland_buffer tbm_bo bo; int reused; tpl_buffer_t *tpl_buffer; - enum wayland_buffer_status status; - union - { - struct - { - struct wl_proxy *wl_proxy; - tpl_bool_t resized; - } app; - struct - { - struct gbm_bo *gbm_bo; - tpl_bool_t posted; - struct wl_listener destroy_listener; - } comp; - } proc; + struct wl_proxy *wl_proxy; + tpl_bool_t resized; }; static const struct wl_registry_listener registry_listener; @@ -111,11 +80,6 @@ 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; -#ifdef EGL_BIND_WL_DISPLAY -unsigned int __tpl_wayland_display_bind_client_display(tpl_display_t *tpl_display, tpl_handle_t native_dpy); -unsigned int __tpl_wayland_display_unbind_client_display(tpl_display_t *tpl_display, tpl_handle_t native_dpy); -#endif - #define TPL_BUFFER_CACHE_MAX_ENTRIES 40 static TPL_INLINE tpl_bool_t @@ -228,22 +192,6 @@ __tpl_wayland_display_is_wl_display(tpl_handle_t native_dpy) return TPL_FALSE; } -static TPL_INLINE tpl_bool_t -__tpl_wayland_display_is_gbm_device(tpl_handle_t native_dpy) -{ - TPL_ASSERT(native_dpy); - - if (*(void **)native_dpy == &wl_display_interface) - return TPL_FALSE; - - /* MAGIC CHECK: A native display handle is a gbm_device if the de-referenced first value - is a memory address pointing gbm_create_surface(). */ - if (*(void **)native_dpy == gbm_create_device) - return TPL_TRUE; - - return TPL_FALSE; -} - static int __tpl_wayland_display_roundtrip(tpl_display_t *display) { @@ -262,11 +210,11 @@ __tpl_wayland_display_roundtrip(tpl_display_t *display) callback = wl_display_sync(wl_dpy); wl_callback_add_listener(callback, &sync_listener, &done); - wl_proxy_set_queue((struct wl_proxy *) callback, wayland_display->proc.app.wl_queue); + wl_proxy_set_queue((struct wl_proxy *) callback, wayland_display->wl_queue); while (ret != -1 && !done) { - ret = wl_display_dispatch_queue(wl_dpy, wayland_display->proc.app.wl_queue); + ret = wl_display_dispatch_queue(wl_dpy, wayland_display->wl_queue); } return ret; @@ -293,8 +241,6 @@ __tpl_wayland_display_init(tpl_display_t *display) if (__tpl_wayland_display_is_wl_display(display->native_handle)) { struct wl_display *wl_dpy = (struct wl_display *)display->native_handle; - - wayland_display->type = CLIENT; wayland_display->wl_tbm_client = wayland_tbm_client_init((struct wl_display *) wl_dpy); if (wayland_display->wl_tbm_client == NULL) @@ -303,28 +249,22 @@ __tpl_wayland_display_init(tpl_display_t *display) goto free_wl_display; } - wayland_display->proc.app.wl_queue = wl_display_create_queue(wl_dpy); - if (NULL == wayland_display->proc.app.wl_queue) + wayland_display->wl_queue = wl_display_create_queue(wl_dpy); + if (NULL == wayland_display->wl_queue) goto free_wl_display; - wayland_display->proc.app.wl_registry = wl_display_get_registry(wl_dpy); - if (NULL == wayland_display->proc.app.wl_registry) + wayland_display->wl_registry = wl_display_get_registry(wl_dpy); + if (NULL == wayland_display->wl_registry) goto destroy_queue; - wl_proxy_set_queue((struct wl_proxy *)wayland_display->proc.app.wl_registry, wayland_display->proc.app.wl_queue); - } - else if (__tpl_wayland_display_is_gbm_device(display->native_handle)) - { - wayland_display->type = SERVER; - - __tpl_list_init(&wayland_display->proc.comp.cached_buffers); + wl_proxy_set_queue((struct wl_proxy *)wayland_display->wl_registry, wayland_display->wl_queue); } else goto free_wl_display; return TPL_TRUE; destroy_queue: - wl_event_queue_destroy(wayland_display->proc.app.wl_queue); + wl_event_queue_destroy(wayland_display->wl_queue); free_wl_display: if (wayland_display != NULL) { @@ -344,18 +284,7 @@ __tpl_wayland_display_fini(tpl_display_t *display) wayland_display = (tpl_wayland_display_t *)display->backend.data; if (wayland_display != NULL) { - if (wayland_display->type == CLIENT) - { - wayland_tbm_client_deinit(wayland_display->wl_tbm_client); - } - if (wayland_display->type == SERVER) - { - if (wayland_display->proc.comp.bound_client_display) - __tpl_wayland_display_unbind_client_display(display, NULL); - - __tpl_list_fini(&wayland_display->proc.comp.cached_buffers, (tpl_free_func_t) tpl_object_unreference); - } - + wayland_tbm_client_deinit(wayland_display->wl_tbm_client); free(wayland_display); } display->backend.data = NULL; @@ -363,13 +292,11 @@ __tpl_wayland_display_fini(tpl_display_t *display) static tpl_bool_t __tpl_wayland_display_query_config(tpl_display_t *display, tpl_surface_type_t surface_type, - int red_size, int green_size, int blue_size, int alpha_size, - int color_depth, int *native_visual_id, tpl_bool_t *is_slow) + int red_size, int green_size, int blue_size, int alpha_size, + int color_depth, int *native_visual_id, tpl_bool_t *is_slow) { TPL_ASSERT(display); - tpl_wayland_display_t* wayland_display = (tpl_wayland_display_t*)display->backend.data; - if (surface_type == TPL_SURFACE_TYPE_WINDOW && red_size == 8 && green_size == 8 && @@ -378,39 +305,13 @@ __tpl_wayland_display_query_config(tpl_display_t *display, tpl_surface_type_t su { if (alpha_size == 8) { - if (wayland_display->type == CLIENT) - { - if (native_visual_id != NULL) *native_visual_id = TBM_FORMAT_ARGB8888; - } - else if (wayland_display->type == SERVER && - gbm_device_is_format_supported((struct gbm_device *)display->native_handle, - GBM_FORMAT_ARGB8888, - GBM_BO_USE_RENDERING) == 1) - { - if (native_visual_id != NULL) *native_visual_id = GBM_FORMAT_ARGB8888; - } - else - return TPL_FALSE; - + if (native_visual_id != NULL) *native_visual_id = TBM_FORMAT_ARGB8888; if (is_slow != NULL) *is_slow = TPL_FALSE; return TPL_TRUE; } if (alpha_size == 0) { - if (wayland_display->type == CLIENT) - { - if (native_visual_id != NULL) *native_visual_id = TBM_FORMAT_XRGB8888; - } - else if (wayland_display->type == SERVER && - gbm_device_is_format_supported((struct gbm_device *)display->native_handle, - GBM_FORMAT_XRGB8888, - GBM_BO_USE_RENDERING) == 1) - { - if (native_visual_id != NULL) *native_visual_id = GBM_FORMAT_XRGB8888; - } - else - return TPL_FALSE; - + if (native_visual_id != NULL) *native_visual_id = TBM_FORMAT_XRGB8888; if (is_slow != NULL) *is_slow = TPL_FALSE; return TPL_TRUE; } @@ -421,7 +322,7 @@ __tpl_wayland_display_query_config(tpl_display_t *display, tpl_surface_type_t su static tpl_bool_t __tpl_wayland_display_filter_config(tpl_display_t *display, - int *visual_id, int alpha_size) + int *visual_id, int alpha_size) { TPL_IGNORE(display); @@ -436,59 +337,33 @@ __tpl_wayland_display_filter_config(tpl_display_t *display, static tpl_bool_t __tpl_wayland_display_get_window_info(tpl_display_t *display, tpl_handle_t window, - int *width, int *height, tpl_format_t *format, int depth, int a_size) + int *width, int *height, tpl_format_t *format, int depth, int a_size) { TPL_ASSERT(display); TPL_ASSERT(window); - tpl_wayland_display_t* wayland_display = (tpl_wayland_display_t*)display->backend.data; + struct wl_egl_window *wl_egl_window = (struct wl_egl_window *)window; - if (wayland_display->type == CLIENT) + if (format != NULL) { - struct wl_egl_window *wl_egl_window = (struct wl_egl_window *)window; - - if (format != NULL) + /* Wayland-egl window doesn't have native format information. + It is fixed from 'EGLconfig' when called eglCreateWindowSurface(). + So we use the tpl_surface format instead. */ + tpl_surface_t *surface = wl_egl_window->private; + if (surface != NULL) + *format = surface->format; + else { - /* Wayland-egl window doesn't have native format information. - It is fixed from 'EGLconfig' when called eglCreateWindowSurface(). - So we use the tpl_surface format instead. */ - tpl_surface_t *surface = wl_egl_window->private; - if (surface != NULL) - *format = surface->format; - else - { - if (a_size == 8) - *format = TPL_FORMAT_ARGB8888; - else if (a_size == 0) - *format = TPL_FORMAT_XRGB8888; - } + if (a_size == 8) + *format = TPL_FORMAT_ARGB8888; + else if (a_size == 0) + *format = TPL_FORMAT_XRGB8888; } - if (width != NULL) *width = wl_egl_window->width; - if (height != NULL) *height = wl_egl_window->height; - - return TPL_TRUE; } - else if (wayland_display->type == SERVER) - { - struct gbm_surface *gbm_surface = (struct gbm_surface *)window; - tbm_surface_queue_h surf_queue = (tbm_surface_queue_h)gbm_tbm_get_surface_queue(gbm_surface); + if (width != NULL) *width = wl_egl_window->width; + if (height != NULL) *height = wl_egl_window->height; - if (format != NULL) - { - switch (tbm_surface_queue_get_format(surf_queue)) - { - case TBM_FORMAT_ARGB8888: *format = TPL_FORMAT_ARGB8888; break; - case TBM_FORMAT_XRGB8888: *format = TPL_FORMAT_XRGB8888; break; - case TBM_FORMAT_RGB565: *format = TPL_FORMAT_RGB565; break; - default: *format = TPL_FORMAT_INVALID; break; - } - } - if (width != NULL) *width = tbm_surface_queue_get_width(surf_queue); - if (height != NULL) *height = tbm_surface_queue_get_height(surf_queue); - return TPL_TRUE; - } - - return TPL_FALSE; + return TPL_TRUE; } static tpl_bool_t @@ -533,7 +408,6 @@ static tpl_bool_t __tpl_wayland_surface_init(tpl_surface_t *surface) { tpl_wayland_surface_t *wayland_surface = NULL; - tpl_wayland_display_t *wayland_display = NULL; int i; TPL_ASSERT(surface); @@ -548,25 +422,15 @@ __tpl_wayland_surface_init(tpl_surface_t *surface) __tpl_list_init(&wayland_surface->done_rendering_queue); - wayland_display = (tpl_wayland_display_t*)surface->display->backend.data; - if (surface->type == TPL_SURFACE_TYPE_WINDOW) { - if (wayland_display->type == CLIENT) - { - struct wl_egl_window *wl_egl_window = (struct wl_egl_window *)surface->native_handle; - wl_egl_window->private = surface; - - /* Create renderable buffer queue. Fill with empty(=NULL) buffers. */ - for (i = 0; i < TPL_BUFFER_ALLOC_SIZE_APP; i++) - { - wayland_surface->back_buffers[i] = NULL; - } - } - if (wayland_display->type == SERVER) + struct wl_egl_window *wl_egl_window = (struct wl_egl_window *)surface->native_handle; + wl_egl_window->private = surface; + + /* Create renderable buffer queue. Fill with empty(=NULL) buffers. */ + for (i = 0; i < TPL_BUFFER_ALLOC_SIZE_APP; i++) { - struct gbm_surface *gbm_surface = (struct gbm_surface*)surface->native_handle; - wayland_surface->tbm_queue = (tbm_surface_queue_h)gbm_tbm_get_surface_queue(gbm_surface); + wayland_surface->back_buffers[i] = NULL; } if (TPL_TRUE != __tpl_wayland_display_get_window_info(surface->display, surface->native_handle, @@ -681,8 +545,7 @@ __tpl_wayland_surface_destroy_cached_buffers(tpl_surface_t *surface) return TPL_FALSE; } - if (wayland_display->type == CLIENT) - __tpl_wayland_surface_render_buffers_free(wayland_surface, TPL_BUFFER_ALLOC_SIZE_APP); + __tpl_wayland_surface_render_buffers_free(wayland_surface, TPL_BUFFER_ALLOC_SIZE_APP); return TPL_TRUE; } @@ -692,6 +555,7 @@ __tpl_wayland_surface_update_cached_buffers(tpl_surface_t *surface) { tpl_wayland_surface_t *wayland_surface = NULL; tpl_wayland_display_t *wayland_display = NULL; + int i; if (surface == NULL) { @@ -708,20 +572,16 @@ __tpl_wayland_surface_update_cached_buffers(tpl_surface_t *surface) return TPL_FALSE; } - if (wayland_display->type == CLIENT) + for (i = 0; i < TPL_BUFFER_ALLOC_SIZE_APP; i++) { - int i; - for (i = 0; i < TPL_BUFFER_ALLOC_SIZE_APP; i++) + tpl_buffer_t *cached_buffer = wayland_surface->back_buffers[i]; + + if (cached_buffer != NULL && + (surface->width != wayland_surface->back_buffers[i]->width || + surface->height != wayland_surface->back_buffers[i]->height)) { - tpl_buffer_t *cached_buffer = wayland_surface->back_buffers[i]; - - if (cached_buffer != NULL && - (surface->width != wayland_surface->back_buffers[i]->width || - surface->height != wayland_surface->back_buffers[i]->height)) - { - __tpl_wayland_surface_buffer_free(wayland_surface->back_buffers[i]); - wayland_surface->back_buffers[i] = NULL; - } + __tpl_wayland_surface_buffer_free(wayland_surface->back_buffers[i]); + wayland_surface->back_buffers[i] = NULL; } } @@ -732,15 +592,11 @@ static void __tpl_wayland_surface_fini(tpl_surface_t *surface) { tpl_wayland_surface_t *wayland_surface = NULL; - tpl_wayland_display_t *wayland_display = NULL; TPL_ASSERT(surface); wayland_surface = (tpl_wayland_surface_t *) surface->backend.data; - if (NULL == wayland_surface) - return; - - wayland_display = (tpl_wayland_display_t *) surface->display->backend.data; + if (NULL == wayland_surface) return; TPL_LOG(3, "window(%p, %p)", surface, surface->native_handle); @@ -749,27 +605,24 @@ __tpl_wayland_surface_fini(tpl_surface_t *surface) if (surface->type == TPL_SURFACE_TYPE_WINDOW) { - if (wayland_display->type == CLIENT) - { - struct wl_egl_window *wl_egl_window = (struct wl_egl_window *)surface->native_handle; + struct wl_egl_window *wl_egl_window = (struct wl_egl_window *)surface->native_handle; - TPL_ASSERT(wl_egl_window); - /* TPL_ASSERT(wl_egl_window->surface); */ /* to be enabled once evas/gl patch is in place */ + TPL_ASSERT(wl_egl_window); + /* TPL_ASSERT(wl_egl_window->surface); */ /* to be enabled once evas/gl patch is in place */ - wl_egl_window->private = NULL; + 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 */ + /* 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(surface->display->native_handle); - __tpl_wayland_display_roundtrip(surface->display); + { + wl_surface_attach(wl_egl_window->surface, NULL, 0, 0); + wl_surface_commit(wl_egl_window->surface); } + + wl_display_flush(surface->display->native_handle); + __tpl_wayland_display_roundtrip(surface->display); } free(wayland_surface); @@ -790,79 +643,54 @@ __tpl_wayland_surface_post(tpl_surface_t *surface, tpl_frame_t *frame) TPL_LOG(3, "window(%p, %p)", surface, surface->native_handle); - if (wayland_display->type == CLIENT) - { - wayland_buffer = (tpl_wayland_buffer_t *)frame->buffer->backend.data; - struct wl_egl_window *wl_egl_window = NULL; - int i; - tbm_bo_handle bo_handle = tbm_bo_get_handle(wayland_buffer->bo , TBM_DEVICE_CPU); - if (bo_handle.ptr != NULL) - TPL_IMAGE_DUMP(bo_handle.ptr, surface->width, surface->height, surface->dump_count++); - TPL_LOG(3, "\t buffer(%p, %p) key:%zu", frame->buffer, wayland_buffer->proc.app.wl_proxy, frame->buffer->key); - - wl_egl_window = (struct wl_egl_window *)surface->native_handle; - - tpl_object_reference((tpl_object_t *)frame->buffer); - wl_surface_attach(wl_egl_window->surface, - (void *)wayland_buffer->proc.app.wl_proxy, + wayland_buffer = (tpl_wayland_buffer_t *)frame->buffer->backend.data; + struct wl_egl_window *wl_egl_window = NULL; + int i; + tbm_bo_handle bo_handle = tbm_bo_get_handle(wayland_buffer->bo , TBM_DEVICE_CPU); + if (bo_handle.ptr != NULL) + TPL_IMAGE_DUMP(bo_handle.ptr, surface->width, surface->height, surface->dump_count++); + TPL_LOG(3, "\t buffer(%p, %p) key:%zu", frame->buffer, wayland_buffer->wl_proxy, frame->buffer->key); + + wl_egl_window = (struct wl_egl_window *)surface->native_handle; + + tpl_object_reference((tpl_object_t *)frame->buffer); + wl_surface_attach(wl_egl_window->surface, + (void *)wayland_buffer->wl_proxy, wl_egl_window->dx, wl_egl_window->dy); - wl_egl_window->attached_width = wl_egl_window->width; - wl_egl_window->attached_height = wl_egl_window->height; + wl_egl_window->attached_width = wl_egl_window->width; + wl_egl_window->attached_height = wl_egl_window->height; - for (i = 0; i < frame->damage.num_rects; i++) - { - wl_surface_damage(wl_egl_window->surface, + for (i = 0; i < frame->damage.num_rects; i++) + { + wl_surface_damage(wl_egl_window->surface, frame->damage.rects[i * 4 + 0], frame->damage.rects[i * 4 + 1], frame->damage.rects[i * 4 + 2], frame->damage.rects[i * 4 + 3]); - } - if (frame->damage.num_rects == 0) { - wl_surface_damage(wl_egl_window->surface, - wl_egl_window->dx, wl_egl_window->dy, - wl_egl_window->width, wl_egl_window->height); - } - - { - /* Register a meaningless surface frame callback. - Because the buffer_release callback only be triggered if this callback is registered. */ - struct wl_callback *frame_callback = NULL; - frame_callback = wl_surface_frame(wl_egl_window->surface); - wl_callback_add_listener(frame_callback, &frame_listener, frame->buffer); - wl_proxy_set_queue((struct wl_proxy *)frame_callback, wayland_display->proc.app.wl_queue); - } - wl_surface_commit(wl_egl_window->surface); - - wl_display_flush(surface->display->native_handle); - - wayland_buffer->status = POSTED; - - TPL_LOG(7, "BO:%d", tbm_bo_export(wayland_buffer->bo)); } - else if (wayland_display->type == SERVER) - { - tpl_wayland_surface_t *wayland_surface = (tpl_wayland_surface_t*)surface->backend.data; - tpl_buffer_t *buffer = NULL; + if (frame->damage.num_rects == 0) { + wl_surface_damage(wl_egl_window->surface, + wl_egl_window->dx, wl_egl_window->dy, + wl_egl_window->width, wl_egl_window->height); + } - if (!__tpl_list_is_empty(&wayland_surface->done_rendering_queue)) - { - buffer = __tpl_list_pop_front(&wayland_surface->done_rendering_queue, NULL); + { + /* Register a meaningless surface frame callback. + Because the buffer_release callback only be triggered if this callback is registered. */ + struct wl_callback *frame_callback = NULL; + frame_callback = wl_surface_frame(wl_egl_window->surface); + wl_callback_add_listener(frame_callback, &frame_listener, frame->buffer); + wl_proxy_set_queue((struct wl_proxy *)frame_callback, wayland_display->wl_queue); + } + wl_surface_commit(wl_egl_window->surface); - TPL_ASSERT(buffer); + wl_display_flush(surface->display->native_handle); - wayland_buffer = (tpl_wayland_buffer_t *) buffer->backend.data; - } + wayland_buffer->status = POSTED; - tbm_surface_internal_unref(wayland_buffer->tbm_surface); - - if (wayland_surface->tbm_queue && wayland_buffer->tbm_surface) - { - tbm_surface_queue_enqueue(wayland_surface->tbm_queue, wayland_buffer->tbm_surface); - TPL_LOG(6, "tbm_surface ENQUEUED!!"); - } - } + TPL_LOG(7, "BO:%d", tbm_bo_export(wayland_buffer->bo)); } static tpl_bool_t @@ -881,28 +709,22 @@ __tpl_wayland_surface_begin_frame(tpl_surface_t *surface) TPL_LOG(3, "window(%p, %p)", surface, surface->native_handle); - if (wayland_display->type == CLIENT) - { - TPL_OBJECT_UNLOCK(surface); - - __tpl_wayland_display_roundtrip(surface->display); + TPL_OBJECT_UNLOCK(surface); + __tpl_wayland_display_roundtrip(surface->display); - while (__tpl_wayland_surface_get_idle_buffer_idx(wayland_surface, TPL_BUFFER_ALLOC_SIZE_APP) == -1) + while (__tpl_wayland_surface_get_idle_buffer_idx(wayland_surface, TPL_BUFFER_ALLOC_SIZE_APP) == -1) + { + /* Application sent all buffers to the server. Wait for server response. */ + if (wl_display_dispatch_queue(surface->display->native_handle, wayland_display->wl_queue) == -1) { - /* Application sent all buffers to the server. Wait for server response. */ - if (wl_display_dispatch_queue(surface->display->native_handle, wayland_display->proc.app.wl_queue) == -1) - { - TPL_OBJECT_LOCK(surface); - return TPL_FALSE; - } + TPL_OBJECT_LOCK(surface); + return TPL_FALSE; } - - TPL_OBJECT_LOCK(surface); } - if (wayland_display->type == CLIENT) - wayland_surface->current_rendering_buffer = wayland_surface->back_buffers[wayland_surface->current_back_idx]; + TPL_OBJECT_LOCK(surface); + wayland_surface->current_rendering_buffer = wayland_surface->back_buffers[wayland_surface->current_back_idx]; - if ( wayland_display->type == CLIENT && wayland_surface->current_rendering_buffer ) + if (wayland_surface->current_rendering_buffer) { tpl_wayland_buffer_t *wayland_buffer = (tpl_wayland_buffer_t*)wayland_surface->current_rendering_buffer->backend.data; wayland_buffer->status = BUSY; @@ -1138,14 +960,14 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool return NULL; } - wl_proxy_set_queue(wl_proxy, wayland_display->proc.app.wl_queue); + wl_proxy_set_queue(wl_proxy, wayland_display->wl_queue); wl_buffer_add_listener((void *)wl_proxy, &buffer_release_listener, buffer); wl_display_flush((struct wl_display *)surface->display->native_handle); wayland_buffer->display = surface->display; wayland_buffer->tbm_surface = tbm_surface; - wayland_buffer->proc.app.wl_proxy = wl_proxy; + wayland_buffer->wl_proxy = wl_proxy; wayland_buffer->bo = bo; wayland_buffer->status = BUSY; @@ -1156,7 +978,7 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool *reset_buffers = TPL_FALSE; TPL_LOG(3, "buffer(%p,%p) name:%d, %dx%d", buffer, wl_proxy, name, width, height); - TPL_LOG(4, "buffer->backend.data : %p", buffer->backend.data); + TPL_LOG(4, "buffer->backend.data : %p", buffer->backend.data); return buffer; } @@ -1167,112 +989,105 @@ static int tpl_buffer_key; static inline tpl_buffer_t * __tpl_wayland_surface_get_buffer_from_tbm_surface(tbm_surface_h surface) { - tbm_bo bo; - tpl_buffer_t* buf=NULL; + tbm_bo bo; + tpl_buffer_t* buf=NULL; - bo = tbm_surface_internal_get_bo(surface, 0); - tbm_bo_get_user_data(bo, KEY_TPL_BUFFER, (void **)&buf); + bo = tbm_surface_internal_get_bo(surface, 0); + tbm_bo_get_user_data(bo, KEY_TPL_BUFFER, (void **)&buf); - return buf; + return buf; } -static inline void + static inline void __tpl_wayland_buffer_set_tbm_surface(tbm_surface_h surface, tpl_buffer_t *buf) { - tbm_bo bo; + tbm_bo bo; - bo = tbm_surface_internal_get_bo(surface, 0); - tbm_bo_add_user_data(bo, KEY_TPL_BUFFER, NULL); - tbm_bo_set_user_data(bo, KEY_TPL_BUFFER, buf); + bo = tbm_surface_internal_get_bo(surface, 0); + tbm_bo_add_user_data(bo, KEY_TPL_BUFFER, NULL); + tbm_bo_set_user_data(bo, KEY_TPL_BUFFER, buf); } static tpl_buffer_t * -__tpl_wayland_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl_bool_t *reset_buffers) +__tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool_t *reset_buffers) { tpl_buffer_t *buffer = NULL; tpl_wayland_buffer_t *wayland_buffer = NULL; - tbm_bo bo; tbm_surface_h tbm_surface = NULL; - tbm_surface_queue_error_e tsq_err = 0; - + /* TODO: If HW support getting of gem memory size, + use tbm_surface_get_info() with tbm_surface_info_s */ +#if 0 + tbm_surface_info_s tbm_surf_info; +#endif + tbm_bo bo; tbm_bo_handle bo_handle; - int width, height, depth; - uint32_t size, offset, stride, key; - tpl_format_t format; - tpl_wayland_surface_t *wayland_surface = NULL; - tpl_wayland_display_t *wayland_display = NULL; + + int width = 0, height = 0, depth; + uint32_t size, offset, stride; + tpl_format_t format = TPL_FORMAT_INVALID; + size_t key = 0; TPL_ASSERT(surface); - TPL_ASSERT(surface->native_handle); TPL_ASSERT(surface->display); - TPL_ASSERT(surface->display->native_handle); - - wayland_surface = (tpl_wayland_surface_t*)surface->backend.data; - wayland_display = (tpl_wayland_display_t*)surface->display->backend.data; + TPL_ASSERT(surface->native_handle); - tsq_err = tbm_surface_queue_dequeue(wayland_surface->tbm_queue, &tbm_surface); + tbm_surface = wayland_tbm_server_get_surface(NULL, (struct wl_resource*)surface->native_handle); if (tbm_surface == NULL) { - TPL_LOG(6, "Wait until dequeable | tsq_err = %d", tsq_err); - tbm_surface_queue_can_dequeue(wayland_surface->tbm_queue, 1); - - tsq_err = tbm_surface_queue_dequeue(wayland_surface->tbm_queue, &tbm_surface); - if (tbm_surface == NULL) - { - TPL_ERR("Failed to get tbm_surface from tbm_surface_queue | tsq_err = %d",tsq_err); - return NULL; - } + TPL_ERR("Failed to get tbm surface!"); + return NULL; } + bo = tbm_surface_internal_get_bo(tbm_surface, 0); + key = tbm_bo_export(bo); + /* Inc ref count about tbm_surface */ - /* It will be dec when before tbm_surface_queue_enqueue called */ + /* It will be dec when wayland_buffer_fini called*/ tbm_surface_internal_ref(tbm_surface); - if ((bo = tbm_surface_internal_get_bo(tbm_surface, 0)) == NULL) + if (TPL_TRUE != __tpl_wayland_display_get_pixmap_info( + surface->display, + surface->native_handle, + &width, &height, &format)) { - TPL_ERR("Failed to get tbm_bo from tbm_surface"); + TPL_ERR("Failed to get pixmap info!"); tbm_surface_internal_unref(tbm_surface); return NULL; } - - key = tbm_bo_export(bo); - - buffer = __tpl_wayland_surface_buffer_cache_find(&wayland_display->proc.comp.cached_buffers, key); - if (buffer != NULL) + /* TODO: If HW support getting of gem memory size, + then replace tbm_surface_internal_get_plane_data() to tbm_surface_get_info() */ +#if 0 + if (tbm_surface_get_info(tbm_surface, &tbm_surf_info) != 0) { - return buffer; + TPL_ERR("Failed to get stride info!"); + tbm_surface_internal_unref(tbm_surface); + return NULL; } - - width = tbm_surface_get_width(tbm_surface); - height = tbm_surface_get_height(tbm_surface); - - switch(tbm_surface_get_format(tbm_surface)) + stride = tbm_surf_info.planes[0].stride; +#else + if (!tbm_surface_internal_get_plane_data(tbm_surface, 0, &size, &offset, &stride)) { - case TBM_FORMAT_ARGB8888: format = TPL_FORMAT_ARGB8888; break; - case TBM_FORMAT_XRGB8888: format = TPL_FORMAT_XRGB8888; break; - case TBM_FORMAT_RGB565: format = TPL_FORMAT_RGB565; break; - default: - format = TPL_FORMAT_INVALID; - TPL_ERR("No matched format!!"); + TPL_ERR("Failed to get tbm_surface stride info!"); tbm_surface_internal_unref(tbm_surface); return NULL; } - +#endif depth = __tpl_wayland_get_depth_from_format(format); - /* Get pitch stride from tbm_surface */ - tbm_surface_internal_get_plane_data(tbm_surface, 0, &size, &offset, &stride); - /* Create tpl buffer. */ bo_handle = tbm_bo_get_handle(bo, TBM_DEVICE_3D); + if (NULL == bo_handle.ptr) + { + TPL_ERR("Failed to get bo handle!"); + tbm_surface_internal_unref(tbm_surface); + return NULL; + } - buffer = __tpl_buffer_alloc(surface, (size_t) key, - (int)bo_handle.u32, width, height, depth, stride); - - if (buffer == NULL) + buffer = __tpl_buffer_alloc(surface, key, + (int) bo_handle.u32, width, height, depth, stride); + if (buffer == NULL) { - TPL_ERR("Failed to allocate tpl buffer | surf:%p bo_hnd:%d WxHxD:%dx%dx%d", - surface, (int) bo_handle.u32, width, height, depth); + TPL_ERR("Failed to alloc TPL buffer!"); tbm_surface_internal_unref(tbm_surface); return NULL; } @@ -1280,178 +1095,19 @@ __tpl_wayland_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl wayland_buffer = (tpl_wayland_buffer_t *) calloc(1, sizeof(tpl_wayland_buffer_t)); if (wayland_buffer == NULL) { - TPL_ERR("Mem alloc for wayland_buffer failed!"); + TPL_ERR("Mem alloc failed for wayland buffer!"); tpl_object_unreference((tpl_object_t *) buffer); tbm_surface_internal_unref(tbm_surface); return NULL; } - buffer->backend.data = (void *)wayland_buffer; - - /* Post process */ wayland_buffer->display = surface->display; wayland_buffer->bo = bo; wayland_buffer->tbm_surface = tbm_surface; + wayland_buffer->tpl_buffer = buffer; - if (TPL_TRUE != __tpl_wayland_surface_buffer_cache_add(&wayland_display->proc.comp.cached_buffers, buffer)) - { - TPL_ERR("Adding surface to buffer cache failed!"); - tpl_object_unreference((tpl_object_t *) buffer); - tbm_surface_internal_unref(tbm_surface); - free(wayland_buffer); - return NULL; - } - - if (reset_buffers != NULL) - *reset_buffers = TPL_FALSE; - - TPL_LOG(3, "buffer:%p bo_hnd:%d, %dx%d", buffer, (int) bo_handle.u32, width, height); - __tpl_wayland_buffer_set_tbm_surface(tbm_surface, buffer); - - return buffer; -} - -static void -__tpl_wayland_buffer_destroy_notify(struct wl_listener *listener, void *data) -{ - tpl_display_t *display; - tpl_wayland_display_t *wayland_display; - tpl_wayland_buffer_t *wayland_buffer = NULL; - size_t key = 0; - int ref; - - wayland_buffer = wl_container_of(listener, wayland_buffer, proc.comp.destroy_listener); - display = wayland_buffer->display; - key = tbm_bo_export(wayland_buffer->bo); - wayland_display = (tpl_wayland_display_t *)display->backend.data; - tpl_object_unreference((tpl_object_t *)wayland_buffer->tpl_buffer); - __tpl_wayland_surface_buffer_cache_remove(&wayland_display->proc.comp.cached_buffers, key); -} - -static tpl_buffer_t * -__tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool_t *reset_buffers) -{ - tpl_buffer_t *buffer = NULL; - tpl_wayland_buffer_t *wayland_buffer = NULL; - tbm_surface_h tbm_surface = NULL; - /* TODO: If HW support getting of gem memory size, - use tbm_surface_get_info() with tbm_surface_info_s */ -#if 0 - tbm_surface_info_s tbm_surf_info; -#endif - tbm_bo bo; - tbm_bo_handle bo_handle; - - int width = 0, height = 0, depth; - uint32_t size, offset, stride; - tpl_format_t format = TPL_FORMAT_INVALID; - size_t key = 0; - - tpl_wayland_display_t *wayland_display; - - TPL_ASSERT(surface); - TPL_ASSERT(surface->display); - TPL_ASSERT(surface->native_handle); - - wayland_display = (tpl_wayland_display_t *) surface->display->backend.data; - - tbm_surface = wayland_tbm_server_get_surface(NULL, (struct wl_resource*)surface->native_handle); - if (tbm_surface == NULL) - { - TPL_ERR("Failed to get tbm surface!"); - return NULL; - } - - bo = tbm_surface_internal_get_bo(tbm_surface, 0); - key = tbm_bo_export(bo); - - buffer = __tpl_wayland_surface_buffer_cache_find(&wayland_display->proc.comp.cached_buffers, key); - if (buffer != NULL) - { - __tpl_buffer_set_surface(buffer, surface); - } - else - { - /* Inc ref count about tbm_surface */ - /* It will be dec when wayland_buffer_fini called*/ - tbm_surface_internal_ref(tbm_surface); - - if (TPL_TRUE != __tpl_wayland_display_get_pixmap_info( - surface->display, - surface->native_handle, - &width, &height, &format)) - { - TPL_ERR("Failed to get pixmap info!"); - tbm_surface_internal_unref(tbm_surface); - return NULL; - } - /* TODO: If HW support getting of gem memory size, - then replace tbm_surface_internal_get_plane_data() to tbm_surface_get_info() */ -#if 0 - if (tbm_surface_get_info(tbm_surface, &tbm_surf_info) != 0) - { - TPL_ERR("Failed to get stride info!"); - tbm_surface_internal_unref(tbm_surface); - return NULL; - } - stride = tbm_surf_info.planes[0].stride; -#else - if (!tbm_surface_internal_get_plane_data(tbm_surface, 0, &size, &offset, &stride)) - { - TPL_ERR("Failed to get tbm_surface stride info!"); - tbm_surface_internal_unref(tbm_surface); - return NULL; - } -#endif - depth = __tpl_wayland_get_depth_from_format(format); - - /* Create tpl buffer. */ - bo_handle = tbm_bo_get_handle(bo, TBM_DEVICE_3D); - if (NULL == bo_handle.ptr) - { - TPL_ERR("Failed to get bo handle!"); - tbm_surface_internal_unref(tbm_surface); - return NULL; - } - - buffer = __tpl_buffer_alloc(surface, key, - (int) bo_handle.u32, width, height, depth, stride); - if (buffer == NULL) - { - TPL_ERR("Failed to alloc TPL buffer!"); - tbm_surface_internal_unref(tbm_surface); - return NULL; - } - - wayland_buffer = (tpl_wayland_buffer_t *) calloc(1, sizeof(tpl_wayland_buffer_t)); - if (wayland_buffer == NULL) - { - TPL_ERR("Mem alloc failed for wayland buffer!"); - tpl_object_unreference((tpl_object_t *) buffer); - tbm_surface_internal_unref(tbm_surface); - return NULL; - } - - wayland_buffer->display = surface->display; - wayland_buffer->bo = bo; - wayland_buffer->tbm_surface = tbm_surface; - wayland_buffer->tpl_buffer = buffer; - - buffer->backend.data = (void *)wayland_buffer; - buffer->key = key; - - if (TPL_TRUE != __tpl_wayland_surface_buffer_cache_add(&wayland_display->proc.comp.cached_buffers, buffer)) - { - TPL_ERR("Adding surface to buffer cache failed!"); - tpl_object_unreference((tpl_object_t *) buffer); - tbm_surface_internal_unref(tbm_surface); - free(wayland_buffer); - return NULL; - } - - wayland_buffer->proc.comp.destroy_listener.notify = __tpl_wayland_buffer_destroy_notify; - wl_resource_add_destroy_listener((struct wl_resource*)surface->native_handle, &wayland_buffer->proc.comp.destroy_listener); - } + buffer->backend.data = (void *)wayland_buffer; + buffer->key = key; if (reset_buffers != NULL) *reset_buffers = TPL_FALSE; @@ -1464,13 +1120,11 @@ __tpl_wayland_surface_get_buffer(tpl_surface_t *surface, tpl_bool_t *reset_buffe { int width, height; tpl_wayland_surface_t *wayland_surface; - tpl_wayland_display_t *wayland_display; TPL_ASSERT(surface); TPL_ASSERT(surface->backend.data); wayland_surface = (tpl_wayland_surface_t *)surface->backend.data; - wayland_display = (tpl_wayland_display_t *)surface->display->backend.data; if (reset_buffers != NULL) *reset_buffers = TPL_FALSE; @@ -1504,27 +1158,19 @@ __tpl_wayland_surface_get_buffer(tpl_surface_t *surface, tpl_bool_t *reset_buffe { if (surface->type == TPL_SURFACE_TYPE_WINDOW) { - if (wayland_display->type == CLIENT) - { - wayland_surface->current_rendering_buffer = - __tpl_wayland_surface_create_buffer_from_wl_egl(surface, reset_buffers); - } - if (wayland_display->type == SERVER) - { - wayland_surface->current_rendering_buffer = - __tpl_wayland_surface_create_buffer_from_gbm_surface(surface, reset_buffers); - } + wayland_surface->current_rendering_buffer = + __tpl_wayland_surface_create_buffer_from_wl_egl(surface, reset_buffers); } if (surface->type == TPL_SURFACE_TYPE_PIXMAP) { - wayland_surface->current_rendering_buffer = + wayland_surface->current_rendering_buffer = __tpl_wayland_surface_create_buffer_from_wl_tbm(surface, reset_buffers); } TPL_LOG(3, "window(%p, %p), current(%p)", surface, surface->native_handle, wayland_surface->current_rendering_buffer); } - TPL_ASSERT(wayland_surface->current_rendering_buffer); + TPL_ASSERT(wayland_surface->current_rendering_buffer); return wayland_surface->current_rendering_buffer; } @@ -1559,13 +1205,10 @@ __tpl_wayland_buffer_fini(tpl_buffer_t *buffer) wayland_buffer->tbm_surface = NULL; } - if (wayland_display->type == CLIENT) - { - wl_display_flush((struct wl_display *)wayland_buffer->display->native_handle); + wl_display_flush((struct wl_display *)wayland_buffer->display->native_handle); - if (wayland_buffer->proc.app.wl_proxy != NULL) - wayland_tbm_client_destroy_buffer(wayland_display->wl_tbm_client, (void *)wayland_buffer->proc.app.wl_proxy); - } + if (wayland_buffer->wl_proxy != NULL) + wayland_tbm_client_destroy_buffer(wayland_display->wl_tbm_client, (void *)wayland_buffer->wl_proxy); buffer->backend.data = NULL; free(wayland_buffer); @@ -1668,9 +1311,6 @@ __tpl_display_choose_backend_wayland(tpl_handle_t native_dpy) if (__tpl_wayland_display_is_wl_display(native_dpy)) return TPL_TRUE; - if (__tpl_wayland_display_is_gbm_device(native_dpy)) - return TPL_TRUE; - return TPL_FALSE; } @@ -1689,10 +1329,8 @@ __tpl_display_init_backend_wayland(tpl_display_backend_t *backend) backend->get_window_info = __tpl_wayland_display_get_window_info; backend->get_pixmap_info = __tpl_wayland_display_get_pixmap_info; backend->flush = __tpl_wayland_display_flush; -#ifdef EGL_BIND_WL_DISPLAY - backend->bind_client_display_handle = __tpl_wayland_display_bind_client_display; - backend->unbind_client_display_handle = __tpl_wayland_display_unbind_client_display; -#endif + backend->bind_client_display_handle = NULL; + backend->unbind_client_display_handle = NULL; } void @@ -1710,7 +1348,7 @@ __tpl_surface_init_backend_wayland(tpl_surface_backend_t *backend) backend->validate_frame = __tpl_wayland_surface_validate_frame; backend->get_buffer = __tpl_wayland_surface_get_buffer; backend->post = __tpl_wayland_surface_post; - backend->destroy_cached_buffers = __tpl_wayland_surface_destroy_cached_buffers; + backend->destroy_cached_buffers = __tpl_wayland_surface_destroy_cached_buffers; backend->update_cached_buffers = __tpl_wayland_surface_update_cached_buffers; } @@ -1799,39 +1437,3 @@ __cb_client_buffer_release_callback(void *data, struct wl_proxy *proxy) static const struct wl_buffer_listener buffer_release_listener = { (void *)__cb_client_buffer_release_callback, }; - -#ifdef EGL_BIND_WL_DISPLAY -unsigned int __tpl_wayland_display_bind_client_display(tpl_display_t *tpl_display, tpl_handle_t native_dpy) -{ - tpl_wayland_display_t *tpl_wayland_display; - - TPL_ASSERT(tpl_display); - TPL_ASSERT(native_dpy); - - tpl_wayland_display = (tpl_wayland_display_t *) tpl_display->backend.data; - tpl_display->bufmgr_fd = dup(gbm_device_get_fd(tpl_display->native_handle)); - tpl_wayland_display->bufmgr = tbm_bufmgr_init(tpl_display->bufmgr_fd); - if (tpl_wayland_display->bufmgr == NULL) - { - TPL_ERR("TBM buffer manager initialization failed!"); - return TPL_FALSE; - } - - tpl_wayland_display->proc.comp.bound_client_display = TPL_TRUE; - return TPL_TRUE; -} - -unsigned int __tpl_wayland_display_unbind_client_display(tpl_display_t *tpl_display, tpl_handle_t native_dpy) -{ - tpl_wayland_display_t *tpl_wayland_display; - - TPL_ASSERT(tpl_display); - - tpl_wayland_display = (tpl_wayland_display_t *) tpl_display->backend.data; - - tbm_bufmgr_deinit(tpl_wayland_display->bufmgr); - close(tpl_display->bufmgr_fd); - tpl_wayland_display->proc.comp.bound_client_display = TPL_FALSE; - return TPL_TRUE; -} -#endif -- 2.7.4 From 3dbf4012d64ce9a1d7b77b780b0cb70c6b3e6fd1 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 22 Dec 2015 14:52:26 +0900 Subject: [PATCH 12/16] Apply tbm_surface_queue(free queue only) for wl-egl(client). Change-Id: I138dd23a0f01073a45955215b26f5596a63911bc --- src/tpl_gbm.c | 82 +++-------- src/tpl_wayland.c | 426 ++++++++++++++++++++++-------------------------------- 2 files changed, 195 insertions(+), 313 deletions(-) diff --git a/src/tpl_gbm.c b/src/tpl_gbm.c index f59e765..a4c74bf 100644 --- a/src/tpl_gbm.c +++ b/src/tpl_gbm.c @@ -2,14 +2,13 @@ #include -#include "wayland-egl/wayland-egl-priv.h" - #include -#include -#include + #ifndef USE_TBM_QUEUE #define USE_TBM_QUEUE #endif + +#include #include #include #include @@ -22,56 +21,39 @@ #include #include +#include #include #include #include #include #include -/* In wayland, application and compositor create its own drawing buffers. Recommend size is more than 2. */ -#define TPL_BUFFER_ALLOC_SIZE_APP 3 -#define TPL_BUFFER_ALLOC_SIZE_COMPOSITOR 4 -#define TPL_BUFFER_ALLOC_SIZE_MAX (((TPL_BUFFER_ALLOC_SIZE_APP) > (TPL_BUFFER_ALLOC_SIZE_COMPOSITOR))?(TPL_BUFFER_ALLOC_SIZE_APP):(TPL_BUFFER_ALLOC_SIZE_COMPOSITOR)) - typedef struct _tpl_gbm_display tpl_gbm_display_t; typedef struct _tpl_gbm_surface tpl_gbm_surface_t; typedef struct _tpl_gbm_buffer tpl_gbm_buffer_t; -enum gbm_buffer_status -{ - IDLE = 0, - BUSY = 1, - READY = 2, /* redering done */ - POSTED = 3 /* gbm locked */ -}; - struct _tpl_gbm_display { - tbm_bufmgr bufmgr; - tpl_list_t cached_buffers; - tpl_bool_t bound_client_display; + tbm_bufmgr bufmgr; + tpl_list_t cached_buffers; + tpl_bool_t bound_client_display; }; struct _tpl_gbm_surface { - tpl_buffer_t *current_rendering_buffer; + tpl_buffer_t *current_rendering_buffer; tpl_list_t done_rendering_queue; - int current_back_idx; - tpl_buffer_t *back_buffers[TPL_BUFFER_ALLOC_SIZE_MAX]; - tbm_surface_queue_h tbm_queue; + tbm_surface_queue_h tbm_queue; }; struct _tpl_gbm_buffer { - tpl_display_t *display; - tbm_surface_h tbm_surface; + tpl_display_t *display; + tpl_buffer_t *tpl_buffer; + tbm_surface_h tbm_surface; tbm_bo bo; - int reused; - tpl_buffer_t *tpl_buffer; - enum gbm_buffer_status status; - struct gbm_bo *gbm_bo; - tpl_bool_t posted; + struct gbm_bo *gbm_bo; struct wl_listener destroy_listener; }; @@ -170,9 +152,6 @@ __tpl_gbm_display_is_gbm_device(tpl_handle_t native_dpy) { TPL_ASSERT(native_dpy); - if (*(void **)native_dpy == &wl_display_interface) - return TPL_FALSE; - /* MAGIC CHECK: A native display handle is a gbm_device if the de-referenced first value is a memory address pointing gbm_create_surface(). */ if (*(void **)native_dpy == gbm_create_device) @@ -204,10 +183,10 @@ __tpl_gbm_display_init(tpl_display_t *display) __tpl_list_init(&gbm_display->cached_buffers); } else - goto free_wl_display; + goto free_gbm_display; return TPL_TRUE; -free_wl_display: +free_gbm_display: if (gbm_display != NULL) { free(gbm_display); @@ -373,7 +352,6 @@ __tpl_gbm_surface_init(tpl_surface_t *surface) return TPL_FALSE; surface->backend.data = (void *)tpl_gbm_surface; - tpl_gbm_surface->current_back_idx = 0; tpl_gbm_surface->tbm_queue = NULL; __tpl_list_init(&tpl_gbm_surface->done_rendering_queue); @@ -416,20 +394,6 @@ __tpl_gbm_surface_buffer_free(tpl_buffer_t *buffer) } } -static void -__tpl_gbm_surface_render_buffers_free(tpl_gbm_surface_t *gbm_surface, int num_buffers) -{ - TPL_ASSERT(gbm_surface); - int i; - - for (i = 0; i < num_buffers; i++) - { - if ( gbm_surface->back_buffers[i] != NULL ) - __tpl_gbm_surface_buffer_free(gbm_surface->back_buffers[i]); - gbm_surface->back_buffers[i] = NULL; - } -} - static tpl_bool_t __tpl_gbm_surface_destroy_cached_buffers(tpl_surface_t *surface) { @@ -482,17 +446,20 @@ static void __tpl_gbm_surface_fini(tpl_surface_t *surface) { tpl_gbm_surface_t *gbm_surface = NULL; + tpl_gbm_display_t *gbm_display = NULL; TPL_ASSERT(surface); + TPL_ASSERT(surface->display); gbm_surface = (tpl_gbm_surface_t *) surface->backend.data; if (NULL == gbm_surface) return; - TPL_LOG(3, "window(%p, %p)", surface, surface->native_handle); + gbm_display = (tpl_gbm_display_t *) surface->display->backend.data; + if (NULL == gbm_display) + return; - /* all back buffers will be freed in this function */ - __tpl_gbm_surface_render_buffers_free(gbm_surface, TPL_BUFFER_ALLOC_SIZE_MAX); + TPL_LOG(3, "window(%p, %p)", surface, surface->native_handle); free(gbm_surface); surface->backend.data = NULL; @@ -574,8 +541,6 @@ __tpl_gbm_surface_end_frame(tpl_surface_t *surface) { gbm_buffer = (tpl_gbm_buffer_t *) gbm_surface->current_rendering_buffer->backend.data; - gbm_buffer->status = READY; - TPL_LOG(6, "current_rendering_buffer BO:%d", tbm_bo_export(gbm_buffer->bo)); } @@ -958,7 +923,6 @@ __tpl_gbm_surface_get_buffer(tpl_surface_t *surface, tpl_bool_t *reset_buffers) { __tpl_gbm_surface_buffer_free(gbm_surface->current_rendering_buffer); gbm_surface->current_rendering_buffer = NULL; - gbm_surface->back_buffers[gbm_surface->current_back_idx] = NULL; if (reset_buffers != NULL) *reset_buffers = TPL_TRUE; @@ -1128,8 +1092,8 @@ __tpl_display_init_backend_gbm(tpl_display_backend_t *backend) backend->fini = __tpl_gbm_display_fini; backend->query_config = __tpl_gbm_display_query_config; backend->filter_config = __tpl_gbm_display_filter_config; - backend->get_window_info = __tpl_gbm_display_get_window_info; - backend->get_pixmap_info = __tpl_gbm_display_get_pixmap_info; + backend->get_window_info = __tpl_gbm_display_get_window_info; + backend->get_pixmap_info = __tpl_gbm_display_get_pixmap_info; backend->flush = __tpl_gbm_display_flush; #ifdef EGL_BIND_WL_DISPLAY backend->bind_client_display_handle = __tpl_gbm_display_bind_client_wayland_display; diff --git a/src/tpl_wayland.c b/src/tpl_wayland.c index b25e11d..b2bda1b 100644 --- a/src/tpl_wayland.c +++ b/src/tpl_wayland.c @@ -5,13 +5,6 @@ #include "wayland-egl/wayland-egl-priv.h" #include -#include -#include -#ifndef USE_TBM_QUEUE -#define USE_TBM_QUEUE -#endif -#include -#include #include #undef inline @@ -22,6 +15,7 @@ #include #include +#include #include #include #include @@ -29,50 +23,36 @@ #include /* In wayland, application and compositor create its own drawing buffers. Recommend size is more than 2. */ -#define TPL_BUFFER_ALLOC_SIZE_APP 3 -#define TPL_BUFFER_ALLOC_SIZE_COMPOSITOR 4 -#define TPL_BUFFER_ALLOC_SIZE_MAX (((TPL_BUFFER_ALLOC_SIZE_APP) > (TPL_BUFFER_ALLOC_SIZE_COMPOSITOR))?(TPL_BUFFER_ALLOC_SIZE_APP):(TPL_BUFFER_ALLOC_SIZE_COMPOSITOR)) +#define CLIENT_QUEUE_SIZE 3 typedef struct _tpl_wayland_display tpl_wayland_display_t; typedef struct _tpl_wayland_surface tpl_wayland_surface_t; typedef struct _tpl_wayland_buffer tpl_wayland_buffer_t; -enum wayland_buffer_status -{ - IDLE = 0, - BUSY = 1, - READY = 2, /* redering done */ - POSTED = 3 /* gbm locked */ -}; - struct _tpl_wayland_display { - tbm_bufmgr bufmgr; + tbm_bufmgr bufmgr; + tpl_list_t cached_buffers; struct wayland_tbm_client *wl_tbm_client; - tpl_bool_t authenticated; - struct wl_event_queue *wl_queue; - struct wl_registry *wl_registry; + struct wl_event_queue *wl_queue; + struct wl_registry *wl_registry; }; struct _tpl_wayland_surface { - tpl_buffer_t *current_rendering_buffer; + tpl_buffer_t *current_rendering_buffer; tpl_list_t done_rendering_queue; - int current_back_idx; - tpl_buffer_t *back_buffers[TPL_BUFFER_ALLOC_SIZE_MAX]; - tbm_surface_queue_h tbm_queue; + tbm_surface_queue_h tbm_queue; }; struct _tpl_wayland_buffer { - tpl_display_t *display; - tbm_surface_h tbm_surface; + tpl_display_t *display; + tbm_surface_h tbm_surface; tbm_bo bo; - int reused; - tpl_buffer_t *tpl_buffer; - enum wayland_buffer_status status; + + tpl_buffer_t *tpl_buffer; struct wl_proxy *wl_proxy; - tpl_bool_t resized; }; static const struct wl_registry_listener registry_listener; @@ -135,6 +115,31 @@ __tpl_wayland_surface_buffer_cache_remove(tpl_list_t *buffer_cache, size_t name) TPL_LOG(3, "Buffer named %zu not found in cache", name); } +static void +__tpl_wayland_surface_buffer_free(tpl_buffer_t *buffer); + +static TPL_INLINE void +__tpl_wayland_surface_buffer_cache_remove_all(tpl_list_t *buffer_cache) +{ + tpl_list_node_t *node; + + TPL_ASSERT(buffer_cache); + + node = __tpl_list_get_front_node(buffer_cache); + + while (node) + { + tpl_buffer_t *buffer = (tpl_buffer_t *)__tpl_list_node_get_data(node); + + TPL_ASSERT(buffer); + + tpl_object_unreference(&buffer->base); + + __tpl_list_remove(node, (tpl_free_func_t)__tpl_wayland_surface_buffer_free); + node = __tpl_list_node_next(node); + } +} + static TPL_INLINE tpl_buffer_t * __tpl_wayland_surface_buffer_cache_find(tpl_list_t *buffer_cache, size_t name) { @@ -170,23 +175,18 @@ __tpl_wayland_display_is_wl_display(tpl_handle_t native_dpy) { TPL_ASSERT(native_dpy); - if (*(void **)native_dpy == gbm_create_device) - return TPL_FALSE; - - { - struct wl_interface *wl_egl_native_dpy = *(void **) native_dpy; + struct wl_interface *wl_egl_native_dpy = *(void **) native_dpy; /* MAGIC CHECK: A native display handle is a wl_display if the de-referenced first value is a memory address pointing the structure of wl_display_interface. */ - if ( wl_egl_native_dpy == &wl_display_interface ) - { - return TPL_TRUE; - } + if ( wl_egl_native_dpy == &wl_display_interface ) + { + return TPL_TRUE; + } - if(strncmp(wl_egl_native_dpy->name, wl_display_interface.name, strlen(wl_display_interface.name)) == 0) - { - return TPL_TRUE; - } + if(strncmp(wl_egl_native_dpy->name, wl_display_interface.name, strlen(wl_display_interface.name)) == 0) + { + return TPL_TRUE; } return TPL_FALSE; @@ -258,6 +258,8 @@ __tpl_wayland_display_init(tpl_display_t *display) goto destroy_queue; wl_proxy_set_queue((struct wl_proxy *)wayland_display->wl_registry, wayland_display->wl_queue); + + __tpl_list_init(&wayland_display->cached_buffers); } else goto free_wl_display; @@ -285,6 +287,7 @@ __tpl_wayland_display_fini(tpl_display_t *display) if (wayland_display != NULL) { wayland_tbm_client_deinit(wayland_display->wl_tbm_client); + __tpl_list_fini(&wayland_display->cached_buffers, (tpl_free_func_t)tpl_object_unreference); free(wayland_display); } display->backend.data = NULL; @@ -321,23 +324,17 @@ __tpl_wayland_display_query_config(tpl_display_t *display, tpl_surface_type_t su } static tpl_bool_t -__tpl_wayland_display_filter_config(tpl_display_t *display, - int *visual_id, int alpha_size) +__tpl_wayland_display_filter_config(tpl_display_t *display, int *visual_id, int alpha_size) { TPL_IGNORE(display); - - if (visual_id != NULL && *visual_id == GBM_FORMAT_ARGB8888 && alpha_size == 0) - { - *visual_id = GBM_FORMAT_XRGB8888; - return TPL_TRUE; - } - - return TPL_FALSE; + TPL_IGNORE(visual_id); + TPL_IGNORE(alpha_size); + return TPL_TRUE; } static tpl_bool_t __tpl_wayland_display_get_window_info(tpl_display_t *display, tpl_handle_t window, - int *width, int *height, tpl_format_t *format, int depth, int a_size) + int *width, int *height, tpl_format_t *format, int depth, int a_size) { TPL_ASSERT(display); TPL_ASSERT(window); @@ -408,7 +405,6 @@ static tpl_bool_t __tpl_wayland_surface_init(tpl_surface_t *surface) { tpl_wayland_surface_t *wayland_surface = NULL; - int i; TPL_ASSERT(surface); @@ -417,20 +413,40 @@ __tpl_wayland_surface_init(tpl_surface_t *surface) return TPL_FALSE; surface->backend.data = (void *)wayland_surface; - wayland_surface->current_back_idx = 0; wayland_surface->tbm_queue = NULL; __tpl_list_init(&wayland_surface->done_rendering_queue); if (surface->type == TPL_SURFACE_TYPE_WINDOW) { + int tbm_format; struct wl_egl_window *wl_egl_window = (struct wl_egl_window *)surface->native_handle; wl_egl_window->private = surface; - /* Create renderable buffer queue. Fill with empty(=NULL) buffers. */ - for (i = 0; i < TPL_BUFFER_ALLOC_SIZE_APP; i++) + switch (surface->format) + { + case TPL_FORMAT_ARGB8888: tbm_format = TBM_FORMAT_ARGB8888; + break; + case TPL_FORMAT_XRGB8888: tbm_format = TBM_FORMAT_XRGB8888; + break; + case TPL_FORMAT_RGB565: tbm_format = TBM_FORMAT_RGB565; + break; + default: + TPL_ERR("Unsupported format found in surface!"); + return TPL_FALSE; + } + + wayland_surface->tbm_queue = tbm_surface_queue_create( + CLIENT_QUEUE_SIZE, + wl_egl_window->width, + wl_egl_window->height, + tbm_format, + 0); + + if (wayland_surface->tbm_queue == NULL) { - wayland_surface->back_buffers[i] = NULL; + TPL_ERR("TBM surface queue creation failed!"); + goto error; } if (TPL_TRUE != __tpl_wayland_display_get_window_info(surface->display, surface->native_handle, @@ -461,69 +477,10 @@ __tpl_wayland_surface_buffer_free(tpl_buffer_t *buffer) TPL_LOG(3, "buffer(%p) key:%zu", buffer, buffer?buffer->key:-1); if (buffer != NULL) { - __tpl_buffer_set_surface(buffer, NULL); tpl_object_unreference((tpl_object_t *) buffer); } } -static void -__tpl_wayland_surface_render_buffers_free(tpl_wayland_surface_t *wayland_surface, int num_buffers) -{ - TPL_ASSERT(wayland_surface); - int i; - - for (i = 0; i < num_buffers; i++) - { - if ( wayland_surface->back_buffers[i] != NULL ) - __tpl_wayland_surface_buffer_free(wayland_surface->back_buffers[i]); - wayland_surface->back_buffers[i] = NULL; - } -} - -static int -__tpl_wayland_surface_get_idle_buffer_idx(tpl_wayland_surface_t *wayland_surface, int num_buffers) -{ - TPL_ASSERT(wayland_surface); - - int i; - int ret_id = -1; - int current_id = wayland_surface->current_back_idx; - - for(i = current_id + 1; i < current_id + num_buffers + 1; i++) - { - int id = i % num_buffers; - tpl_buffer_t *tpl_buffer = wayland_surface->back_buffers[id]; - tpl_wayland_buffer_t *wayland_buffer = NULL; - - if ( tpl_buffer == NULL ) - { - wayland_surface->current_back_idx = id; - return id; - } - - wayland_buffer = (tpl_wayland_buffer_t*)tpl_buffer->backend.data; - - if ( wayland_buffer && wayland_buffer->status == IDLE ) - { - wayland_surface->current_back_idx = id; - return id; - } - - /* [HOT-FIX] 20151106 joonbum.ko */ - /* It will be useful when kernel didn't send event page-flip done */ - if ( wayland_buffer && wayland_buffer->status == POSTED ) - { - wayland_buffer->status = IDLE; - wayland_surface->current_back_idx = id; - return id; - } - } - - TPL_LOG(6, "There is no IDLE index : %d", ret_id); - - return ret_id; -} - static tpl_bool_t __tpl_wayland_surface_destroy_cached_buffers(tpl_surface_t *surface) { @@ -545,7 +502,7 @@ __tpl_wayland_surface_destroy_cached_buffers(tpl_surface_t *surface) return TPL_FALSE; } - __tpl_wayland_surface_render_buffers_free(wayland_surface, TPL_BUFFER_ALLOC_SIZE_APP); + __tpl_wayland_surface_buffer_cache_remove_all(&wayland_display->cached_buffers); return TPL_TRUE; } @@ -555,7 +512,6 @@ __tpl_wayland_surface_update_cached_buffers(tpl_surface_t *surface) { tpl_wayland_surface_t *wayland_surface = NULL; tpl_wayland_display_t *wayland_display = NULL; - int i; if (surface == NULL) { @@ -572,19 +528,6 @@ __tpl_wayland_surface_update_cached_buffers(tpl_surface_t *surface) return TPL_FALSE; } - for (i = 0; i < TPL_BUFFER_ALLOC_SIZE_APP; i++) - { - tpl_buffer_t *cached_buffer = wayland_surface->back_buffers[i]; - - if (cached_buffer != NULL && - (surface->width != wayland_surface->back_buffers[i]->width || - surface->height != wayland_surface->back_buffers[i]->height)) - { - __tpl_wayland_surface_buffer_free(wayland_surface->back_buffers[i]); - wayland_surface->back_buffers[i] = NULL; - } - } - return TPL_TRUE; } @@ -592,16 +535,20 @@ static void __tpl_wayland_surface_fini(tpl_surface_t *surface) { tpl_wayland_surface_t *wayland_surface = NULL; + tpl_wayland_display_t *wayland_display = NULL; TPL_ASSERT(surface); + TPL_ASSERT(surface->display); wayland_surface = (tpl_wayland_surface_t *) surface->backend.data; - if (NULL == wayland_surface) return; + if (wayland_surface == NULL) return; + + wayland_display = (tpl_wayland_display_t *) surface->display->backend.data; + if (wayland_display == NULL) return; TPL_LOG(3, "window(%p, %p)", surface, surface->native_handle); - /* all back buffers will be freed in this function */ - __tpl_wayland_surface_render_buffers_free(wayland_surface, TPL_BUFFER_ALLOC_SIZE_MAX); + __tpl_wayland_surface_buffer_cache_remove_all(&wayland_display->cached_buffers); if (surface->type == TPL_SURFACE_TYPE_WINDOW) { @@ -623,6 +570,9 @@ __tpl_wayland_surface_fini(tpl_surface_t *surface) wl_display_flush(surface->display->native_handle); __tpl_wayland_display_roundtrip(surface->display); + + tbm_surface_queue_destroy(wayland_surface->tbm_queue); + wayland_surface->tbm_queue = NULL; } free(wayland_surface); @@ -688,21 +638,17 @@ __tpl_wayland_surface_post(tpl_surface_t *surface, tpl_frame_t *frame) wl_display_flush(surface->display->native_handle); - wayland_buffer->status = POSTED; - TPL_LOG(7, "BO:%d", tbm_bo_export(wayland_buffer->bo)); } static tpl_bool_t __tpl_wayland_surface_begin_frame(tpl_surface_t *surface) { - tpl_wayland_display_t *wayland_display; tpl_wayland_surface_t *wayland_surface; TPL_ASSERT(surface); TPL_ASSERT(surface->display); - wayland_display = (tpl_wayland_display_t *) surface->display->backend.data; wayland_surface = (tpl_wayland_surface_t *) surface->backend.data; TPL_ASSERT(wayland_surface->current_rendering_buffer == NULL); @@ -712,24 +658,10 @@ __tpl_wayland_surface_begin_frame(tpl_surface_t *surface) TPL_OBJECT_UNLOCK(surface); __tpl_wayland_display_roundtrip(surface->display); - while (__tpl_wayland_surface_get_idle_buffer_idx(wayland_surface, TPL_BUFFER_ALLOC_SIZE_APP) == -1) - { - /* Application sent all buffers to the server. Wait for server response. */ - if (wl_display_dispatch_queue(surface->display->native_handle, wayland_display->wl_queue) == -1) - { - TPL_OBJECT_LOCK(surface); - return TPL_FALSE; - } - } TPL_OBJECT_LOCK(surface); - wayland_surface->current_rendering_buffer = wayland_surface->back_buffers[wayland_surface->current_back_idx]; - if (wayland_surface->current_rendering_buffer) - { - tpl_wayland_buffer_t *wayland_buffer = (tpl_wayland_buffer_t*)wayland_surface->current_rendering_buffer->backend.data; - wayland_buffer->status = BUSY; - TPL_LOG(6, "current_rendering_buffer BO:%d", tbm_bo_export(wayland_buffer->bo)); - } + wayland_surface->current_rendering_buffer = NULL; + return TPL_TRUE; } @@ -758,15 +690,9 @@ __tpl_wayland_surface_end_frame(tpl_surface_t *surface) { wayland_buffer = (tpl_wayland_buffer_t *) wayland_surface->current_rendering_buffer->backend.data; - wayland_buffer->status = READY; - TPL_LOG(6, "current_rendering_buffer BO:%d", tbm_bo_export(wayland_buffer->bo)); } - /* MOVE BUFFER : (current buffer) --> [done queue] */ - if (TPL_TRUE != __tpl_list_push_back(&wayland_surface->done_rendering_queue, wayland_surface->current_rendering_buffer)) - return TPL_FALSE; - wayland_surface->current_rendering_buffer = NULL; return TPL_TRUE; @@ -818,23 +744,23 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool tpl_buffer_t *buffer = NULL; tpl_wayland_buffer_t *wayland_buffer = NULL; tpl_wayland_surface_t *wayland_surface = NULL; + tpl_wayland_display_t *wayland_display = NULL; tbm_bo bo; tbm_bo_handle bo_handle; - int width, height, depth; + int width, height, depth, format; uint32_t stride, size, offset; - tpl_format_t format; - - tpl_wayland_display_t *wayland_display; + uint32_t key; + tpl_format_t tpl_format; tbm_surface_h tbm_surface = NULL; -/* TODO: If HW support getting of gem memory size, + tbm_surface_queue_error_e tsq_err = 0; + + /* TODO: If HW support getting of gem memory size, use tbm_surface_get_info() with tbm_surface_info_s */ #if 0 tbm_surface_info_s tbm_surf_info; #endif struct wl_proxy *wl_proxy = NULL; - unsigned int name = -1; - uint32_t wl_format = 0; TPL_ASSERT(surface); TPL_ASSERT(surface->display); @@ -842,45 +768,39 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool TPL_ASSERT(surface->display->backend.data); wayland_display = (tpl_wayland_display_t *) surface->display->backend.data; + wayland_surface = (tpl_wayland_surface_t *) surface->backend.data; - if (TPL_TRUE != __tpl_wayland_display_get_window_info(surface->display, surface->native_handle, - &width, &height, &format, 0, 0)) - { - TPL_ERR("Failed to get window info!"); - return NULL; - } - - depth = __tpl_wayland_get_depth_from_format(format); - - if (surface->format == TPL_FORMAT_INVALID) - surface->format = format; + struct wl_egl_window *wl_egl_window = (struct wl_egl_window *)surface->native_handle; + width = wl_egl_window->width; + height = wl_egl_window->height; + format = tbm_surface_queue_get_format(wayland_surface->tbm_queue); - switch (surface->format) + /* Check whether the surface was resized by wayland_egl */ + if (width != tbm_surface_queue_get_width(wayland_surface->tbm_queue) || + height != tbm_surface_queue_get_height(wayland_surface->tbm_queue)) { - case TPL_FORMAT_ARGB8888: - wl_format = TBM_FORMAT_ARGB8888; - break; - case TPL_FORMAT_XRGB8888: - wl_format = TBM_FORMAT_XRGB8888; - break; - case TPL_FORMAT_RGB565: - wl_format = TBM_FORMAT_RGB565; - break; - default: - TPL_ERR("Unsupported format found in surface!"); - return NULL; + tbm_surface_queue_reset(wayland_surface->tbm_queue, width, height, format); + + /* Remove all cached buffers (This code will be deleted.)*/ + __tpl_wayland_surface_buffer_cache_remove_all(&wayland_display->cached_buffers); + if (reset_buffers != NULL) + *reset_buffers = TPL_TRUE; } - /* Create tbm_surface_h */ - tbm_surface = tbm_surface_create(width, height, wl_format); - if (NULL == tbm_surface) + tsq_err = tbm_surface_queue_dequeue(wayland_surface->tbm_queue, &tbm_surface); + if (tbm_surface == NULL) { - TPL_ERR("TBM SURFACE create failed!"); - return NULL; + TPL_LOG(6, "Wait until dequeable | tsq_err = %d", tsq_err); + tbm_surface_queue_can_dequeue(wayland_surface->tbm_queue, 1); + + tsq_err = tbm_surface_queue_dequeue(wayland_surface->tbm_queue, &tbm_surface); + if (tbm_surface == NULL) + { + TPL_ERR("Failed to get tbm_surface from tbm_surface_queue | tsq_err = %d",tsq_err); + return NULL; + } } - /* Inc ref count about tbm_surface */ - /* It will be dec when wayland_buffer_fini called*/ tbm_surface_internal_ref(tbm_surface); /* Get tbm_bo from tbm_surface_h */ @@ -889,49 +809,54 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool { TPL_ERR("TBM get bo failed!"); tbm_surface_internal_unref(tbm_surface); - tbm_surface_destroy(tbm_surface); return NULL; } - /* Create tpl buffer. */ - bo_handle = tbm_bo_get_handle(bo, TBM_DEVICE_3D); - if (bo_handle.ptr == NULL) + key = tbm_bo_export(bo); + + buffer = __tpl_wayland_surface_buffer_cache_find(&wayland_display->cached_buffers, key); + if (buffer != NULL) { - TPL_ERR("TBM bo get handle failed!"); - tbm_surface_internal_unref(tbm_surface); - tbm_surface_destroy(tbm_surface); - return NULL; + return buffer; } - /* TODO: If HW support getting of gem memory size, - then replace tbm_surface_internal_get_plane_data() to tbm_surface_get_info() */ -#if 0 - if (tbm_surface_get_info(tbm_surface, &tbm_surf_info) != 0) + + width = tbm_surface_get_width(tbm_surface); + height = tbm_surface_get_height(tbm_surface); + + switch(tbm_surface_get_format(tbm_surface)) { - TPL_ERR("Failed to get tbm_surface info!"); + case TBM_FORMAT_ARGB8888: tpl_format = TPL_FORMAT_ARGB8888; break; + case TBM_FORMAT_XRGB8888: tpl_format = TPL_FORMAT_XRGB8888; break; + case TBM_FORMAT_RGB565: tpl_format = TPL_FORMAT_RGB565; break; + default: + tpl_format = TPL_FORMAT_INVALID; + TPL_ERR("No matched format!!"); tbm_surface_internal_unref(tbm_surface); - tbm_surface_destroy(tbm_surface); return NULL; } - stride = tbm_surf_info.planes[0].stride; -#else - if (!tbm_surface_internal_get_plane_data(tbm_surface, 0, &size, &offset, &stride)) + + depth = __tpl_wayland_get_depth_from_format(tpl_format); + + /* Get pitch stride from tbm_surface */ + tbm_surface_internal_get_plane_data(tbm_surface, 0, &size, &offset, &stride); + + /* Create tpl buffer. */ + bo_handle = tbm_bo_get_handle(bo, TBM_DEVICE_3D); + if (bo_handle.ptr == NULL) { - TPL_ERR("Failed to get tbm_surface stride info!"); + TPL_ERR("TBM bo get handle failed!"); tbm_surface_internal_unref(tbm_surface); - tbm_surface_destroy(tbm_surface); return NULL; } -#endif - name = tbm_bo_export(bo); - TPL_LOG(7, "Client back buffer is new alloced | BO:%d",name); + buffer = __tpl_buffer_alloc(surface, (size_t) key, + (int)bo_handle.u32, width, height, depth, stride); - buffer = __tpl_buffer_alloc(surface, (size_t) name, (int) bo_handle.u32, width, height, depth, stride); - if (NULL == buffer) + if (buffer == NULL) { - TPL_ERR("TPL buffer alloc failed!"); + TPL_ERR("Failed to allocate tpl buffer | surf:%p bo_hnd:%d WxHxD:%dx%dx%d", + surface, (int) bo_handle.u32, width, height, depth); tbm_surface_internal_unref(tbm_surface); - tbm_surface_destroy(tbm_surface); return NULL; } @@ -939,13 +864,21 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool if (wayland_buffer == NULL) { TPL_ERR("Mem alloc for wayland_buffer failed!"); - tbm_surface_internal_unref(tbm_surface); - tbm_surface_destroy(tbm_surface); tpl_object_unreference((tpl_object_t *) buffer); + tbm_surface_internal_unref(tbm_surface); return NULL; } - buffer->backend.data = (void *) wayland_buffer; + buffer->backend.data = (void *)wayland_buffer; + + if (TPL_TRUE != __tpl_wayland_surface_buffer_cache_add(&wayland_display->cached_buffers, buffer)) + { + TPL_ERR("Adding surface to buffer cache failed!"); + tpl_object_unreference((tpl_object_t *) buffer); + tbm_surface_internal_unref(tbm_surface); + free(wayland_buffer); + return NULL; + } wl_proxy = (struct wl_proxy *)wayland_tbm_client_create_buffer(wayland_display->wl_tbm_client, tbm_surface); @@ -954,7 +887,6 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool { TPL_ERR("Failed to create TBM client buffer!"); tbm_surface_internal_unref(tbm_surface); - tbm_surface_destroy(tbm_surface); tpl_object_unreference((tpl_object_t *)buffer); free(wayland_buffer); return NULL; @@ -970,15 +902,12 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool wayland_buffer->wl_proxy = wl_proxy; wayland_buffer->bo = bo; - wayland_buffer->status = BUSY; wayland_surface = (tpl_wayland_surface_t*) surface->backend.data; - wayland_surface->back_buffers[wayland_surface->current_back_idx] = buffer; if (reset_buffers != NULL) *reset_buffers = TPL_FALSE; - TPL_LOG(3, "buffer(%p,%p) name:%d, %dx%d", buffer, wl_proxy, name, width, height); - TPL_LOG(4, "buffer->backend.data : %p", buffer->backend.data); + TPL_LOG(3, "buffer:%p bo_hnd:%d, %dx%d", buffer, (int) bo_handle.u32, width, height); return buffer; } @@ -997,8 +926,8 @@ __tpl_wayland_surface_get_buffer_from_tbm_surface(tbm_surface_h surface) return buf; } - - static inline void +#if 0 +static inline void __tpl_wayland_buffer_set_tbm_surface(tbm_surface_h surface, tpl_buffer_t *buf) { tbm_bo bo; @@ -1007,6 +936,7 @@ __tpl_wayland_buffer_set_tbm_surface(tbm_surface_h surface, tpl_buffer_t *buf) tbm_bo_add_user_data(bo, KEY_TPL_BUFFER, NULL); tbm_bo_set_user_data(bo, KEY_TPL_BUFFER, buf); } +#endif static tpl_buffer_t * __tpl_wayland_surface_create_buffer_from_wl_tbm(tpl_surface_t *surface, tpl_bool_t *reset_buffers) @@ -1140,20 +1070,6 @@ __tpl_wayland_surface_get_buffer(tpl_surface_t *surface, tpl_bool_t *reset_buffe return NULL; } - /* Check whether the surface was resized by wayland_egl */ - if (surface->type != TPL_SURFACE_TYPE_PIXMAP && - wayland_surface->current_rendering_buffer != NULL && - (width != wayland_surface->current_rendering_buffer->width || - height != wayland_surface->current_rendering_buffer->height)) - { - __tpl_wayland_surface_buffer_free(wayland_surface->current_rendering_buffer); - wayland_surface->current_rendering_buffer = NULL; - wayland_surface->back_buffers[wayland_surface->current_back_idx] = NULL; - - if (reset_buffers != NULL) - *reset_buffers = TPL_TRUE; - } - if (wayland_surface->current_rendering_buffer == NULL) { if (surface->type == TPL_SURFACE_TYPE_WINDOW) @@ -1409,11 +1325,13 @@ __cb_client_buffer_release_callback(void *data, struct wl_proxy *proxy) { tpl_buffer_t *tpl_buffer; tpl_surface_t *surface; + tpl_wayland_surface_t *wayland_surface; TPL_ASSERT(data); tpl_buffer = (tpl_buffer_t *) data; surface = tpl_buffer->surface; + wayland_surface = (tpl_wayland_surface_t *)surface->backend.data; TPL_LOG(3, "release window(%p, %p), buffer(%p), key:%zu", surface, surface?surface->native_handle:NULL, @@ -1424,8 +1342,8 @@ __cb_client_buffer_release_callback(void *data, struct wl_proxy *proxy) TPL_OBJECT_LOCK(surface); tpl_wayland_buffer_t *wayland_buffer = (tpl_wayland_buffer_t*) tpl_buffer->backend.data; - wayland_buffer->status = IDLE; - + tbm_surface_internal_unref(wayland_buffer->tbm_surface); + tbm_surface_queue_release(wayland_surface->tbm_queue, wayland_buffer->tbm_surface); TPL_LOG(7, "BO:%d", tbm_bo_export(wayland_buffer->bo)); TPL_OBJECT_UNLOCK(surface); -- 2.7.4 From dec29feda58fb1ca7de92abc544956b9c92f985c Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 22 Dec 2015 17:34:25 +0900 Subject: [PATCH 13/16] Prevent an exception about getenv() for EGL_PLATFORM. Change-Id: I308247b16807a25ad11bcae377e07071ba20f906 --- src/tpl.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/tpl.c b/src/tpl.c index d2a1100..cd58eba 100644 --- a/src/tpl.c +++ b/src/tpl.c @@ -221,18 +221,22 @@ __tpl_runtime_flush_all_display() tpl_backend_type_t __tpl_display_choose_backend(tpl_handle_t native_dpy) { - const char *plat_name; - plat_name = getenv("EGL_PLATFORM"); + const char *plat_name = NULL; + plat_name = getenv("EGL_PLATFORM"); + + if (plat_name) + { #ifdef TPL_WINSYS_DRI2 - if (strcmp(plat_name, "x11") == 0) return TPL_BACKEND_X11_DRI2; + if (strcmp(plat_name, "x11") == 0) return TPL_BACKEND_X11_DRI2; #endif #ifdef TPL_WINSYS_DRI3 - if (strcmp(plat_name, "x11") == 0) return TPL_BACKEND_X11_DRI3; + if (strcmp(plat_name, "x11") == 0) return TPL_BACKEND_X11_DRI3; #endif #ifdef TPL_WINSYS_WL - if (strcmp(plat_name, "wayland") == 0) return TPL_BACKEND_WAYLAND; - if (strcmp(plat_name, "drm") == 0) return TPL_BACKEND_GBM; + if (strcmp(plat_name, "wayland") == 0) return TPL_BACKEND_WAYLAND; + if (strcmp(plat_name, "drm") == 0) return TPL_BACKEND_GBM; #endif + } #ifdef TPL_WINSYS_WL if (__tpl_display_choose_backend_gbm(native_dpy) == TPL_TRUE) -- 2.7.4 From 40991f2308cab2ee8898c44cf59fc9797360c611 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Wed, 23 Dec 2015 19:04:08 +0900 Subject: [PATCH 14/16] Modify dequeue procedure for client. - Before this patch, can_dequeue will be locked up when ddk runs heavy rendering. Change-Id: Iec48aee77158c83cb6b3dfed0a977b9a5595402a --- src/tpl_gbm.c | 6 +----- src/tpl_wayland.c | 22 ++++++++++++++-------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/tpl_gbm.c b/src/tpl_gbm.c index a4c74bf..822e951 100644 --- a/src/tpl_gbm.c +++ b/src/tpl_gbm.c @@ -643,11 +643,8 @@ __tpl_gbm_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl_boo gbm_display = (tpl_gbm_display_t*)surface->display->backend.data; tsq_err = tbm_surface_queue_dequeue(gbm_surface->tbm_queue, &tbm_surface); - if (tbm_surface == NULL) + if(tbm_surface == NULL && tbm_surface_queue_can_dequeue(gbm_surface->tbm_queue, 1) == 1) { - TPL_LOG(6, "Wait until dequeable | tsq_err = %d", tsq_err); - tbm_surface_queue_can_dequeue(gbm_surface->tbm_queue, 1); - tsq_err = tbm_surface_queue_dequeue(gbm_surface->tbm_queue, &tbm_surface); if (tbm_surface == NULL) { @@ -655,7 +652,6 @@ __tpl_gbm_surface_create_buffer_from_gbm_surface(tpl_surface_t *surface, tpl_boo return NULL; } } - /* Inc ref count about tbm_surface */ /* It will be dec when before tbm_surface_queue_enqueue called */ tbm_surface_internal_ref(tbm_surface); diff --git a/src/tpl_wayland.c b/src/tpl_wayland.c index b2bda1b..6be5f95 100644 --- a/src/tpl_wayland.c +++ b/src/tpl_wayland.c @@ -787,19 +787,25 @@ __tpl_wayland_surface_create_buffer_from_wl_egl(tpl_surface_t *surface, tpl_bool *reset_buffers = TPL_TRUE; } - tsq_err = tbm_surface_queue_dequeue(wayland_surface->tbm_queue, &tbm_surface); - if (tbm_surface == NULL) + TPL_OBJECT_UNLOCK(surface); + TPL_LOG(6, "Wait until dequeable | tsq_err = %d", tsq_err); + while(tbm_surface_queue_can_dequeue(wayland_surface->tbm_queue, 0) == 0) { - TPL_LOG(6, "Wait until dequeable | tsq_err = %d", tsq_err); - tbm_surface_queue_can_dequeue(wayland_surface->tbm_queue, 1); - - tsq_err = tbm_surface_queue_dequeue(wayland_surface->tbm_queue, &tbm_surface); - if (tbm_surface == NULL) + /* Application sent all buffers to the server. Wait for server response. */ + if (wl_display_dispatch_queue(surface->display->native_handle, wayland_display->wl_queue) == -1) { - TPL_ERR("Failed to get tbm_surface from tbm_surface_queue | tsq_err = %d",tsq_err); + TPL_OBJECT_LOCK(surface); return NULL; } } + TPL_OBJECT_LOCK(surface); + + tsq_err = tbm_surface_queue_dequeue(wayland_surface->tbm_queue, &tbm_surface); + if (tbm_surface == NULL) + { + TPL_ERR("Failed to get tbm_surface from tbm_surface_queue | tsq_err = %d",tsq_err); + return NULL; + } tbm_surface_internal_ref(tbm_surface); -- 2.7.4 From 7adc1d31c2f9773381aaaf66be6dac6a869e4898 Mon Sep 17 00:00:00 2001 From: "Mun, Gwan-gyeong" Date: Mon, 4 Jan 2016 16:24:12 +0900 Subject: [PATCH 15/16] Remove comment: specific GPU Vendor name. Change-Id: I88bfead48fd49bc220992d8362e58295acc564c7 --- packaging/libtpl-egl.spec | 10 +++++----- pkgconfig/tpl-egl.pc | 2 +- src/tpl.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packaging/libtpl-egl.spec b/packaging/libtpl-egl.spec index b047e4c..76b8a29 100644 --- a/packaging/libtpl-egl.spec +++ b/packaging/libtpl-egl.spec @@ -24,13 +24,13 @@ Name: libtpl-egl Version: %{TPL_VERSION} Release: %{TPL_RELEASE} %if "%{TPL_WINSYS}" == "DRI2" -Summary: Tizen Porting Layer for ARM Mali EGL (DRI2 backend) +Summary: Tizen Porting Layer for EGL (DRI2 backend) %endif %if "%{TPL_WINSYS}" == "DRI3" -Summary: Tizen Porting Layer for ARM Mali EGL (DRI3 backend) +Summary: Tizen Porting Layer for EGL (DRI3 backend) %endif %if "%{TPL_WINSYS}" == "WL" -Summary: Tizen Porting Layer for ARM Mali EGL (Wayland backend) +Summary: Tizen Porting Layer for EGL (Wayland backend) %endif Group: Graphics & UI Framework/GL License: MIT @@ -68,7 +68,7 @@ BuildRequires: pkgconfig(libpng) %description Tizen Porting Layer (a.k.a TPL) is a linkage between the underlying window -system and the EGL porting layer found in ARM Mali DDKs. +system and the EGL porting layer. The following window systems are supported: - X11 DRI2/DRI3 @@ -84,7 +84,7 @@ Requires: libwayland-egl-devel %description devel This package contains the development libraries and header files needed by -the DDK for ARM Mali EGL. +the GPU Vendor DDK's EGL. %if "%{TPL_WINSYS}" == "WL" %package -n libwayland-egl diff --git a/pkgconfig/tpl-egl.pc b/pkgconfig/tpl-egl.pc index 7924d32..fb8cdc5 100644 --- a/pkgconfig/tpl-egl.pc +++ b/pkgconfig/tpl-egl.pc @@ -4,7 +4,7 @@ libdir=${exec_prefix}/lib includedir=${prefix}/include Name: libtpl-egl -Description: Tizen Porting Layer for ARM Mali EGL +Description: Tizen Porting Layer for EGL Version: 0.1 Requires.private: Libs: -L${libdir} -ltpl-egl diff --git a/src/tpl.h b/src/tpl.h index 7a96ce4..a13f2b6 100644 --- a/src/tpl.h +++ b/src/tpl.h @@ -6,7 +6,7 @@ * @brief TPL API header file. * * TPL is an abstraction layer for surface & buffer management on Tizen - * platform aimed to implement the EGL porting layer of ARM Mali OpenGLES + * platform aimed to implement the EGL porting layer of GPU Vendor's OpenGLES * driver over various display protocols. * * TPL provides object-oriented interfaces. Every TPL object can be represented -- 2.7.4 From 2e3db23d527ca5e482ac382e4ee229ec60d094e6 Mon Sep 17 00:00:00 2001 From: "Mun, Gwan-gyeong" Date: Thu, 24 Dec 2015 16:22:27 +0900 Subject: [PATCH 16/16] Add exclude architecture - emulator : emulator uses emulator-yagl which creates egl-wayland package. Change-Id: Ia13fd1d40e4f757a54fb4adbfc9bb9b880a7fd18 --- packaging/libtpl-egl.spec | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packaging/libtpl-egl.spec b/packaging/libtpl-egl.spec index 76b8a29..486a47a 100644 --- a/packaging/libtpl-egl.spec +++ b/packaging/libtpl-egl.spec @@ -20,6 +20,11 @@ BuildRequires: ERROR(No_window_system_designated) %endif +#Exclusive Emulator Arch +%if "%{_with_emulator}" == "1" +ExclusiveArch: +%endif + Name: libtpl-egl Version: %{TPL_VERSION} Release: %{TPL_RELEASE} -- 2.7.4