tbm_module: Fix leak of fd
[platform/core/uifw/libtbm.git] / src / tbm_module.c
1 /**************************************************************************
2
3 libtbm
4
5 Copyright 2012-2021 Samsung Electronics co., Ltd. All Rights Reserved.
6
7 Contact: SooChan Lim <sc1.lim@samsung.com>
8          Changyeon Lee <cyeon.lee@samsung.com>
9
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
17
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
20 of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 **************************************************************************/
31
32 #include "config.h"
33
34 #include "tbm_bufmgr_int.h"
35 #include "tbm_bufmgr_backend.h"
36 #include "tbm_drm_helper.h"
37
38 #define PREFIX_LIB    "libtbm_"
39 #define SUFFIX_LIB    ".so"
40 #define DEFAULT_LIB   PREFIX_LIB"default"SUFFIX_LIB
41
42 /* values to indicate unspecified fields in XF86ModReqInfo. */
43 #define MAJOR_UNSPEC      0xFF
44 #define MINOR_UNSPEC      0xFF
45 #define PATCH_UNSPEC      0xFFFF
46 #define ABI_VERS_UNSPEC   0xFFFFFFFF
47
48 #define MODULE_VERSION_NUMERIC(maj, min, patch) \
49                         ((((maj) & 0xFF) << 24) | (((min) & 0xFF) << 16) | (patch & 0xFFFF))
50 #define GET_MODULE_MAJOR_VERSION(vers)    (((vers) >> 24) & 0xFF)
51 #define GET_MODULE_MINOR_VERSION(vers)    (((vers) >> 16) & 0xFF)
52 #define GET_MODULE_PATCHLEVEL(vers)    ((vers) & 0xFFFF)
53
54 /* LCOV_EXCL_START */
55 static int
56 _tbm_backend_load_hal_tbm(tbm_module *module)
57 {
58         hal_tbm_backend *hal_backend = NULL;
59         hal_tbm_bufmgr *hal_bufmgr;
60         hal_tbm_error ret = HAL_TBM_ERROR_NONE;
61         hal_tbm_fd auth_drm_fd = -1;
62
63         hal_backend = hal_tbm_get_backend(&ret);
64         if (hal_backend == NULL || ret != HAL_TBM_ERROR_NONE) {
65                 TBM_ERR("get backend fail");
66                 return 0;
67         }
68
69         hal_bufmgr = hal_tbm_backend_get_bufmgr(hal_backend, &ret);
70         if (hal_bufmgr == NULL || ret != HAL_TBM_ERROR_NONE) {
71                 TBM_ERR("get hal_bufmgr fail");
72                 goto get_backend_fail;
73         }
74
75         if (hal_tbm_backend_has_drm_device(hal_backend, &ret)) {
76                 auth_drm_fd = hal_tbm_backend_get_master_drm_fd(hal_backend, &ret);
77                 if (auth_drm_fd < 0) {
78                         TBM_INFO("tbm_backend has no master drm_fd.");
79
80                         auth_drm_fd = tbm_drm_helper_get_master_fd();
81                         if (auth_drm_fd < 0) {
82                                 TBM_INFO("libtbm requests an authenticated drm_fd to a process(display server).");
83                                 if (!tbm_drm_helper_get_auth_info(&auth_drm_fd, NULL, NULL)) {
84                                         TBM_ERR("get auth drm_fd fail");
85                                         goto get_backend_fail;
86                                 }
87                         } else {
88                                 TBM_INFO("libtbm gets a master drm_fd from libtdm via tbm_drm_helper.");
89                         }
90
91                         TBM_INFO("libtbm sends a master drm_fd as an authentiated drm_fd to tbm_backend.");
92                         ret = hal_tbm_backend_set_authenticated_drm_fd(hal_backend, auth_drm_fd);
93                         if (ret != HAL_TBM_ERROR_NONE) {
94                                 TBM_ERR("hal_tbm_backend_set_authenticated_drm_fd failed.");
95                                 goto get_backend_fail;
96                         }
97                 } else {
98                         TBM_INFO("tbm_backend has a master drm_fd.");
99
100                         tbm_drm_helper_set_tbm_master_fd(auth_drm_fd);
101                 }
102                 tbm_drm_helper_set_fd(auth_drm_fd);
103         }
104
105         module->hal_backend = hal_backend;
106         module->hal_bufmgr = hal_bufmgr;
107
108         module->use_hal_tbm = 1;
109
110         TBM_INFO("use HAL-TBM_API");
111
112         return 1;
113
114 get_backend_fail:
115         if (auth_drm_fd >= 0)
116                 close(auth_drm_fd);
117         hal_tbm_put_backend(hal_backend);
118         return 0;
119 }
120
121 static int
122 _check_version(TBMModuleVersionInfo *data)
123 {
124         int backend_module_major, backend_module_minor;
125         int tbm_backend_major, tbm_backend_minor;
126
127         backend_module_major = GET_ABI_MAJOR(data->abiversion);
128         backend_module_minor = GET_ABI_MINOR(data->abiversion);
129
130         TBM_DBG("TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
131             data->modname ? data->modname : "UNKNOWN!",
132             data->vendor ? data->vendor : "UNKNOWN!", backend_module_major, backend_module_minor);
133
134         tbm_backend_major = GET_ABI_MAJOR(TBM_ABI_VERSION);
135         tbm_backend_minor = GET_ABI_MINOR(TBM_ABI_VERSION);
136
137         TBM_DBG("TBM ABI version %d.%d\n",
138             tbm_backend_major, tbm_backend_minor);
139
140         if (backend_module_major != tbm_backend_major) {
141                 TBM_ERR("TBM module ABI major ver(%d) doesn't match the TBM's ver(%d)\n",
142                         backend_module_major, tbm_backend_major);
143                 return 0;
144         } else if (backend_module_minor > tbm_backend_minor) {
145                 TBM_ERR("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
146                         backend_module_minor, tbm_backend_minor);
147                 return 0;
148         }
149
150         return 1;
151 }
152
153 static int
154 _tbm_backend_check_bufmgr_func(tbm_backend_bufmgr_func *bufmgr_func)
155 {
156         TBM_RETURN_VAL_IF_FAIL(bufmgr_func, 0); /* mandatory symbol */
157         TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_capabilities, 0); /* mandatory symbol */
158         TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_bind_native_display, 0); /* mandatory symbol */
159         TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_supported_formats, 0); /* mandatory symbol */
160         TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_plane_data, 0); /* mandatory symbol */
161         TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_alloc_bo, 0); /* mandatory symbol */
162         if (!bufmgr_func->bufmgr_alloc_bo_with_format)
163                 TBM_DBG("No bufmgr_func->bufmgr_alloc_bo_with_format.");
164         TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_import_fd, 0); /* mandatory symbol */
165         if (!bufmgr_func->bufmgr_import_key)
166                 TBM_DBG("No bufmgr_func->bo_export_key.");
167
168         return 1;
169 }
170
171 static int
172 _tbm_backend_check_bufmgr_bo(tbm_backend_bo_func *bo_func)
173 {
174         TBM_RETURN_VAL_IF_FAIL(bo_func, 0); /* mandatory symbol */
175         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_free, 0); /* mandatory symbol */
176         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_size, 0); /* mandatory symbol */
177         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_memory_types, 0); /* mandatory symbol */
178         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_handle, 0); /* mandatory symbol */
179         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_map, 0); /* mandatory symbol */
180         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_unmap, 0); /* mandatory symbol */
181         if (!bo_func->bo_lock)
182                 TBM_DBG("No bo_func->bo_lock.");
183         if (!bo_func->bo_unlock)
184                 TBM_DBG("No bo_func->bo_unlock.");
185         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_export_fd, 0); /* mandatory symbol */
186         if (!bo_func->bo_export_key)
187                 TBM_INFO("No bo_func->bo_export_key.");
188
189         return 1;
190 }
191
192 static int
193 _tbm_backend_load_module(tbm_module *module, const char *file)
194 {
195         char path[PATH_MAX] = {0, };
196         void *module_data = NULL;
197         tbm_backend_module *backend_module_data = NULL;
198         tbm_backend_bufmgr_data *bufmgr_data = NULL;
199         int backend_module_major, backend_module_minor;
200         int tbm_backend_major, tbm_backend_minor;
201         tbm_error_e error;
202
203         snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
204
205         module_data = dlopen(path, RTLD_LAZY);
206         if (!module_data) {
207                 TBM_ERR("failed to load module: %s(%s)\n", dlerror(), file);
208                 return 0;
209         }
210
211         backend_module_data = dlsym(module_data, "tbm_backend_module_data");
212         if (!backend_module_data) {
213                 TBM_ERR("Error: module does not have data object.\n");
214                 goto err;
215         }
216
217         tbm_backend_major = GET_ABI_MAJOR(TBM_BACKEND_ABI_LATEST_VERSION);
218         tbm_backend_minor = GET_ABI_MINOR(TBM_BACKEND_ABI_LATEST_VERSION);
219         TBM_INFO("TBM Backend ABI version %d.%d\n", tbm_backend_major, tbm_backend_minor);
220
221         backend_module_major = GET_ABI_MAJOR(backend_module_data->abi_version);
222         backend_module_minor = GET_ABI_MINOR(backend_module_data->abi_version);
223
224         TBM_INFO("TBM module %s: vendor=\"%s\" Backend ABI version=%d.%d\n",
225             backend_module_data->name ? backend_module_data->name : "UNKNOWN!",
226             backend_module_data->vendor ? backend_module_data->vendor : "UNKNOWN!",
227                 backend_module_major, backend_module_minor);
228
229         if (backend_module_major > tbm_backend_major) {
230                 TBM_ERR("TBM module ABI major ver(%d) is newer than the TBM's ver(%d)\n",
231                         backend_module_major, tbm_backend_major);
232                 goto err;
233         } else if (backend_module_minor > tbm_backend_minor) {
234                 TBM_ERR("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
235                         backend_module_minor, tbm_backend_minor);
236                 goto err;
237         }
238
239         if (!backend_module_data->init) {
240                 TBM_ERR("Error: module does not supply init symbol.\n");
241                 goto err;
242         }
243
244         if (!backend_module_data->deinit)       {
245                 TBM_ERR("Error: module does not supply deinit symbol.\n");
246                 goto err;
247         }
248
249         bufmgr_data = backend_module_data->init((tbm_bufmgr)module, &error);
250         if (!bufmgr_data) {
251                 TBM_ERR("Fail to init module(%s)\n", file);
252                 goto err;
253         }
254
255         /* check the mandatory symbols of the backend module */
256         if (!_tbm_backend_check_bufmgr_func(module->bufmgr_func)) {
257                 TBM_ERR("Fail to check the bufmgr_func symboles.");
258                 goto err;
259         }
260
261         if (!_tbm_backend_check_bufmgr_bo(module->bo_func)) {
262                 TBM_ERR("Fail to check the bufmgr_bo symboles.");
263                 goto err;
264         }
265
266         module->module_data = module_data;
267         module->backend_module_data = backend_module_data;
268         module->bufmgr_data = bufmgr_data;
269
270         TBM_INFO("Success to load module(%s)\n", file);
271
272         return 1;
273
274 err:
275         if (bufmgr_data)
276                 module->backend_module_data->deinit(bufmgr_data);
277         if (module_data)
278                 dlclose(module_data);
279
280         return 0;
281 }
282
283 static int
284 _tbm_backend_load_bufmgr_module(tbm_module *module, int fd, const char *file)
285 {
286         char path[PATH_MAX] = {0, };
287         TBMModuleVersionInfo *vers;
288         TBMModuleData *initdata;
289         ModuleInitProc init;
290         void *module_data;
291
292         snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
293
294         module_data = dlopen(path, RTLD_LAZY);
295         if (!module_data) {
296                 TBM_ERR("failed to load module: %s(%s)\n", dlerror(), file);
297                 return 0;
298         }
299
300         initdata = dlsym(module_data, "tbmModuleData");
301         if (!initdata) {
302                 TBM_ERR("Error: module does not have data object.\n");
303                 goto err;
304         }
305
306         vers = initdata->vers;
307         if (!vers) {
308                 TBM_ERR("Error: module does not supply version information.\n");
309                 goto err;
310         }
311
312         init = initdata->init;
313         if (!init) {
314                 TBM_ERR("Error: module does not supply init symbol.\n");
315                 goto err;
316         }
317
318         if (!_check_version(vers)) {
319                 TBM_ERR("Fail to check version.\n");
320                 goto err;
321         }
322
323         if (!init((tbm_bufmgr)module, fd)) {
324                 TBM_ERR("Fail to init module(%s)\n", file);
325                 goto err;
326         }
327
328         if (!module->backend || !module->backend->priv) {
329                 TBM_ERR("Error: module(%s) wrong operation. Check backend or backend's priv.\n", file);
330                 goto err;
331         }
332
333         module->module_data = module_data;
334
335         TBM_DBG("Success to load module(%s)\n", file);
336
337         return 1;
338
339 err:
340         dlclose(module_data);
341         return 0;
342 }
343 /* LCOV_EXCL_STOP */
344
345 tbm_module *
346 tbm_module_load(int fd)
347 {
348         tbm_module *module;
349         struct dirent **namelist;
350         int ret = 0, n;
351
352         module = calloc(1, sizeof(struct _tbm_module));
353         if (!module) {
354                 TBM_ERR("fail to allocate the memory");
355                 return NULL;
356         }
357
358         /* try to load the hal-tbm backend module */
359         ret = _tbm_backend_load_hal_tbm(module);
360         if (ret) {
361                 module->type = TBM_MODULE_TYPE_HAL_TBM;
362                 goto done;
363         }
364
365 /* LCOV_EXCL_START */
366         /* try to load the new backend module */
367         ret = _tbm_backend_load_module(module, DEFAULT_LIB);
368         if (ret) {
369                 module->type = TBM_MODULE_TYPE_TBM_BACKEND;
370                 goto done;
371         }
372
373         /* try to load the old(deprecated) backend mdoule */
374         ret = _tbm_backend_load_bufmgr_module(module, fd, DEFAULT_LIB);
375         if (ret) {
376                 module->type = TBM_MODULE_TYPE_BUFMGR_BACKEND;
377                 return module;
378         }
379
380         /* load backend_module from configured path */
381         n = scandir(BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
382         if (n < 0) {
383                 TBM_ERR("no files : %s\n", BUFMGR_MODULE_DIR);
384                 tbm_module_unload(module);
385                 return NULL;
386         }
387
388         while (n--) {
389                 if (!ret && strstr(namelist[n]->d_name, PREFIX_LIB)) {
390                         const char *p = strstr(namelist[n]->d_name, SUFFIX_LIB);
391
392                         if (p && !strcmp(p, SUFFIX_LIB)) {
393                                 ret = _tbm_backend_load_module(module, namelist[n]->d_name);
394                                 if (ret)
395                                         module->type = TBM_MODULE_TYPE_TBM_BACKEND;
396                                 else {
397                                         ret = _tbm_backend_load_bufmgr_module(module, fd, namelist[n]->d_name);
398                                         module->type = TBM_MODULE_TYPE_BUFMGR_BACKEND;
399                                 }
400                         }
401                 }
402
403                 free(namelist[n]);
404         }
405
406         free(namelist);
407
408         if (!ret) {
409                 free(module);
410                 module = NULL;
411         }
412 /* LCOV_EXCL_STOP */
413
414 done:
415         return module;
416 }
417
418 void
419 tbm_module_unload(tbm_module *module)
420 {
421         switch (module->type) {
422         case TBM_MODULE_TYPE_HAL_TBM:
423                 if (module->auth_wl_socket_created) {
424                         tbm_drm_helper_wl_auth_server_deinit();
425                         close(module->auth_fd);
426                 }
427                 tbm_drm_helper_unset_tbm_master_fd();
428                 tbm_drm_helper_unset_fd();
429
430                 hal_tbm_put_backend(module->hal_backend);
431                 module->hal_backend = NULL;
432                 module->hal_bufmgr = NULL;
433                 module->use_hal_tbm = 0;
434                 break;
435 /* LCOV_EXCL_START */
436         case TBM_MODULE_TYPE_TBM_BACKEND:
437                 module->backend_module_data->deinit(module->bufmgr_data);
438                 module->bo_func = NULL;
439                 module->bufmgr_func = NULL;
440                 module->bufmgr_data = NULL;
441                 module->backend_module_data = NULL;
442
443                 dlclose(module->module_data);
444                 break;
445         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
446                 module->backend->bufmgr_deinit(module->backend->priv);
447                 module->backend->priv = NULL;
448                 tbm_backend_free(module->backend);
449                 module->backend = NULL;
450
451                 dlclose(module->module_data);
452                 break;
453         default:
454                 TBM_ERR("Wrong module type:%d", module->type);
455                 break;
456 /* LCOV_EXCL_STOP */
457         }
458
459         free(module);
460 }
461
462 int
463 tbm_module_get_capabilities(tbm_module *module, tbm_error_e *error)
464 {
465         int capabilities = 0;
466         tbm_backend_bufmgr_func *bufmgr_func = NULL;
467
468         TBM_RETURN_VAL_SET_ERR_IF_FAIL(module, TBM_BUFMGR_CAPABILITY_NONE, *error, TBM_ERROR_INVALID_PARAMETER);
469
470         switch (module->type) {
471         case TBM_MODULE_TYPE_HAL_TBM:
472                 capabilities = hal_tbm_bufmgr_get_capabilities(module->hal_bufmgr, (hal_tbm_error *)error);
473                 break;
474 /* LCOV_EXCL_START */
475         case TBM_MODULE_TYPE_TBM_BACKEND:
476                 bufmgr_func = module->bufmgr_func;
477                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr_func, 0, *error, TBM_ERROR_INVALID_OPERATION);
478                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr_func->bufmgr_get_capabilities, 0, *error, TBM_ERROR_NOT_SUPPORTED);
479
480                 capabilities = module->bufmgr_func->bufmgr_get_capabilities(module->bufmgr_data, error);
481                 break;
482         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
483                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
484                 TBM_ERR("Do not support at tbm_bufmgr_backend.");
485
486                 *error = TBM_ERROR_NOT_SUPPORTED;
487                 break;
488         default:
489                 TBM_ERR("Wrong module type:%d", module->type);
490                 *error = TBM_ERROR_INVALID_OPERATION;
491                 break;
492 /* LCOV_EXCL_STOP */
493         }
494
495         return capabilities;
496 }
497
498 tbm_error_e
499 tbm_module_bind_native_display(tbm_module *module, void *native_display)
500 {
501         tbm_error_e error = TBM_ERROR_NONE;
502         tbm_backend_bufmgr_func *bufmgr_func = NULL;
503         tbm_bufmgr_backend backend = NULL;
504         int ret = 0;
505
506         TBM_RETURN_VAL_IF_FAIL(module, TBM_ERROR_INVALID_PARAMETER);
507
508         switch (module->type) {
509         case TBM_MODULE_TYPE_HAL_TBM:
510                 if (hal_tbm_backend_has_drm_device(module->hal_backend, &ret)) {
511                         int fd = tbm_drm_helper_get_fd(); // this must be the auth drm_fd.(master drm_fd);
512                         if (fd < 0) {
513                                 TBM_ERR("error: module(%p) native_display(%p)\n", module, native_display);
514                                 return TBM_ERROR_INVALID_OPERATION;
515                         }
516
517                         if (tbm_drm_helper_is_render_node(fd)) {
518                                 TBM_INFO("tbm_module has render node.");
519                                 close(fd);
520                                 error = TBM_ERROR_NONE;
521                         } else {
522                                 // make the wayland server socket for sending the authenticated drm_fd to wayland clients.
523                                 if (!tbm_drm_helper_wl_auth_server_init(native_display, fd, NULL, 0)) {
524                                         TBM_ERR("error: tbm_drm_helper_wl_auth_server_init failed\n", module, native_display);
525                                         close(fd);
526                                         return TBM_ERROR_INVALID_OPERATION;
527                                 }
528                                 TBM_INFO("tbm creates a wayland socket for authentication of drm_fd.");
529
530                                 module->auth_wl_socket_created = 1;
531                                 module->auth_fd = fd;
532                         }
533                 } else {
534                         TBM_INFO("tbm_module has no drm device.");
535                         error = TBM_ERROR_NONE;
536                 }
537                 break;
538 /* LCOV_EXCL_START */
539         case TBM_MODULE_TYPE_TBM_BACKEND:
540                 bufmgr_func = module->bufmgr_func;
541                 TBM_RETURN_VAL_IF_FAIL(bufmgr_func, TBM_ERROR_INVALID_OPERATION);
542                 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_bind_native_display, TBM_ERROR_NOT_SUPPORTED);
543
544                 error = bufmgr_func->bufmgr_bind_native_display(module->bufmgr_data, (tbm_native_display *)native_display);
545                 break;
546         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
547                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
548                 backend = module->backend;
549                 TBM_RETURN_VAL_IF_FAIL(backend, TBM_ERROR_INVALID_OPERATION);
550                 TBM_RETURN_VAL_IF_FAIL(backend->bufmgr_bind_native_display, TBM_ERROR_NOT_SUPPORTED);
551
552                 ret = backend->bufmgr_bind_native_display((tbm_bufmgr)module, native_display);
553                 if (!ret)
554                         error = TBM_ERROR_INVALID_OPERATION;
555
556                 break;
557         default:
558                 TBM_ERR("Wrong module type:%d", module->type);
559                 error = TBM_ERROR_INVALID_OPERATION;
560                 break;
561 /* LCOV_EXCL_STOP */
562         }
563
564         return error;
565 }
566
567 tbm_error_e
568 tbm_module_get_supported_formats(tbm_module *module, uint32_t **formats, uint32_t *num)
569 {
570         tbm_error_e error = TBM_ERROR_NONE;
571         tbm_backend_bufmgr_func *bufmgr_func = NULL;
572         tbm_bufmgr_backend backend = NULL;
573         int ret = 0;
574
575         TBM_RETURN_VAL_IF_FAIL(module, TBM_ERROR_INVALID_PARAMETER);
576
577         switch (module->type) {
578         case TBM_MODULE_TYPE_HAL_TBM:
579                 error = (tbm_error_e)hal_tbm_bufmgr_get_supported_formats(module->hal_bufmgr, formats, num);
580                 break;
581 /* LCOV_EXCL_START */
582         case TBM_MODULE_TYPE_TBM_BACKEND:
583                 bufmgr_func = module->bufmgr_func;
584                 TBM_RETURN_VAL_IF_FAIL(bufmgr_func, TBM_ERROR_INVALID_OPERATION);
585                 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_supported_formats, TBM_ERROR_NOT_SUPPORTED);
586
587                 error = bufmgr_func->bufmgr_get_supported_formats(module->bufmgr_data, formats, num);
588                 break;
589         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
590                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
591                 backend = module->backend;
592                 TBM_RETURN_VAL_IF_FAIL(backend, TBM_ERROR_INVALID_OPERATION);
593                 TBM_RETURN_VAL_IF_FAIL(backend->surface_supported_format, TBM_ERROR_NOT_SUPPORTED);
594
595                 ret = backend->surface_supported_format(formats, num);
596                 if (!ret)
597                         error = TBM_ERROR_INVALID_OPERATION;
598
599                 break;
600         default:
601                 TBM_ERR("Wrong module type:%d", module->type);
602                 error = TBM_ERROR_INVALID_OPERATION;
603                 break;
604 /* LCOV_EXCL_STOP */
605         }
606
607         return error;
608 }
609
610 tbm_error_e
611 tbm_module_get_plane_data(tbm_module *module, int format, int plane_idx, uint32_t w, uint32_t h,
612                                         uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
613 {
614         tbm_error_e error = TBM_ERROR_NONE;
615         tbm_backend_bufmgr_func *bufmgr_func = NULL;
616         tbm_bufmgr_backend backend = NULL;
617         int ret = 0;
618
619         TBM_RETURN_VAL_IF_FAIL(module, TBM_ERROR_INVALID_PARAMETER);
620
621         switch (module->type) {
622         case TBM_MODULE_TYPE_HAL_TBM:
623                 error = (tbm_error_e)hal_tbm_bufmgr_get_plane_data(module->hal_bufmgr, format, plane_idx, w, h, size, offset, pitch, bo_idx);
624                 break;
625 /* LCOV_EXCL_START */
626         case TBM_MODULE_TYPE_TBM_BACKEND:
627                 bufmgr_func = module->bufmgr_func;
628                 TBM_RETURN_VAL_IF_FAIL(bufmgr_func, TBM_ERROR_INVALID_OPERATION);
629                 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_plane_data, TBM_ERROR_NOT_SUPPORTED);
630
631                 error = bufmgr_func->bufmgr_get_plane_data(module->bufmgr_data, format, plane_idx, w, h, size, offset, pitch, bo_idx);
632                 break;
633         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
634                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
635                 backend = module->backend;
636                 TBM_RETURN_VAL_IF_FAIL(backend, TBM_ERROR_INVALID_OPERATION);
637                 TBM_RETURN_VAL_IF_FAIL(backend->surface_get_plane_data, TBM_ERROR_NOT_SUPPORTED);
638
639                 ret = backend->surface_get_plane_data(w, h, format, plane_idx, size, offset, pitch, bo_idx);
640                 if (!ret)
641                         error = TBM_ERROR_INVALID_OPERATION;
642                 break;
643         default:
644                 TBM_ERR("Wrong module type:%d", module->type);
645                 error = TBM_ERROR_INVALID_OPERATION;
646                 break;
647 /* LCOV_EXCL_STOP */
648         }
649
650         return error;
651 }
652
653 int
654 tbm_module_support_surface_data(tbm_module *module)
655 {
656         tbm_error_e error = TBM_ERROR_NONE;
657         tbm_surface_data *surface_data = NULL;
658
659         TBM_RETURN_VAL_IF_FAIL(module, 0);
660
661         // check once support_surface_data or not.
662         if (module->check_surface_data) {
663                 // return the value which already set.
664                 return module->support_surface_data;
665         }
666
667         // check this only once
668         module->check_surface_data = 1;
669
670         if (module->type != TBM_MODULE_TYPE_HAL_TBM)
671                 goto done;
672
673         // Assume that the hal-tbm supports the hal surface apis if tbm_module_alloc_surface_data succeed.
674         surface_data = tbm_module_alloc_surface_data(module, 10, 10, TBM_FORMAT_ARGB8888, TBM_BO_DEFAULT, &error);
675         if (!surface_data)
676                 goto done;
677         free(surface_data);
678
679         module->support_surface_data = 1;
680
681 done:
682         return module->support_surface_data;
683 }
684
685
686 tbm_surface_data *
687 tbm_module_alloc_surface_data(tbm_module *module, int width, int height, int format, int flags, tbm_error_e *error)
688 {
689         tbm_surface_data *surface_data = NULL;
690
691         TBM_RETURN_VAL_SET_ERR_IF_FAIL(module, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
692         TBM_RETURN_VAL_SET_ERR_IF_FAIL(module->type == TBM_MODULE_TYPE_HAL_TBM, NULL, *error, TBM_ERROR_INVALID_OPERATION);
693
694         surface_data = calloc(1, sizeof(struct _tbm_surface_data));
695         if (!surface_data) {
696                 TBM_ERR("memory allocation failed.");
697                 *error = TBM_ERROR_OUT_OF_MEMORY;
698                 return NULL;
699         }
700
701         surface_data->hal_surface = hal_tbm_bufmgr_alloc_surface(module->hal_bufmgr,
702                                                                                            (uint32_t)width,
703                                                                                            (uint32_t)height,
704                                                                                            (hal_tbm_format)format,
705                                                                                            (hal_tbm_bo_memory_type)flags,
706                                                                                            NULL,
707                                                                                            0,
708                                                                                            (hal_tbm_error *)error);
709         if (!surface_data->hal_surface) {
710                 if (*error != TBM_ERROR_NOT_SUPPORTED) // do not print the error message when it is not supported.
711                         TBM_ERR("hal_tbm_bufmgr_alloc_surface failed.");
712                 free(surface_data);
713                 return NULL;
714         }
715
716         surface_data->module = module;
717
718         return surface_data;
719 }
720
721 tbm_surface_data *
722 tbm_module_import_surface_data(tbm_module *module, int width, int height, int format, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
723 {
724         tbm_surface_data *surface_data = NULL;
725
726         TBM_RETURN_VAL_SET_ERR_IF_FAIL(module, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
727         TBM_RETURN_VAL_SET_ERR_IF_FAIL(module->type == TBM_MODULE_TYPE_HAL_TBM, NULL, *error, TBM_ERROR_INVALID_OPERATION);
728
729         surface_data = calloc(1, sizeof(struct _tbm_surface_data));
730         if (!surface_data) {
731                 TBM_ERR("memory allocation failed.");
732                 *error = TBM_ERROR_OUT_OF_MEMORY;
733                 return NULL;
734         }
735
736         surface_data->hal_surface = hal_tbm_bufmgr_import_surface(module->hal_bufmgr,
737                                                                                         (uint32_t)width,
738                                                                                         (uint32_t)height,
739                                                                                         (hal_tbm_format)format,
740                                                                                         (hal_tbm_surface_buffer_data *)buffer_data,
741                                                                                         (hal_tbm_error *)error);
742         if (!surface_data->hal_surface) {
743                 TBM_ERR("hal_tbm_bufmgr_import_surface failed. width:%d height:%d format:%d error:%s",
744                                 width, height, format, tbm_error_str(*error));
745                 free(surface_data);
746                 return NULL;
747         }
748
749         surface_data->module = module;
750
751         return surface_data;
752 }
753
754 tbm_bo_data *
755 tbm_module_alloc_bo_data(tbm_module *module, tbm_bo bo, int size, int flags, tbm_error_e *error)
756 {
757         tbm_bo_data *bo_data = NULL;
758         tbm_backend_bufmgr_func *bufmgr_func = NULL;
759         tbm_bufmgr_backend backend = NULL;
760
761         TBM_RETURN_VAL_SET_ERR_IF_FAIL(module, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
762
763         bo_data = calloc(1, sizeof(struct _tbm_bo_data));
764         TBM_GOTO_VAL_SET_ERR_IF_FAIL(bo_data, failed, *error, TBM_ERROR_OUT_OF_MEMORY);
765
766         switch (module->type) {
767         case TBM_MODULE_TYPE_HAL_TBM:
768                 bo_data->hal_bo = hal_tbm_bufmgr_alloc_bo(module->hal_bufmgr, size, flags, (hal_tbm_error *)error);
769                 TBM_GOTO_VAL_IF_FAIL(bo_data->hal_bo, failed);
770                 break;
771 /* LCOV_EXCL_START */
772         case TBM_MODULE_TYPE_TBM_BACKEND:
773                 bufmgr_func = module->bufmgr_func;
774                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bufmgr_func, failed, *error, TBM_ERROR_INVALID_OPERATION);
775                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bufmgr_func->bufmgr_alloc_bo, failed, *error, TBM_ERROR_NOT_SUPPORTED);
776
777                 bo_data->backend_bo_data = bufmgr_func->bufmgr_alloc_bo(module->bufmgr_data, (unsigned int)size, flags, error);
778                 TBM_GOTO_VAL_IF_FAIL(bo_data->backend_bo_data, failed);
779                 break;
780         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
781                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
782
783                 backend = module->backend;
784                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(backend, failed, *error, TBM_ERROR_INVALID_OPERATION);
785                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(backend->bo_alloc, failed, *error, TBM_ERROR_NOT_SUPPORTED);
786
787                 bo_data->priv = (void *)backend->bo_alloc(bo, size, flags);
788                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bo_data->priv, failed, *error, TBM_ERROR_INVALID_OPERATION);
789
790                 *error = TBM_ERROR_NONE;
791                 break;
792         default:
793                 TBM_ERR("Wrong module type:%d", module->type);
794                 *error = TBM_ERROR_INVALID_OPERATION;
795                 goto failed;
796                 break;
797 /* LCOV_EXCL_STOP */
798         }
799
800         bo_data->module = module;
801
802         return bo_data;
803
804 /* LCOV_EXCL_START */
805 failed:
806         if (bo_data)
807                 free(bo_data);
808
809         return NULL;
810 /* LCOV_EXCL_STOP */
811 }
812
813 tbm_bo_data *
814 tbm_module_alloc_bo_data_with_format(tbm_module *module, int format, int bo_idx, int width,
815                                                 int height, int bpp, tbm_bo_memory_type flags, tbm_error_e *error)
816 {
817         tbm_bo_data *bo_data = NULL;
818         tbm_backend_bufmgr_func *bufmgr_func = NULL;
819
820         TBM_RETURN_VAL_SET_ERR_IF_FAIL(module, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
821
822         bo_data = calloc(1, sizeof(struct _tbm_bo_data));
823         TBM_GOTO_VAL_SET_ERR_IF_FAIL(bo_data, failed, *error, TBM_ERROR_OUT_OF_MEMORY);
824
825         switch (module->type) {
826         case TBM_MODULE_TYPE_HAL_TBM:
827                 bo_data->hal_bo = hal_tbm_bufmgr_alloc_bo_with_format(module->hal_bufmgr,
828                                                                                         format, bo_idx, width, height, bpp,
829                                                                                         (hal_tbm_bo_memory_type)flags, (hal_tbm_error *)error);
830                 if (!bo_data->hal_bo)
831                         goto failed;
832                 break;
833 /* LCOV_EXCL_START */
834         case TBM_MODULE_TYPE_TBM_BACKEND:
835                 bufmgr_func = module->bufmgr_func;
836                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bufmgr_func, failed, *error, TBM_ERROR_INVALID_OPERATION);
837                 if (!bufmgr_func->bufmgr_alloc_bo_with_format) {
838                         *error = TBM_ERROR_NOT_SUPPORTED;
839                         goto failed;
840                 }
841
842                 bo_data->backend_bo_data = bufmgr_func->bufmgr_alloc_bo_with_format(module->bufmgr_data, format, bo_idx, width, height, flags, error);
843                 if (!bo_data->backend_bo_data)
844                         goto failed;
845                 break;
846         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
847                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
848                 TBM_ERR("error: not supported tbm_module_alloc_bo_data_with_format.");
849
850                 *error = TBM_ERROR_NOT_SUPPORTED;
851                 goto failed;
852                 break;
853         default:
854                 TBM_ERR("Wrong module type:%d", module->type);
855                 *error = TBM_ERROR_INVALID_OPERATION;
856                 goto failed;
857                 break;
858 /* LCOV_EXCL_STOP */
859         }
860
861         bo_data->module = module;
862
863         return bo_data;
864
865 /* LCOV_EXCL_START */
866 failed:
867         if (bo_data)
868                 free(bo_data);
869
870         return NULL;
871 /* LCOV_EXCL_STOP */
872 }
873
874 tbm_bo_data *
875 tbm_module_import_bo_data_with_fd(tbm_module *module, tbm_bo bo, tbm_fd fd, tbm_error_e *error)
876 {
877         tbm_bo_data *bo_data = NULL;
878         tbm_backend_bufmgr_func *bufmgr_func = NULL;
879         tbm_bufmgr_backend backend = NULL;
880
881         TBM_RETURN_VAL_SET_ERR_IF_FAIL(module, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
882
883         bo_data = calloc(1, sizeof(struct _tbm_bo_data));
884         TBM_GOTO_VAL_SET_ERR_IF_FAIL(bo_data, failed, *error, TBM_ERROR_OUT_OF_MEMORY);
885
886         switch (module->type) {
887         case TBM_MODULE_TYPE_HAL_TBM:
888                 bo_data->hal_bo = hal_tbm_bufmgr_import_fd(module->hal_bufmgr, (hal_tbm_fd)fd, (hal_tbm_error *)error);
889                 TBM_GOTO_VAL_IF_FAIL(bo_data->hal_bo, failed);
890                 break;
891 /* LCOV_EXCL_START */
892         case TBM_MODULE_TYPE_TBM_BACKEND:
893                 bufmgr_func = module->bufmgr_func;
894                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bufmgr_func, failed, *error, TBM_ERROR_INVALID_OPERATION);
895                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bufmgr_func->bufmgr_import_fd, failed, *error, TBM_ERROR_NOT_SUPPORTED);
896
897                 bo_data->backend_bo_data = bufmgr_func->bufmgr_import_fd(module->bufmgr_data, fd, error);
898                 TBM_GOTO_VAL_IF_FAIL(bo_data->backend_bo_data, failed);
899                 break;
900         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
901                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
902                 backend = module->backend;
903                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(backend, failed, *error, TBM_ERROR_INVALID_OPERATION);
904                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(backend->bo_import_fd, failed, *error, TBM_ERROR_NOT_SUPPORTED);
905
906                 bo_data->priv = (void *)backend->bo_import_fd(bo, fd);
907                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bo_data->priv, failed, *error, TBM_ERROR_INVALID_OPERATION);
908
909                 *error = TBM_ERROR_NONE;
910                 break;
911         default:
912                 TBM_ERR("Wrong module type:%d", module->type);
913                 *error = TBM_ERROR_INVALID_OPERATION;
914                 goto failed;
915                 break;
916 /* LCOV_EXCL_STOP */
917         }
918
919         bo_data->module = module;
920
921         return bo_data;
922
923 /* LCOV_EXCL_START */
924 failed:
925         if (bo_data)
926                 free(bo_data);
927
928         return NULL;
929 /* LCOV_EXCL_STOP */
930 }
931
932 tbm_bo_data *
933 tbm_module_import_bo_data_with_key(tbm_module *module, tbm_bo bo, tbm_key key, tbm_error_e *error)
934 {
935         tbm_bo_data *bo_data = NULL;
936         tbm_backend_bufmgr_func *bufmgr_func = NULL;
937         tbm_bufmgr_backend backend = NULL;
938
939         TBM_RETURN_VAL_SET_ERR_IF_FAIL(module, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
940
941         bo_data = calloc(1, sizeof(struct _tbm_bo_data));
942         TBM_GOTO_VAL_SET_ERR_IF_FAIL(bo_data, failed, *error, TBM_ERROR_OUT_OF_MEMORY);
943
944         switch (module->type) {
945         case TBM_MODULE_TYPE_HAL_TBM:
946                 bo_data->hal_bo = hal_tbm_bufmgr_import_key(module->hal_bufmgr, key, (hal_tbm_error *)error);
947                 TBM_GOTO_VAL_IF_FAIL(bo_data->hal_bo, failed);
948                 break;
949 /* LCOV_EXCL_START */
950         case TBM_MODULE_TYPE_TBM_BACKEND:
951                 bufmgr_func = module->bufmgr_func;
952                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bufmgr_func, failed, *error, TBM_ERROR_INVALID_OPERATION);
953                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bufmgr_func->bufmgr_import_key, failed, *error, TBM_ERROR_NOT_SUPPORTED);
954
955                 bo_data->backend_bo_data = bufmgr_func->bufmgr_import_key(module->bufmgr_data, key, error);
956                 TBM_GOTO_VAL_IF_FAIL(bo_data->backend_bo_data, failed);
957                 break;
958         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
959                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
960                 backend = module->backend;
961                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(backend, failed, *error, TBM_ERROR_INVALID_OPERATION);
962                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(backend->bo_import, failed, *error, TBM_ERROR_NOT_SUPPORTED);
963
964                 bo_data->priv = (void *)backend->bo_import(bo, key);
965                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bo_data->priv, failed, *error, TBM_ERROR_INVALID_OPERATION);
966
967                 *error = TBM_ERROR_NONE;
968                 break;
969         default:
970                 TBM_ERR("Wrong module type:%d", module->type);
971                 *error = TBM_ERROR_INVALID_OPERATION;
972                 goto failed;
973                 break;
974 /* LCOV_EXCL_STOP */
975         }
976
977         bo_data->module = module;
978
979         return bo_data;
980
981 /* LCOV_EXCL_START */
982 failed:
983         if (bo_data)
984                 free(bo_data);
985
986         return NULL;
987 /* LCOV_EXCL_STOP */
988 }
989
990 int
991 tbm_module_compare_bo_data(tbm_module *module, tbm_bo_data *bo_data1, tbm_bo_data *bo_data2)
992 {
993         TBM_RETURN_VAL_IF_FAIL(module, 0);
994
995         switch (module->type) {
996         case TBM_MODULE_TYPE_HAL_TBM:
997                 return (bo_data1->hal_bo == bo_data2->hal_bo);
998                 break;
999 /* LCOV_EXCL_START */
1000         case TBM_MODULE_TYPE_TBM_BACKEND:
1001                 return (bo_data1->backend_bo_data == bo_data2->backend_bo_data);
1002                 break;
1003         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1004                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1005                 return (bo_data1->priv == bo_data2->priv);
1006                 break;
1007         default:
1008                 TBM_ERR("Wrong module type:%d", module->type);
1009                 break;
1010 /* LCOV_EXCL_STOP */
1011         }
1012
1013         return 0;
1014 }
1015
1016 void
1017 tbm_surface_data_free(tbm_surface_data *surface_data)
1018 {
1019         TBM_RETURN_IF_FAIL(surface_data);
1020         TBM_RETURN_IF_FAIL(surface_data->module);
1021         TBM_RETURN_IF_FAIL(surface_data->module->type == TBM_MODULE_TYPE_HAL_TBM);
1022
1023         surface_data->module = NULL;
1024
1025         hal_tbm_surface_free(surface_data->hal_surface);
1026         surface_data->hal_surface = NULL;
1027
1028         free(surface_data);
1029 }
1030
1031 tbm_error_e
1032 tbm_surface_data_get_plane_data(tbm_surface_data *surface_data, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
1033 {
1034         tbm_error_e error;
1035
1036         TBM_RETURN_VAL_IF_FAIL(surface_data, TBM_ERROR_INVALID_PARAMETER);
1037         TBM_RETURN_VAL_IF_FAIL(surface_data->hal_surface, TBM_ERROR_NOT_SUPPORTED);
1038
1039         error = (tbm_error_e)hal_tbm_surface_get_plane_data(surface_data->hal_surface, plane_idx, size, offset, pitch, bo_idx);
1040         TBM_RETURN_VAL_IF_FAIL(error == TBM_ERROR_NONE, error);
1041
1042         return TBM_ERROR_NONE;
1043 }
1044
1045 tbm_bo_data **
1046 tbm_surface_data_get_bo_data_array(tbm_surface_data *surface_data, int *num_bos, int *memory_types, tbm_error_e *error)
1047 {
1048         tbm_bo_data **bo_data_array = NULL;
1049         hal_tbm_bo **hal_bos = NULL;
1050         int i;
1051
1052         TBM_RETURN_VAL_SET_ERR_IF_FAIL(surface_data, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
1053         TBM_RETURN_VAL_SET_ERR_IF_FAIL(surface_data->hal_surface, NULL, *error, TBM_ERROR_NOT_SUPPORTED);
1054
1055         hal_bos = hal_tbm_surface_get_bos(surface_data->hal_surface, num_bos, (hal_tbm_error *)error);
1056         TBM_RETURN_VAL_IF_FAIL(hal_bos, NULL);
1057
1058         bo_data_array = calloc(*num_bos, sizeof(tbm_bo_data *));
1059         TBM_RETURN_VAL_IF_FAIL(bo_data_array, NULL);
1060
1061         for (i = 0; i < *num_bos; i++) {
1062                 bo_data_array[i] = calloc(*num_bos, sizeof(struct _tbm_bo_data));
1063                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bo_data_array[i], failed, *error, TBM_ERROR_OUT_OF_MEMORY);
1064         }
1065
1066         for (i = 0; i < *num_bos; i++) {
1067                 bo_data_array[i]->hal_bo = hal_bos[i];
1068                 bo_data_array[i]->module = surface_data->module;
1069         }
1070
1071         // get memory_types(bo flags)
1072         *memory_types = tbm_bo_data_get_memory_types(bo_data_array[0], error);
1073         TBM_GOTO_VAL_IF_FAIL(*error == TBM_ERROR_NONE, failed);
1074
1075         return bo_data_array;
1076
1077 /* LCOV_EXCL_START */
1078 failed:
1079         for (i = 0; i < *num_bos; i++) {
1080                 if (bo_data_array[i])
1081                         free(bo_data_array[i]);
1082         }
1083         free(bo_data_array);
1084
1085         return NULL;
1086 /* LCOV_EXCL_STOP */
1087 }
1088
1089 tbm_surface_buffer_data *
1090 tbm_surface_data_export(tbm_surface_data *surface_data, tbm_error_e *error)
1091 {
1092         tbm_surface_buffer_data *buffer_data;
1093
1094         TBM_RETURN_VAL_SET_ERR_IF_FAIL(surface_data, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
1095         TBM_RETURN_VAL_SET_ERR_IF_FAIL(surface_data->hal_surface, NULL, *error, TBM_ERROR_NOT_SUPPORTED);
1096
1097         buffer_data = (tbm_surface_buffer_data *)hal_tbm_surface_export((hal_tbm_surface *)surface_data->hal_surface,
1098                                                                                                                                         (hal_tbm_error *)error);
1099         TBM_RETURN_VAL_IF_FAIL(buffer_data, NULL);
1100
1101         return buffer_data;
1102 }
1103
1104 void
1105 tbm_bo_data_free(tbm_bo_data *bo_data, int get_from_surface_data)
1106 {
1107         tbm_module *module = NULL;
1108         tbm_backend_bo_func *bo_func = NULL;
1109         tbm_bufmgr_backend backend = NULL;
1110
1111         TBM_RETURN_IF_FAIL(bo_data);
1112         TBM_RETURN_IF_FAIL(bo_data->module);
1113
1114         module = bo_data->module;
1115
1116         switch (module->type) {
1117         case TBM_MODULE_TYPE_HAL_TBM:
1118                 // call hal_tbm_bo_free when bo is created by tbm_bo_alloc api.
1119                 if (!get_from_surface_data) {
1120                         hal_tbm_bo_free(bo_data->hal_bo);
1121                         bo_data->hal_bo = NULL;
1122                 }
1123                 break;
1124 /* LCOV_EXCL_START */
1125         case TBM_MODULE_TYPE_TBM_BACKEND:
1126                 bo_func = module->bo_func;
1127                 TBM_RETURN_IF_FAIL(bo_func);
1128                 TBM_RETURN_IF_FAIL(bo_func->bo_free);
1129
1130                 bo_func->bo_free(bo_data->backend_bo_data);
1131                 bo_data->backend_bo_data = NULL;
1132                 break;
1133         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1134                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1135                 backend = module->backend;
1136                 TBM_RETURN_IF_FAIL(backend);
1137                 TBM_RETURN_IF_FAIL(backend->bo_free);
1138
1139                 backend->bo_free(bo_data->priv);
1140                 bo_data->priv = NULL;
1141                 break;
1142         default:
1143                 TBM_ERR("Wrong module type:%d", module->type);
1144                 break;
1145 /* LCOV_EXCL_STOP */
1146         }
1147
1148         bo_data->module = NULL;
1149         free(bo_data);
1150 }
1151
1152 int
1153 tbm_bo_data_get_size(tbm_bo_data *bo_data, tbm_error_e *error)
1154 {
1155         tbm_module *module = NULL;
1156         tbm_backend_bo_func *bo_func = NULL;
1157         tbm_bufmgr_backend backend = NULL;
1158         int size = 0;
1159
1160         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data, 0, *error, TBM_ERROR_INVALID_PARAMETER);
1161         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data->module, 0, *error, TBM_ERROR_INVALID_PARAMETER);
1162
1163         module = bo_data->module;
1164
1165         switch (module->type) {
1166         case TBM_MODULE_TYPE_HAL_TBM:
1167                 size = hal_tbm_bo_get_size(bo_data->hal_bo, (hal_tbm_error *)error);
1168                 break;
1169 /* LCOV_EXCL_START */
1170         case TBM_MODULE_TYPE_TBM_BACKEND:
1171                 bo_func = module->bo_func;
1172                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func, 0, *error, TBM_ERROR_INVALID_OPERATION);
1173                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func->bo_get_size, 0, *error, TBM_ERROR_NOT_SUPPORTED);
1174
1175                 size = bo_func->bo_get_size(bo_data->backend_bo_data, error);
1176                 break;
1177         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1178                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1179                 backend = module->backend;
1180                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend, 0, *error, TBM_ERROR_INVALID_OPERATION);
1181                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend->bo_size, 0, *error, TBM_ERROR_NOT_SUPPORTED);
1182
1183                 size = backend->bo_size(bo_data->priv);
1184                 if (size == 0)
1185                         *error = TBM_ERROR_INVALID_OPERATION;
1186                 else
1187                         *error = TBM_ERROR_NONE;
1188                 break;
1189         default:
1190                 TBM_ERR("Wrong module type:%d", module->type);
1191                 *error = TBM_ERROR_INVALID_OPERATION;
1192                 break;
1193 /* LCOV_EXCL_STOP */
1194         }
1195
1196         return size;
1197 }
1198
1199 int
1200 tbm_bo_data_get_memory_types(tbm_bo_data *bo_data, tbm_error_e *error)
1201 {
1202         tbm_module *module = NULL;
1203         tbm_backend_bo_func *bo_func = NULL;
1204         tbm_bufmgr_backend backend = NULL;
1205         int memory_types = TBM_BO_DEFAULT;
1206
1207         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data, 0, *error, TBM_ERROR_INVALID_PARAMETER);
1208         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data->module, 0, *error, TBM_ERROR_INVALID_PARAMETER);
1209
1210         module = bo_data->module;
1211
1212         switch (module->type) {
1213         case TBM_MODULE_TYPE_HAL_TBM:
1214                 memory_types = (tbm_bo_memory_type)hal_tbm_bo_get_memory_types(bo_data->hal_bo, (hal_tbm_error *)error);
1215                 break;
1216 /* LCOV_EXCL_START */
1217         case TBM_MODULE_TYPE_TBM_BACKEND:
1218                 bo_func = module->bo_func;
1219                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func, 0, *error, TBM_ERROR_INVALID_OPERATION);
1220                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func->bo_get_memory_types, 0, *error, TBM_ERROR_NOT_SUPPORTED);
1221
1222                 memory_types = bo_func->bo_get_memory_types(bo_data->backend_bo_data, error);
1223                 break;
1224         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1225                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1226                 backend = module->backend;
1227                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend, 0, *error, TBM_ERROR_INVALID_OPERATION);
1228                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend->bo_get_flags, 0, *error, TBM_ERROR_NOT_SUPPORTED);
1229
1230                 memory_types = backend->bo_get_flags(bo_data->priv);
1231                 *error = TBM_ERROR_NONE;
1232                 break;
1233         default:
1234                 TBM_ERR("Wrong module type:%d", module->type);
1235                 *error = TBM_ERROR_INVALID_OPERATION;
1236                 break;
1237 /* LCOV_EXCL_STOP */
1238         }
1239
1240         return memory_types;
1241 }
1242
1243 tbm_bo_handle
1244 tbm_bo_data_get_handle(tbm_bo_data *bo_data, int device, tbm_error_e *error)
1245 {
1246         tbm_module *module = NULL;
1247         tbm_backend_bo_func *bo_func = NULL;
1248         tbm_bufmgr_backend backend = NULL;
1249         tbm_bo_handle bo_handle = (tbm_bo_handle)NULL;
1250         hal_tbm_bo_handle hbo_handle;
1251
1252         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data, (tbm_bo_handle)NULL, *error, TBM_ERROR_INVALID_PARAMETER);
1253         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data->module, (tbm_bo_handle)NULL, *error, TBM_ERROR_INVALID_PARAMETER);
1254
1255         module = bo_data->module;
1256
1257         switch (module->type) {
1258         case TBM_MODULE_TYPE_HAL_TBM:
1259                 hbo_handle = hal_tbm_bo_get_handle(bo_data->hal_bo, device, (hal_tbm_error *)error);
1260                 if (hbo_handle.ptr != NULL)
1261                         memcpy(&bo_handle.ptr, &hbo_handle.ptr, sizeof(tbm_bo_handle));
1262                 break;
1263 /* LCOV_EXCL_START */
1264         case TBM_MODULE_TYPE_TBM_BACKEND:
1265                 bo_func = module->bo_func;
1266                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func, (tbm_bo_handle)NULL, *error, TBM_ERROR_INVALID_OPERATION);
1267                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func->bo_get_handle, (tbm_bo_handle)NULL, *error, TBM_ERROR_NOT_SUPPORTED);
1268
1269                 bo_handle = bo_func->bo_get_handle(bo_data->backend_bo_data, device, error);
1270                 break;
1271         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1272                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1273                 backend = module->backend;
1274                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend, (tbm_bo_handle)NULL, *error, TBM_ERROR_INVALID_OPERATION);
1275                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend->bo_get_handle, (tbm_bo_handle)NULL, *error, TBM_ERROR_NOT_SUPPORTED);
1276
1277                 bo_handle = backend->bo_get_handle(bo_data->priv, device);
1278                 if (!bo_handle.ptr)
1279                         *error = TBM_ERROR_INVALID_OPERATION;
1280                 else
1281                         *error = TBM_ERROR_NONE;
1282                 break;
1283         default:
1284                 TBM_ERR("Wrong module type:%d", module->type);
1285                 bo_handle.ptr = NULL;
1286                 *error = TBM_ERROR_INVALID_OPERATION;
1287                 break;
1288 /* LCOV_EXCL_STOP */
1289         }
1290
1291         return bo_handle;
1292 }
1293
1294 tbm_bo_handle
1295 tbm_bo_data_map(tbm_bo_data *bo_data, int device, int opt, tbm_error_e *error)
1296 {
1297         tbm_module *module = NULL;
1298         tbm_backend_bo_func *bo_func = NULL;
1299         tbm_bufmgr_backend backend = NULL;
1300         tbm_bo_handle bo_handle = (tbm_bo_handle)NULL;
1301         hal_tbm_bo_handle hbo_handle = (hal_tbm_bo_handle)NULL;
1302
1303         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data, (tbm_bo_handle)NULL, *error, TBM_ERROR_INVALID_PARAMETER);
1304         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data->module, (tbm_bo_handle)NULL, *error, TBM_ERROR_INVALID_PARAMETER);
1305
1306         module = bo_data->module;
1307
1308         switch (module->type) {
1309         case TBM_MODULE_TYPE_HAL_TBM:
1310                 hbo_handle = hal_tbm_bo_map(bo_data->hal_bo, device, opt, (hal_tbm_error *)error);
1311                 if (hbo_handle.ptr != NULL)
1312                         memcpy(&bo_handle.ptr, &hbo_handle.ptr, sizeof(tbm_bo_handle));
1313                 break;
1314 /* LCOV_EXCL_START */
1315         case TBM_MODULE_TYPE_TBM_BACKEND:
1316                 bo_func = module->bo_func;
1317                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func, (tbm_bo_handle)NULL, *error, TBM_ERROR_INVALID_OPERATION);
1318                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func->bo_map, (tbm_bo_handle)NULL, *error, TBM_ERROR_NOT_SUPPORTED);
1319
1320                 bo_handle = bo_func->bo_map(bo_data->backend_bo_data, device, opt, error);
1321                 break;
1322         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1323                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1324                 backend = module->backend;
1325                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend, (tbm_bo_handle)NULL, *error, TBM_ERROR_INVALID_OPERATION);
1326                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend->bo_map, (tbm_bo_handle)NULL, *error, TBM_ERROR_NOT_SUPPORTED);
1327
1328                 bo_handle = backend->bo_map(bo_data->priv, device, opt);
1329                 if (!bo_handle.ptr)
1330                         *error = TBM_ERROR_INVALID_OPERATION;
1331                 else
1332                         *error = TBM_ERROR_NONE;
1333                 break;
1334         default:
1335                 TBM_ERR("Wrong module type:%d", module->type);
1336                 bo_handle.ptr = NULL;
1337                 *error = TBM_ERROR_INVALID_OPERATION;
1338                 break;
1339 /* LCOV_EXCL_STOP */
1340         }
1341
1342         return bo_handle;
1343 }
1344
1345 tbm_error_e
1346 tbm_bo_data_unmap(tbm_bo_data *bo_data)
1347 {
1348         tbm_module *module = NULL;
1349         tbm_backend_bo_func *bo_func = NULL;
1350         tbm_bufmgr_backend backend = NULL;
1351         tbm_error_e error;
1352         int ret = 0;
1353
1354         TBM_RETURN_VAL_IF_FAIL(bo_data, TBM_ERROR_INVALID_PARAMETER);
1355         TBM_RETURN_VAL_IF_FAIL(bo_data->module, TBM_ERROR_INVALID_PARAMETER);
1356
1357         module = bo_data->module;
1358
1359         switch (module->type) {
1360         case TBM_MODULE_TYPE_HAL_TBM:
1361                 error = (hal_tbm_error)hal_tbm_bo_unmap(bo_data->hal_bo);
1362                 break;
1363 /* LCOV_EXCL_START */
1364         case TBM_MODULE_TYPE_TBM_BACKEND:
1365                 bo_func = module->bo_func;
1366                 TBM_RETURN_VAL_IF_FAIL(bo_func, TBM_ERROR_INVALID_OPERATION);
1367                 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_unmap, TBM_ERROR_NOT_SUPPORTED);
1368
1369                 error = bo_func->bo_unmap(bo_data->backend_bo_data);
1370                 break;
1371         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1372                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1373                 backend = module->backend;
1374                 TBM_RETURN_VAL_IF_FAIL(backend, TBM_ERROR_INVALID_OPERATION);
1375                 TBM_RETURN_VAL_IF_FAIL(backend->bo_unmap, TBM_ERROR_NOT_SUPPORTED);
1376
1377                 ret = backend->bo_unmap(bo_data->priv);
1378                 if (!ret)
1379                         error = TBM_ERROR_INVALID_OPERATION;
1380                 else
1381                         error = TBM_ERROR_NONE;
1382                 break;
1383         default:
1384                 TBM_ERR("Wrong module type:%d", module->type);
1385                 error = TBM_ERROR_INVALID_OPERATION;
1386                 break;
1387 /* LCOV_EXCL_STOP */
1388         }
1389
1390         return error;
1391 }
1392
1393 tbm_error_e
1394 tbm_bo_data_lock(tbm_bo_data *bo_data, int device, int opt)
1395 {
1396         tbm_module *module = NULL;
1397         tbm_backend_bo_func *bo_func = NULL;
1398         tbm_bufmgr_backend backend = NULL;
1399         tbm_error_e error;
1400         int ret = 0;
1401
1402         TBM_RETURN_VAL_IF_FAIL(bo_data, TBM_ERROR_INVALID_PARAMETER);
1403         TBM_RETURN_VAL_IF_FAIL(bo_data->module, TBM_ERROR_INVALID_PARAMETER);
1404
1405         module = bo_data->module;
1406
1407         switch (module->type) {
1408         case TBM_MODULE_TYPE_HAL_TBM:
1409                 error = (tbm_error_e)hal_tbm_bo_lock(bo_data->hal_bo, device, opt);
1410                 break;
1411 /* LCOV_EXCL_START */
1412         case TBM_MODULE_TYPE_TBM_BACKEND:
1413                 bo_func = module->bo_func;
1414                 TBM_RETURN_VAL_IF_FAIL(bo_func, TBM_ERROR_INVALID_OPERATION);
1415                 if (!bo_func->bo_lock)
1416                         return TBM_ERROR_NOT_SUPPORTED;
1417
1418                 error = bo_func->bo_lock(bo_data->backend_bo_data, device, opt);
1419                 break;
1420         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1421                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1422                 backend = module->backend;
1423                 TBM_RETURN_VAL_IF_FAIL(backend, TBM_ERROR_INVALID_OPERATION);
1424                 if (!backend->bo_unmap)
1425                         return TBM_ERROR_NOT_SUPPORTED;
1426
1427                 ret = backend->bo_lock(bo_data->priv, device, opt);
1428                 if (!ret)
1429                         error = TBM_ERROR_INVALID_OPERATION;
1430                 else
1431                         error = TBM_ERROR_NONE;
1432                 break;
1433         default:
1434                 TBM_ERR("Wrong module type:%d", module->type);
1435                 error = TBM_ERROR_INVALID_OPERATION;
1436                 break;
1437 /* LCOV_EXCL_STOP */
1438         }
1439
1440         return error;
1441 }
1442
1443 tbm_error_e
1444 tbm_bo_data_unlock(tbm_bo_data *bo_data)
1445 {
1446         tbm_module *module = NULL;
1447         tbm_backend_bo_func *bo_func = NULL;
1448         tbm_bufmgr_backend backend = NULL;
1449         tbm_error_e error;
1450
1451         TBM_RETURN_VAL_IF_FAIL(bo_data, TBM_ERROR_INVALID_PARAMETER);
1452         TBM_RETURN_VAL_IF_FAIL(bo_data->module, TBM_ERROR_INVALID_PARAMETER);
1453
1454         module = bo_data->module;
1455
1456         switch (module->type) {
1457         case TBM_MODULE_TYPE_HAL_TBM:
1458                 error = (tbm_error_e)hal_tbm_bo_unlock(bo_data->hal_bo);
1459                 break;
1460 /* LCOV_EXCL_START */
1461         case TBM_MODULE_TYPE_TBM_BACKEND:
1462                 bo_func = module->bo_func;
1463                 TBM_RETURN_VAL_IF_FAIL(bo_func, TBM_ERROR_INVALID_OPERATION);
1464                 if (!bo_func->bo_unlock)
1465                         return TBM_ERROR_NOT_SUPPORTED;
1466
1467                 error = bo_func->bo_unlock(bo_data->backend_bo_data);
1468                 break;
1469         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1470                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1471                 backend = module->backend;
1472                 TBM_RETURN_VAL_IF_FAIL(backend, TBM_ERROR_INVALID_OPERATION);
1473                 if (!backend->bo_unlock)
1474                         return TBM_ERROR_NOT_SUPPORTED;
1475
1476                 backend->bo_unlock(bo_data->priv);
1477                 error = TBM_ERROR_NONE;
1478                 break;
1479         default:
1480                 TBM_ERR("Wrong module type:%d", module->type);
1481                 error = TBM_ERROR_INVALID_OPERATION;
1482                 break;
1483 /* LCOV_EXCL_STOP */
1484         }
1485
1486         return error;
1487 }
1488
1489 tbm_fd
1490 tbm_bo_data_export_fd(tbm_bo_data *bo_data, tbm_error_e *error)
1491 {
1492         tbm_module *module = NULL;
1493         tbm_backend_bo_func *bo_func = NULL;
1494         tbm_bufmgr_backend backend = NULL;
1495         tbm_fd fd;
1496
1497         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data, -1, *error, TBM_ERROR_INVALID_PARAMETER);
1498         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data->module, -1, *error, TBM_ERROR_INVALID_PARAMETER);
1499
1500         module = bo_data->module;
1501
1502         switch (module->type) {
1503         case TBM_MODULE_TYPE_HAL_TBM:
1504                 fd = (hal_tbm_fd)hal_tbm_bo_export_fd(bo_data->hal_bo, (hal_tbm_error *)error);
1505                 break;
1506 /* LCOV_EXCL_START */
1507         case TBM_MODULE_TYPE_TBM_BACKEND:
1508                 bo_func = module->bo_func;
1509                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func, -1, *error, TBM_ERROR_INVALID_OPERATION);
1510                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func->bo_export_fd, -1, *error, TBM_ERROR_NOT_SUPPORTED);
1511
1512                 fd = bo_func->bo_export_fd(bo_data->backend_bo_data, error);
1513                 break;
1514         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1515                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1516                 backend = module->backend;
1517                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend, -1, *error, TBM_ERROR_INVALID_OPERATION);
1518                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend->bo_export_fd, -1, *error, TBM_ERROR_NOT_SUPPORTED);
1519
1520                 fd = backend->bo_export_fd(bo_data->priv);
1521                 if (fd < 0)
1522                         *error = TBM_ERROR_INVALID_OPERATION;
1523                 else
1524                         *error = TBM_ERROR_NONE;
1525                 break;
1526         default:
1527                 TBM_ERR("Wrong module type:%d", module->type);
1528                 fd = -1;
1529                 *error = TBM_ERROR_INVALID_OPERATION;
1530                 break;
1531 /* LCOV_EXCL_STOP */
1532         }
1533
1534         return fd;
1535 }
1536
1537 tbm_key
1538 tbm_bo_data_export_key(tbm_bo_data *bo_data, tbm_error_e *error)
1539 {
1540         tbm_module *module = NULL;
1541         tbm_backend_bo_func *bo_func = NULL;
1542         tbm_bufmgr_backend backend = NULL;
1543         tbm_key ret;
1544
1545         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data, 0, *error, TBM_ERROR_INVALID_PARAMETER);
1546         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data->module, 0, *error, TBM_ERROR_INVALID_PARAMETER);
1547
1548         module = bo_data->module;
1549
1550         switch (module->type) {
1551         case TBM_MODULE_TYPE_HAL_TBM:
1552                 ret = (hal_tbm_fd)hal_tbm_bo_export_key(bo_data->hal_bo, (hal_tbm_error *)error);
1553                 break;
1554 /* LCOV_EXCL_START */
1555         case TBM_MODULE_TYPE_TBM_BACKEND:
1556                 bo_func = module->bo_func;
1557                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func, 0, *error, TBM_ERROR_INVALID_OPERATION);
1558                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func->bo_export_key, 0, *error, TBM_ERROR_NOT_SUPPORTED);
1559
1560                 ret = bo_func->bo_export_key(bo_data->backend_bo_data, error);
1561                 break;
1562         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1563                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1564                 backend = module->backend;
1565                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend, 0, *error, TBM_ERROR_INVALID_OPERATION);
1566                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend->bo_export, 0, *error, TBM_ERROR_NOT_SUPPORTED);
1567
1568                 ret = backend->bo_export(bo_data->priv);
1569                 if (!ret)
1570                         *error = TBM_ERROR_INVALID_OPERATION;
1571                 else
1572                         *error = TBM_ERROR_NONE;
1573                 break;
1574         default:
1575                 TBM_ERR("Wrong module type:%d", module->type);
1576                 ret = -1;
1577                 *error = TBM_ERROR_INVALID_OPERATION;
1578                 break;
1579 /* LCOV_EXCL_STOP */
1580         }
1581
1582         return ret;
1583 }