backend: load the tbm_backend_module_data and init/deinit. 69/172369/7
authorSooChan Lim <sc1.lim@samsung.com>
Tue, 13 Mar 2018 10:26:44 +0000 (19:26 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Wed, 14 Mar 2018 09:39:22 +0000 (09:39 +0000)
load the new backend module data and initialize/deinitialize
the backend module.

The tbm_bufmgr_init load the new backend module at first.
If the backend module does not implement with the new tbm_backend.h,
libtbm finds and load the old init symbol from the backend module.

Change-Id: I85e91615cee3ff9615d4680077037aa5d82d1455

src/tbm_bufmgr.c

index c027195..8988299 100644 (file)
@@ -235,6 +235,150 @@ _check_version(TBMModuleVersionInfo *data)
 }
 
 static int
+_tbm_backend_check_bufmgr_func(tbm_backend_bufmgr_func *bufmgr_func)
+{
+       TBM_RETURN_VAL_IF_FAIL(bufmgr_func, 0); /* mandatory symbol */
+       TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_capabilities, 0); /* mandatory symbol */
+       TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_bind_native_display, 0); /* mandatory symbol */
+       TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_supported_formats, 0); /* mandatory symbol */
+       TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_plane_data, 0); /* mandatory symbol */
+       TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_alloc_bo, 0); /* mandatory symbol */
+       if (!bufmgr_func->bufmgr_alloc_bo_with_format)
+               TBM_DBG("No bufmgr_func->bufmgr_alloc_bo_with_format.");
+       TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_import_fd, 0); /* mandatory symbol */
+       if (!bufmgr_func->bufmgr_import_key)
+               TBM_DBG("No bufmgr_func->bo_export_key.");
+
+       return 1;
+}
+
+static int
+_tbm_backend_check_bufmgr_bo(tbm_backend_bo_func *bo_func)
+{
+       TBM_RETURN_VAL_IF_FAIL(bo_func, 0); /* mandatory symbol */
+       TBM_RETURN_VAL_IF_FAIL(bo_func->bo_free, 0); /* mandatory symbol */
+       TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_size, 0); /* mandatory symbol */
+       TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_memory_types, 0); /* mandatory symbol */
+       TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_handle, 0); /* mandatory symbol */
+       TBM_RETURN_VAL_IF_FAIL(bo_func->bo_map, 0); /* mandatory symbol */
+       TBM_RETURN_VAL_IF_FAIL(bo_func->bo_unmap, 0); /* mandatory symbol */
+       if (!bo_func->bo_lock)
+               TBM_DBG("No bo_func->bo_lock.");
+       if (!bo_func->bo_unlock)
+               TBM_DBG("No bo_func->bo_unlock.");
+       TBM_RETURN_VAL_IF_FAIL(bo_func->bo_export_fd, 0); /* mandatory symbol */
+       if (!bo_func->bo_export_key)
+               TBM_INFO("No bo_func->bo_export_key.");
+
+       return 1;
+}
+
+static int
+_tbm_backend_load_module(tbm_bufmgr bufmgr, const char *file)
+{
+       char path[PATH_MAX] = {0, };
+       void *module_data = NULL;
+       tbm_backend_module *backend_module_data = NULL;
+       tbm_backend_bufmgr_data *bufmgr_data = NULL;
+       int abimaj, abimin;
+       int vermaj, vermin;
+       tbm_error_e error;
+
+       snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
+
+       module_data = dlopen(path, RTLD_LAZY);
+       if (!module_data) {
+               TBM_ERR("failed to load module: %s(%s)\n", dlerror(), file);
+               return 0;
+       }
+
+       backend_module_data = dlsym(module_data, "tbm_backend_module_data");
+       if (!backend_module_data) {
+               TBM_ERR("Error: module does not have data object.\n");
+               goto err;
+       }
+
+       abimaj = GET_ABI_MAJOR(backend_module_data->abi_version);
+       abimin = GET_ABI_MINOR(backend_module_data->abi_version);
+
+       TBM_DBG("TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
+           backend_module_data->name ? backend_module_data->name : "UNKNOWN!",
+           backend_module_data->vendor ? backend_module_data->vendor : "UNKNOWN!",
+               abimaj, abimin);
+
+       vermaj = GET_ABI_MAJOR(TBM_BACKEND_ABI_LATEST_VERSION);
+       vermin = GET_ABI_MINOR(TBM_BACKEND_ABI_LATEST_VERSION);
+       TBM_DBG("TBM ABI version %d.%d\n", vermaj, vermin);
+
+       if (abimaj > vermaj) {
+               TBM_ERR("TBM module ABI major ver(%d) is newer than the TBM's ver(%d)\n",
+                       abimaj, vermaj);
+               goto err;
+       } else if (abimin > vermin) {
+               TBM_ERR("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
+                       abimin, vermin);
+               goto err;
+       }
+
+       if (!backend_module_data->init) {
+               TBM_ERR("Error: module does not supply init symbol.\n");
+               goto err;
+       }
+
+       if (!backend_module_data->deinit)       {
+               TBM_ERR("Error: module does not supply deinit symbol.\n");
+               goto err;
+       }
+
+       bufmgr_data = backend_module_data->init(bufmgr, &error);
+       if (!bufmgr_data) {
+               TBM_ERR("Fail to init module(%s)\n", file);
+               goto err;
+       }
+
+       /* check the mandatory symbols of the backend module */
+       if (!_tbm_backend_check_bufmgr_func(bufmgr->bufmgr_func)) {
+               TBM_ERR("Fail to check the bufmgr_func symboles.");
+               goto err;
+       }
+
+       if (!_tbm_backend_check_bufmgr_bo(bufmgr->bo_func)) {
+               TBM_ERR("Fail to check the bufmgr_bo symboles.");
+               goto err;
+       }
+
+       /* get the capability */
+       bufmgr->capabilities = bufmgr->bufmgr_func->bufmgr_get_capabilities(bufmgr_data, &error);
+       if (bufmgr->capabilities == TBM_BUFMGR_CAPABILITY_NONE) {
+               TBM_ERR("The capabilities of the backend module is TBM_BUFMGR_CAPABILITY_NONE.");
+               TBM_ERR("TBM_BUFMGR_CAPABILITY_SHARE_FD is the essential capability.");
+               goto err;
+       }
+
+       if (!(bufmgr->capabilities & TBM_BUFMGR_CAPABILITY_SHARE_FD)) {
+               TBM_ERR("The capabilities of the backend module had no TBM_BUFMGR_CAPABILITY_SHARE_FD.");
+               TBM_ERR("The tbm backend has to get TBM_BUFMGR_CAPABILITY_SHARE_FD. ");
+               goto err;
+       }
+
+       bufmgr->module_data = module_data;
+       bufmgr->backend_module_data = backend_module_data;
+       bufmgr->bufmgr_data = bufmgr_data;
+
+       TBM_DBG("Success to load module(%s)\n", file);
+
+       return 1;
+
+err:
+       if (bufmgr_data)
+               bufmgr->backend_module_data->deinit(bufmgr_data);
+       if (module_data)
+               dlclose(module_data);
+
+       return 0;
+}
+
+static int
 _tbm_bufmgr_load_module(tbm_bufmgr bufmgr, int fd, const char *file)
 {
        char path[PATH_MAX] = {0, };
@@ -301,8 +445,14 @@ _tbm_load_module(tbm_bufmgr bufmgr, int fd)
        struct dirent **namelist;
        int ret = 0, n;
 
-       /* load bufmgr priv from default lib */
-       if (_tbm_bufmgr_load_module(bufmgr, fd, DEFAULT_LIB))
+       /* try to load the new backend module */
+       ret = _tbm_backend_load_module(bufmgr, DEFAULT_LIB);
+       if (ret)
+               return 1;
+
+       /* try to load the old(deprecated) backend mdoule */
+       ret = _tbm_bufmgr_load_module(bufmgr, fd, DEFAULT_LIB);
+       if (ret)
                return 1;
 
        /* load bufmgr priv from configured path */
@@ -316,9 +466,12 @@ _tbm_load_module(tbm_bufmgr bufmgr, int fd)
                if (!ret && strstr(namelist[n]->d_name, PREFIX_LIB)) {
                        const char *p = strstr(namelist[n]->d_name, SUFFIX_LIB);
 
-                       if (p && !strcmp(p, SUFFIX_LIB))
-                               ret = _tbm_bufmgr_load_module(bufmgr, fd,
-                                                       namelist[n]->d_name);
+                       if (p && !strcmp(p, SUFFIX_LIB)) {
+                               ret = _tbm_backend_load_module(bufmgr, namelist[n]->d_name);
+                               if (!ret)
+                                       ret = _tbm_bufmgr_load_module(bufmgr, fd,
+                                                                       namelist[n]->d_name);
+                       }
                }
 
                free(namelist[n]);
@@ -503,11 +656,20 @@ tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
                LIST_DELINIT(&bufmgr->surf_list);
        }
 
-       /* destroy bufmgr priv */
-       bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
-       bufmgr->backend->priv = NULL;
-       tbm_backend_free(bufmgr->backend);
-       bufmgr->backend = NULL;
+       if (bufmgr->backend_module_data) {
+               /* deinit and backend destroys the backend func and data */
+               bufmgr->backend_module_data->deinit(bufmgr->bufmgr_data);
+               bufmgr->bo_func = NULL;
+               bufmgr->bufmgr_func = NULL;
+               bufmgr->bufmgr_data = NULL;
+               bufmgr->backend_module_data = NULL;
+       } else {
+               /* destroy bufmgr priv */
+               bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
+               bufmgr->backend->priv = NULL;
+               tbm_backend_free(bufmgr->backend);
+               bufmgr->backend = NULL;
+       }
 
        TBM_INFO("destroy tbm_bufmgr(%p)\n", bufmgr);