tpl: Added internal functions to manage tpl_surface in runtime. 77/161977/3
authorjoonbum.ko <joonbum.ko@samsung.com>
Mon, 13 Nov 2017 06:24:51 +0000 (15:24 +0900)
committerjoonbum.ko <joonbum.ko@samsung.com>
Tue, 28 Nov 2017 11:18:02 +0000 (20:18 +0900)
Change-Id: Id9499bc999f7f147687838bbaf2b3191afcacb2a
Signed-off-by: joonbum.ko <joonbum.ko@samsung.com>
src/tpl.c
src/tpl_internal.h
src/tpl_surface.c

index 7b0a213..d29e9de 100644 (file)
--- a/src/tpl.c
+++ b/src/tpl.c
@@ -6,6 +6,7 @@ unsigned int tpl_dump_lvl = 0;
 
 struct _tpl_runtime {
        tpl_hlist_t *displays[TPL_BACKEND_COUNT];
+       tpl_hlist_t *surfaces[TPL_BACKEND_COUNT];
 };
 
 static tpl_runtime_t   *runtime = NULL;
@@ -326,6 +327,103 @@ __tpl_display_init_backend(tpl_display_t *display, tpl_backend_type_t type)
        }
 }
 
+tpl_surface_t *
+__tpl_runtime_find_surface(tpl_backend_type_t type, tpl_handle_t native_surface)
+{
+       tpl_surface_t *surface = NULL;
+
+       if (runtime == NULL)
+               return NULL;
+
+       pthread_mutex_lock(&runtime_mutex);
+
+       if (type != TPL_BACKEND_UNKNOWN) {
+               if (runtime->surfaces[type] != NULL) {
+                       surface = (tpl_surface_t *) __tpl_hashlist_lookup(runtime->surfaces[type],
+                                         (size_t) native_surface);
+               }
+       } else {
+               int i;
+
+               for (i = 0; i < TPL_BACKEND_COUNT; i++) {
+                       if (runtime->surfaces[i] != NULL) {
+                               surface = (tpl_surface_t *) __tpl_hashlist_lookup(runtime->surfaces[i],
+                                                 (size_t) native_surface);
+                       }
+                       if (surface != NULL) break;
+               }
+       }
+
+       pthread_mutex_unlock(&runtime_mutex);
+
+       return surface;
+}
+
+tpl_result_t
+__tpl_runtime_add_surface(tpl_surface_t *surface)
+{
+       tpl_result_t ret;
+       tpl_handle_t handle;
+       tpl_backend_type_t type;
+
+       TPL_ASSERT(surface);
+
+       handle = surface->native_handle;
+       type = surface->display->backend.type;
+
+       TPL_ASSERT(0 <= type && TPL_BACKEND_COUNT > type);
+
+       if (0 != pthread_mutex_lock(&runtime_mutex)) {
+               TPL_ERR("runtime_mutex pthread_mutex_lock failed.");
+               return TPL_ERROR_INVALID_OPERATION;
+       }
+
+       if (TPL_ERROR_NONE != __tpl_runtime_init()) {
+               TPL_ERR("__tpl_runtime_init() failed.");
+               pthread_mutex_unlock(&runtime_mutex);
+               return TPL_ERROR_INVALID_OPERATION;
+       }
+
+       if (NULL == runtime->surfaces[type]) {
+               runtime->surfaces[type] = __tpl_hashlist_create();
+               if (NULL == runtime->surfaces[type]) {
+                       TPL_ERR("__tpl_hashlist_create failed.");
+                       pthread_mutex_unlock(&runtime_mutex);
+                       return TPL_ERROR_INVALID_OPERATION;
+               }
+       }
+
+       ret = __tpl_hashlist_insert(runtime->surfaces[type],
+                                                               (size_t) handle, (void *) surface);
+       if (TPL_ERROR_NONE != ret) {
+               TPL_ERR("__tpl_hashlist_insert failed. list(%p), handle(%p), surface(%p)",
+                               runtime->surfaces[type], handle, surface);
+               pthread_mutex_unlock(&runtime_mutex);
+               return TPL_ERROR_INVALID_OPERATION;
+       }
+
+       pthread_mutex_unlock(&runtime_mutex);
+
+       return TPL_ERROR_NONE;
+}
+
+void
+__tpl_runtime_remove_surface(tpl_surface_t *surface)
+{
+       tpl_handle_t handle = surface->native_handle;
+       tpl_backend_type_t type = surface->backend.type;
+
+       pthread_mutex_lock(&runtime_mutex);
+
+       if (type != TPL_BACKEND_UNKNOWN) {
+               if (runtime != NULL && runtime->surfaces[type] != NULL)
+                       __tpl_hashlist_delete(runtime->surfaces[type],
+                                                                 (size_t) handle);
+       }
+
+       pthread_mutex_unlock(&runtime_mutex);
+}
+
 void
 __tpl_surface_init_backend(tpl_surface_t *surface, tpl_backend_type_t type)
 {
index 56552a4..d8f037d 100644 (file)
@@ -201,6 +201,12 @@ __tpl_runtime_find_display(tpl_backend_type_t type,
 tpl_result_t __tpl_runtime_add_display(tpl_display_t *display);
 void __tpl_runtime_remove_display(tpl_display_t *display);
 
+tpl_surface_t *
+__tpl_runtime_find_surface(tpl_backend_type_t type,
+                                                  tpl_handle_t native_surface);
+tpl_result_t __tpl_runtime_add_surface(tpl_surface_t *surface);
+void __tpl_runtime_remove_surface(tpl_surface_t *surface);
+
 /* 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);
index 254da8d..f9d9443 100644 (file)
@@ -6,6 +6,7 @@ __tpl_surface_fini(tpl_surface_t *surface)
        TPL_ASSERT(surface);
 
        surface->backend.fini(surface);
+       __tpl_runtime_remove_surface(surface);
 }
 
 static void
@@ -22,7 +23,8 @@ tpl_surface_t *
 tpl_surface_create(tpl_display_t *display, tpl_handle_t handle,
                                   tpl_surface_type_t type, tbm_format format)
 {
-       tpl_surface_t *surface;
+       tpl_surface_t *surface = NULL;
+       tpl_result_t ret = TPL_ERROR_NONE;
 
        if (!display) {
                TPL_ERR("Display is NULL!");
@@ -34,6 +36,13 @@ tpl_surface_create(tpl_display_t *display, tpl_handle_t handle,
                return NULL;
        }
 
+       surface = __tpl_runtime_find_surface(type, handle);
+       if (surface) {
+               TPL_LOG_F("[REUSE] tpl_display_t(%p) tpl_surface_t(%p) native_handle(%p) format(%d)",
+                                 display, surface, handle, format);
+               return surface;
+       }
+
        surface = (tpl_surface_t *) calloc(1, sizeof(tpl_surface_t));
        if (!surface) {
                TPL_ERR("Failed to allocate memory for surface!");
@@ -67,6 +76,14 @@ tpl_surface_create(tpl_display_t *display, tpl_handle_t handle,
                return NULL;
        }
 
+       /* Add it to the runtime. */
+       ret = __tpl_runtime_add_surface(surface);
+       if (ret != TPL_ERROR_NONE) {
+               TPL_ERR("Failed to add surface to runtime list!");
+               tpl_object_unreference((tpl_object_t *) surface);
+               return NULL;
+       }
+
        TPL_LOG_F("tpl_display_t(%p) tpl_surface_t(%p) native_handle(%p) format(%d)",
                          display, surface, handle, format);
        return surface;