tbm_module: handle the memory leak of the bo_data_array
[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                         // make the wayland server socket for sending the authenticated drm_fd to wayland clients.
518                         if (!tbm_drm_helper_wl_auth_server_init(native_display, fd, NULL, 0)) {
519                                 TBM_ERR("error: tbm_drm_helper_wl_auth_server_init failed\n", module, native_display);
520                                 close(fd);
521                                 return TBM_ERROR_INVALID_OPERATION;
522                         }
523                         TBM_INFO("tbm creates a wayland socket for authentication of drm_fd.");
524
525                         module->auth_wl_socket_created = 1;
526                         module->auth_fd = fd;
527                 } else {
528                         TBM_INFO("tbm_module has no drm device.");
529                         error = TBM_ERROR_NONE;
530                 }
531                 break;
532 /* LCOV_EXCL_START */
533         case TBM_MODULE_TYPE_TBM_BACKEND:
534                 bufmgr_func = module->bufmgr_func;
535                 TBM_RETURN_VAL_IF_FAIL(bufmgr_func, TBM_ERROR_INVALID_OPERATION);
536                 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_bind_native_display, TBM_ERROR_NOT_SUPPORTED);
537
538                 error = bufmgr_func->bufmgr_bind_native_display(module->bufmgr_data, (tbm_native_display *)native_display);
539                 break;
540         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
541                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
542                 backend = module->backend;
543                 TBM_RETURN_VAL_IF_FAIL(backend, TBM_ERROR_INVALID_OPERATION);
544                 TBM_RETURN_VAL_IF_FAIL(backend->bufmgr_bind_native_display, TBM_ERROR_NOT_SUPPORTED);
545
546                 ret = backend->bufmgr_bind_native_display((tbm_bufmgr)module, native_display);
547                 if (!ret)
548                         error = TBM_ERROR_INVALID_OPERATION;
549
550                 break;
551         default:
552                 TBM_ERR("Wrong module type:%d", module->type);
553                 error = TBM_ERROR_INVALID_OPERATION;
554                 break;
555 /* LCOV_EXCL_STOP */
556         }
557
558         return error;
559 }
560
561 tbm_error_e
562 tbm_module_get_supported_formats(tbm_module *module, uint32_t **formats, uint32_t *num)
563 {
564         tbm_error_e error = TBM_ERROR_NONE;
565         tbm_backend_bufmgr_func *bufmgr_func = NULL;
566         tbm_bufmgr_backend backend = NULL;
567         int ret = 0;
568
569         TBM_RETURN_VAL_IF_FAIL(module, TBM_ERROR_INVALID_PARAMETER);
570
571         switch (module->type) {
572         case TBM_MODULE_TYPE_HAL_TBM:
573                 error = (tbm_error_e)hal_tbm_bufmgr_get_supported_formats(module->hal_bufmgr, formats, num);
574                 break;
575 /* LCOV_EXCL_START */
576         case TBM_MODULE_TYPE_TBM_BACKEND:
577                 bufmgr_func = module->bufmgr_func;
578                 TBM_RETURN_VAL_IF_FAIL(bufmgr_func, TBM_ERROR_INVALID_OPERATION);
579                 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_supported_formats, TBM_ERROR_NOT_SUPPORTED);
580
581                 error = bufmgr_func->bufmgr_get_supported_formats(module->bufmgr_data, formats, num);
582                 break;
583         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
584                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
585                 backend = module->backend;
586                 TBM_RETURN_VAL_IF_FAIL(backend, TBM_ERROR_INVALID_OPERATION);
587                 TBM_RETURN_VAL_IF_FAIL(backend->surface_supported_format, TBM_ERROR_NOT_SUPPORTED);
588
589                 ret = backend->surface_supported_format(formats, num);
590                 if (!ret)
591                         error = TBM_ERROR_INVALID_OPERATION;
592
593                 break;
594         default:
595                 TBM_ERR("Wrong module type:%d", module->type);
596                 error = TBM_ERROR_INVALID_OPERATION;
597                 break;
598 /* LCOV_EXCL_STOP */
599         }
600
601         return error;
602 }
603
604 tbm_error_e
605 tbm_module_get_plane_data(tbm_module *module, int format, int plane_idx, uint32_t w, uint32_t h,
606                                         uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
607 {
608         tbm_error_e error = TBM_ERROR_NONE;
609         tbm_backend_bufmgr_func *bufmgr_func = NULL;
610         tbm_bufmgr_backend backend = NULL;
611         int ret = 0;
612
613         TBM_RETURN_VAL_IF_FAIL(module, TBM_ERROR_INVALID_PARAMETER);
614
615         switch (module->type) {
616         case TBM_MODULE_TYPE_HAL_TBM:
617                 error = (tbm_error_e)hal_tbm_bufmgr_get_plane_data(module->hal_bufmgr, format, plane_idx, w, h, size, offset, pitch, bo_idx);
618                 break;
619 /* LCOV_EXCL_START */
620         case TBM_MODULE_TYPE_TBM_BACKEND:
621                 bufmgr_func = module->bufmgr_func;
622                 TBM_RETURN_VAL_IF_FAIL(bufmgr_func, TBM_ERROR_INVALID_OPERATION);
623                 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_plane_data, TBM_ERROR_NOT_SUPPORTED);
624
625                 error = bufmgr_func->bufmgr_get_plane_data(module->bufmgr_data, format, plane_idx, w, h, size, offset, pitch, bo_idx);
626                 break;
627         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
628                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
629                 backend = module->backend;
630                 TBM_RETURN_VAL_IF_FAIL(backend, TBM_ERROR_INVALID_OPERATION);
631                 TBM_RETURN_VAL_IF_FAIL(backend->surface_get_plane_data, TBM_ERROR_NOT_SUPPORTED);
632
633                 ret = backend->surface_get_plane_data(w, h, format, plane_idx, size, offset, pitch, bo_idx);
634                 if (!ret)
635                         error = TBM_ERROR_INVALID_OPERATION;
636                 break;
637         default:
638                 TBM_ERR("Wrong module type:%d", module->type);
639                 error = TBM_ERROR_INVALID_OPERATION;
640                 break;
641 /* LCOV_EXCL_STOP */
642         }
643
644         return error;
645 }
646
647 int
648 tbm_module_support_surface_data(tbm_module *module)
649 {
650         tbm_error_e error = TBM_ERROR_NONE;
651         tbm_surface_data *surface_data = NULL;
652
653         TBM_RETURN_VAL_IF_FAIL(module, 0);
654
655         // check once support_surface_data or not.
656         if (module->check_surface_data) {
657                 // return the value which already set.
658                 return module->support_surface_data;
659         }
660
661         // check this only once
662         module->check_surface_data = 1;
663
664         if (module->type != TBM_MODULE_TYPE_HAL_TBM)
665                 goto done;
666
667         // Assume that the hal-tbm supports the hal surface apis if tbm_module_alloc_surface_data succeed.
668         surface_data = tbm_module_alloc_surface_data(module, 10, 10, TBM_FORMAT_ARGB8888, TBM_BO_DEFAULT, &error);
669         if (!surface_data)
670                 goto done;
671         free(surface_data);
672
673         module->support_surface_data = 1;
674
675 done:
676         return module->support_surface_data;
677 }
678
679
680 tbm_surface_data *
681 tbm_module_alloc_surface_data(tbm_module *module, int width, int height, int format, int flags, tbm_error_e *error)
682 {
683         tbm_surface_data *surface_data = NULL;
684
685         TBM_RETURN_VAL_SET_ERR_IF_FAIL(module, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
686         TBM_RETURN_VAL_SET_ERR_IF_FAIL(module->type == TBM_MODULE_TYPE_HAL_TBM, NULL, *error, TBM_ERROR_INVALID_OPERATION);
687
688         surface_data = calloc(1, sizeof(struct _tbm_surface_data));
689         if (!surface_data) {
690                 TBM_ERR("memory allocation failed.");
691                 *error = TBM_ERROR_OUT_OF_MEMORY;
692                 return NULL;
693         }
694
695         surface_data->hal_surface = hal_tbm_bufmgr_alloc_surface(module->hal_bufmgr,
696                                                                                            (uint32_t)width,
697                                                                                            (uint32_t)height,
698                                                                                            (hal_tbm_format)format,
699                                                                                            (hal_tbm_bo_memory_type)flags,
700                                                                                            NULL,
701                                                                                            0,
702                                                                                            (hal_tbm_error *)error);
703         if (!surface_data->hal_surface) {
704                 TBM_ERR("hal_tbm_bufmgr_alloc_surface failed.");
705                 *error = TBM_ERROR_INVALID_OPERATION;
706                 free(surface_data);
707                 return NULL;
708         }
709
710         surface_data->module = module;
711
712         return surface_data;
713 }
714
715 tbm_surface_data *
716 tbm_module_import_surface_data(tbm_module *module, int width, int height, int format, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
717 {
718         tbm_surface_data *surface_data = NULL;
719
720         TBM_RETURN_VAL_SET_ERR_IF_FAIL(module, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
721         TBM_RETURN_VAL_SET_ERR_IF_FAIL(module->type == TBM_MODULE_TYPE_HAL_TBM, NULL, *error, TBM_ERROR_INVALID_OPERATION);
722
723         surface_data = calloc(1, sizeof(struct _tbm_surface_data));
724         if (!surface_data) {
725                 TBM_ERR("memory allocation failed.");
726                 *error = TBM_ERROR_OUT_OF_MEMORY;
727                 return NULL;
728         }
729
730         surface_data->hal_surface = hal_tbm_bufmgr_import_surface(module->hal_bufmgr,
731                                                                                         (uint32_t)width,
732                                                                                         (uint32_t)height,
733                                                                                         (hal_tbm_format)format,
734                                                                                         (hal_tbm_surface_buffer_data *)buffer_data,
735                                                                                         (hal_tbm_error *)error);
736         if (!surface_data->hal_surface) {
737                 TBM_ERR("hal_tbm_bufmgr_import_surface failed. width:%d height:%d format:%d error:%s",
738                                 width, height, format, tbm_error_str(*error));
739                 free(surface_data);
740                 return NULL;
741         }
742
743         surface_data->module = module;
744
745         return surface_data;
746 }
747
748 tbm_bo_data *
749 tbm_module_alloc_bo_data(tbm_module *module, tbm_bo bo, int size, int flags, tbm_error_e *error)
750 {
751         tbm_bo_data *bo_data = NULL;
752         tbm_backend_bufmgr_func *bufmgr_func = NULL;
753         tbm_bufmgr_backend backend = NULL;
754
755         TBM_RETURN_VAL_SET_ERR_IF_FAIL(module, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
756
757         bo_data = calloc(1, sizeof(struct _tbm_bo_data));
758         TBM_GOTO_VAL_SET_ERR_IF_FAIL(bo_data, failed, *error, TBM_ERROR_OUT_OF_MEMORY);
759
760         switch (module->type) {
761         case TBM_MODULE_TYPE_HAL_TBM:
762                 bo_data->hal_bo = hal_tbm_bufmgr_alloc_bo(module->hal_bufmgr, size, flags, (hal_tbm_error *)error);
763                 TBM_GOTO_VAL_IF_FAIL(bo_data->hal_bo, failed);
764                 break;
765 /* LCOV_EXCL_START */
766         case TBM_MODULE_TYPE_TBM_BACKEND:
767                 bufmgr_func = module->bufmgr_func;
768                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bufmgr_func, failed, *error, TBM_ERROR_INVALID_OPERATION);
769                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bufmgr_func->bufmgr_alloc_bo, failed, *error, TBM_ERROR_NOT_SUPPORTED);
770
771                 bo_data->backend_bo_data = bufmgr_func->bufmgr_alloc_bo(module->bufmgr_data, (unsigned int)size, flags, error);
772                 TBM_GOTO_VAL_IF_FAIL(bo_data->backend_bo_data, failed);
773                 break;
774         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
775                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
776
777                 backend = module->backend;
778                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(backend, failed, *error, TBM_ERROR_INVALID_OPERATION);
779                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(backend->bo_alloc, failed, *error, TBM_ERROR_NOT_SUPPORTED);
780
781                 bo_data->priv = (void *)backend->bo_alloc(bo, size, flags);
782                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bo_data->priv, failed, *error, TBM_ERROR_INVALID_OPERATION);
783
784                 *error = TBM_ERROR_NONE;
785                 break;
786         default:
787                 TBM_ERR("Wrong module type:%d", module->type);
788                 *error = TBM_ERROR_INVALID_OPERATION;
789                 goto failed;
790                 break;
791 /* LCOV_EXCL_STOP */
792         }
793
794         bo_data->module = module;
795
796         return bo_data;
797
798 /* LCOV_EXCL_START */
799 failed:
800         if (bo_data)
801                 free(bo_data);
802
803         return NULL;
804 /* LCOV_EXCL_STOP */
805 }
806
807 tbm_bo_data *
808 tbm_module_alloc_bo_data_with_format(tbm_module *module, int format, int bo_idx, int width,
809                                                 int height, int bpp, tbm_bo_memory_type flags, tbm_error_e *error)
810 {
811         tbm_bo_data *bo_data = NULL;
812         tbm_backend_bufmgr_func *bufmgr_func = NULL;
813
814         TBM_RETURN_VAL_SET_ERR_IF_FAIL(module, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
815
816         bo_data = calloc(1, sizeof(struct _tbm_bo_data));
817         TBM_GOTO_VAL_SET_ERR_IF_FAIL(bo_data, failed, *error, TBM_ERROR_OUT_OF_MEMORY);
818
819         switch (module->type) {
820         case TBM_MODULE_TYPE_HAL_TBM:
821                 bo_data->hal_bo = hal_tbm_bufmgr_alloc_bo_with_format(module->hal_bufmgr,
822                                                                                         format, bo_idx, width, height, bpp,
823                                                                                         (hal_tbm_bo_memory_type)flags, (hal_tbm_error *)error);
824                 TBM_GOTO_VAL_IF_FAIL(bo_data->hal_bo, failed);
825                 break;
826 /* LCOV_EXCL_START */
827         case TBM_MODULE_TYPE_TBM_BACKEND:
828                 bufmgr_func = module->bufmgr_func;
829                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bufmgr_func, failed, *error, TBM_ERROR_INVALID_OPERATION);
830                 if (!bufmgr_func->bufmgr_alloc_bo_with_format) {
831                         *error = TBM_ERROR_NOT_SUPPORTED;
832                         goto failed;
833                 }
834
835                 bo_data->backend_bo_data = bufmgr_func->bufmgr_alloc_bo_with_format(module->bufmgr_data, format, bo_idx, width, height, flags, error);
836                 TBM_GOTO_VAL_IF_FAIL(bo_data->backend_bo_data, failed);
837                 break;
838         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
839                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
840                 TBM_ERR("error: not supported tbm_module_alloc_bo_data_with_format.");
841
842                 *error = TBM_ERROR_NOT_SUPPORTED;
843                 goto failed;
844                 break;
845         default:
846                 TBM_ERR("Wrong module type:%d", module->type);
847                 *error = TBM_ERROR_INVALID_OPERATION;
848                 goto failed;
849                 break;
850 /* LCOV_EXCL_STOP */
851         }
852
853         bo_data->module = module;
854
855         return bo_data;
856
857 /* LCOV_EXCL_START */
858 failed:
859         if (bo_data)
860                 free(bo_data);
861
862         return NULL;
863 /* LCOV_EXCL_STOP */
864 }
865
866 tbm_bo_data *
867 tbm_module_import_bo_data_with_fd(tbm_module *module, tbm_bo bo, tbm_fd fd, tbm_error_e *error)
868 {
869         tbm_bo_data *bo_data = NULL;
870         tbm_backend_bufmgr_func *bufmgr_func = NULL;
871         tbm_bufmgr_backend backend = NULL;
872
873         TBM_RETURN_VAL_SET_ERR_IF_FAIL(module, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
874
875         bo_data = calloc(1, sizeof(struct _tbm_bo_data));
876         TBM_GOTO_VAL_SET_ERR_IF_FAIL(bo_data, failed, *error, TBM_ERROR_OUT_OF_MEMORY);
877
878         switch (module->type) {
879         case TBM_MODULE_TYPE_HAL_TBM:
880                 bo_data->hal_bo = hal_tbm_bufmgr_import_fd(module->hal_bufmgr, (hal_tbm_fd)fd, (hal_tbm_error *)error);
881                 TBM_GOTO_VAL_IF_FAIL(bo_data->hal_bo, failed);
882                 break;
883 /* LCOV_EXCL_START */
884         case TBM_MODULE_TYPE_TBM_BACKEND:
885                 bufmgr_func = module->bufmgr_func;
886                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bufmgr_func, failed, *error, TBM_ERROR_INVALID_OPERATION);
887                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bufmgr_func->bufmgr_import_fd, failed, *error, TBM_ERROR_NOT_SUPPORTED);
888
889                 bo_data->backend_bo_data = bufmgr_func->bufmgr_import_fd(module->bufmgr_data, fd, error);
890                 TBM_GOTO_VAL_IF_FAIL(bo_data->backend_bo_data, failed);
891                 break;
892         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
893                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
894                 backend = module->backend;
895                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(backend, failed, *error, TBM_ERROR_INVALID_OPERATION);
896                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(backend->bo_import_fd, failed, *error, TBM_ERROR_NOT_SUPPORTED);
897
898                 bo_data->priv = (void *)backend->bo_import_fd(bo, fd);
899                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bo_data->priv, failed, *error, TBM_ERROR_INVALID_OPERATION);
900
901                 *error = TBM_ERROR_NONE;
902                 break;
903         default:
904                 TBM_ERR("Wrong module type:%d", module->type);
905                 *error = TBM_ERROR_INVALID_OPERATION;
906                 goto failed;
907                 break;
908 /* LCOV_EXCL_STOP */
909         }
910
911         bo_data->module = module;
912
913         return bo_data;
914
915 /* LCOV_EXCL_START */
916 failed:
917         if (bo_data)
918                 free(bo_data);
919
920         return NULL;
921 /* LCOV_EXCL_STOP */
922 }
923
924 tbm_bo_data *
925 tbm_module_import_bo_data_with_key(tbm_module *module, tbm_bo bo, tbm_key key, tbm_error_e *error)
926 {
927         tbm_bo_data *bo_data = NULL;
928         tbm_backend_bufmgr_func *bufmgr_func = NULL;
929         tbm_bufmgr_backend backend = NULL;
930
931         TBM_RETURN_VAL_SET_ERR_IF_FAIL(module, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
932
933         bo_data = calloc(1, sizeof(struct _tbm_bo_data));
934         TBM_GOTO_VAL_SET_ERR_IF_FAIL(bo_data, failed, *error, TBM_ERROR_OUT_OF_MEMORY);
935
936         switch (module->type) {
937         case TBM_MODULE_TYPE_HAL_TBM:
938                 bo_data->hal_bo = hal_tbm_bufmgr_import_key(module->hal_bufmgr, key, (hal_tbm_error *)error);
939                 TBM_GOTO_VAL_IF_FAIL(bo_data->hal_bo, failed);
940                 break;
941 /* LCOV_EXCL_START */
942         case TBM_MODULE_TYPE_TBM_BACKEND:
943                 bufmgr_func = module->bufmgr_func;
944                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bufmgr_func, failed, *error, TBM_ERROR_INVALID_OPERATION);
945                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bufmgr_func->bufmgr_import_key, failed, *error, TBM_ERROR_NOT_SUPPORTED);
946
947                 bo_data->backend_bo_data = bufmgr_func->bufmgr_import_key(module->bufmgr_data, key, error);
948                 TBM_GOTO_VAL_IF_FAIL(bo_data->backend_bo_data, failed);
949                 break;
950         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
951                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
952                 backend = module->backend;
953                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(backend, failed, *error, TBM_ERROR_INVALID_OPERATION);
954                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(backend->bo_import, failed, *error, TBM_ERROR_NOT_SUPPORTED);
955
956                 bo_data->priv = (void *)backend->bo_import(bo, key);
957                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bo_data->priv, failed, *error, TBM_ERROR_INVALID_OPERATION);
958
959                 *error = TBM_ERROR_NONE;
960                 break;
961         default:
962                 TBM_ERR("Wrong module type:%d", module->type);
963                 *error = TBM_ERROR_INVALID_OPERATION;
964                 goto failed;
965                 break;
966 /* LCOV_EXCL_STOP */
967         }
968
969         bo_data->module = module;
970
971         return bo_data;
972
973 /* LCOV_EXCL_START */
974 failed:
975         if (bo_data)
976                 free(bo_data);
977
978         return NULL;
979 /* LCOV_EXCL_STOP */
980 }
981
982 int
983 tbm_module_compare_bo_data(tbm_module *module, tbm_bo_data *bo_data1, tbm_bo_data *bo_data2)
984 {
985         TBM_RETURN_VAL_IF_FAIL(module, 0);
986
987         switch (module->type) {
988         case TBM_MODULE_TYPE_HAL_TBM:
989                 return (bo_data1->hal_bo == bo_data2->hal_bo);
990                 break;
991 /* LCOV_EXCL_START */
992         case TBM_MODULE_TYPE_TBM_BACKEND:
993                 return (bo_data1->backend_bo_data == bo_data2->backend_bo_data);
994                 break;
995         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
996                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
997                 return (bo_data1->priv == bo_data2->priv);
998                 break;
999         default:
1000                 TBM_ERR("Wrong module type:%d", module->type);
1001                 break;
1002 /* LCOV_EXCL_STOP */
1003         }
1004
1005         return 0;
1006 }
1007
1008 void
1009 tbm_surface_data_free(tbm_surface_data *surface_data)
1010 {
1011         TBM_RETURN_IF_FAIL(surface_data);
1012         TBM_RETURN_IF_FAIL(surface_data->module);
1013         TBM_RETURN_IF_FAIL(surface_data->module->type == TBM_MODULE_TYPE_HAL_TBM);
1014
1015         surface_data->module = NULL;
1016
1017         hal_tbm_surface_free(surface_data->hal_surface);
1018         surface_data->hal_surface = NULL;
1019
1020         free(surface_data);
1021 }
1022
1023 tbm_error_e
1024 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)
1025 {
1026         tbm_error_e error;
1027
1028         TBM_RETURN_VAL_IF_FAIL(surface_data, TBM_ERROR_INVALID_PARAMETER);
1029         TBM_RETURN_VAL_IF_FAIL(surface_data->hal_surface, TBM_ERROR_NOT_SUPPORTED);
1030
1031         error = (tbm_error_e)hal_tbm_surface_get_plane_data(surface_data->hal_surface, plane_idx, size, offset, pitch, bo_idx);
1032         TBM_RETURN_VAL_IF_FAIL(error == TBM_ERROR_NONE, error);
1033
1034         return TBM_ERROR_NONE;
1035 }
1036
1037 tbm_bo_data **
1038 tbm_surface_data_get_bo_data_array(tbm_surface_data *surface_data, int *num_bos, int *memory_types, tbm_error_e *error)
1039 {
1040         tbm_bo_data **bo_data_array = NULL;
1041         hal_tbm_bo **hal_bos = NULL;
1042         int i;
1043
1044         TBM_RETURN_VAL_SET_ERR_IF_FAIL(surface_data, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
1045         TBM_RETURN_VAL_SET_ERR_IF_FAIL(surface_data->hal_surface, NULL, *error, TBM_ERROR_NOT_SUPPORTED);
1046
1047         hal_bos = hal_tbm_surface_get_bos(surface_data->hal_surface, num_bos, (hal_tbm_error *)error);
1048         TBM_RETURN_VAL_IF_FAIL(hal_bos, NULL);
1049
1050         bo_data_array = calloc(*num_bos, sizeof(tbm_bo_data *));
1051         TBM_RETURN_VAL_IF_FAIL(bo_data_array, NULL);
1052
1053         for (i = 0; i < *num_bos; i++) {
1054                 bo_data_array[i] = calloc(*num_bos, sizeof(struct _tbm_bo_data));
1055                 TBM_GOTO_VAL_SET_ERR_IF_FAIL(bo_data_array[i], failed, *error, TBM_ERROR_OUT_OF_MEMORY);
1056         }
1057
1058         for (i = 0; i < *num_bos; i++) {
1059                 bo_data_array[i]->hal_bo = hal_bos[i];
1060                 bo_data_array[i]->module = surface_data->module;
1061         }
1062
1063         // get memory_types(bo flags)
1064         *memory_types = tbm_bo_data_get_memory_types(bo_data_array[0], error);
1065         TBM_GOTO_VAL_IF_FAIL(*error == TBM_ERROR_NONE, failed);
1066
1067         return bo_data_array;
1068
1069 /* LCOV_EXCL_START */
1070 failed:
1071         for (i = 0; i < *num_bos; i++) {
1072                 if (bo_data_array[i])
1073                         free(bo_data_array[i]);
1074         }
1075         free(bo_data_array);
1076
1077         return NULL;
1078 /* LCOV_EXCL_STOP */
1079 }
1080
1081 tbm_surface_buffer_data *
1082 tbm_surface_data_export(tbm_surface_data *surface_data, tbm_error_e *error)
1083 {
1084         tbm_surface_buffer_data *buffer_data;
1085
1086         TBM_RETURN_VAL_SET_ERR_IF_FAIL(surface_data, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
1087         TBM_RETURN_VAL_SET_ERR_IF_FAIL(surface_data->hal_surface, NULL, *error, TBM_ERROR_NOT_SUPPORTED);
1088
1089         buffer_data = (tbm_surface_buffer_data *)hal_tbm_surface_export((hal_tbm_surface *)surface_data->hal_surface,
1090                                                                                                                                         (hal_tbm_error *)error);
1091         TBM_RETURN_VAL_IF_FAIL(buffer_data, NULL);
1092
1093         return buffer_data;
1094 }
1095
1096 void
1097 tbm_bo_data_free(tbm_bo_data *bo_data, int get_from_surface_data)
1098 {
1099         tbm_module *module = NULL;
1100         tbm_backend_bo_func *bo_func = NULL;
1101         tbm_bufmgr_backend backend = NULL;
1102
1103         TBM_RETURN_IF_FAIL(bo_data);
1104         TBM_RETURN_IF_FAIL(bo_data->module);
1105
1106         module = bo_data->module;
1107
1108         switch (module->type) {
1109         case TBM_MODULE_TYPE_HAL_TBM:
1110                 // call hal_tbm_bo_free when bo is created by tbm_bo_alloc api.
1111                 if (!get_from_surface_data) {
1112                         hal_tbm_bo_free(bo_data->hal_bo);
1113                         bo_data->hal_bo = NULL;
1114                 }
1115                 break;
1116 /* LCOV_EXCL_START */
1117         case TBM_MODULE_TYPE_TBM_BACKEND:
1118                 bo_func = module->bo_func;
1119                 TBM_RETURN_IF_FAIL(bo_func);
1120                 TBM_RETURN_IF_FAIL(bo_func->bo_free);
1121
1122                 bo_func->bo_free(bo_data->backend_bo_data);
1123                 bo_data->backend_bo_data = NULL;
1124                 break;
1125         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1126                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1127                 backend = module->backend;
1128                 TBM_RETURN_IF_FAIL(backend);
1129                 TBM_RETURN_IF_FAIL(backend->bo_free);
1130
1131                 backend->bo_free(bo_data->priv);
1132                 bo_data->priv = NULL;
1133                 break;
1134         default:
1135                 TBM_ERR("Wrong module type:%d", module->type);
1136                 break;
1137 /* LCOV_EXCL_STOP */
1138         }
1139
1140         bo_data->module = NULL;
1141         free(bo_data);
1142 }
1143
1144 int
1145 tbm_bo_data_get_size(tbm_bo_data *bo_data, tbm_error_e *error)
1146 {
1147         tbm_module *module = NULL;
1148         tbm_backend_bo_func *bo_func = NULL;
1149         tbm_bufmgr_backend backend = NULL;
1150         int size = 0;
1151
1152         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data, 0, *error, TBM_ERROR_INVALID_PARAMETER);
1153         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data->module, 0, *error, TBM_ERROR_INVALID_PARAMETER);
1154
1155         module = bo_data->module;
1156
1157         switch (module->type) {
1158         case TBM_MODULE_TYPE_HAL_TBM:
1159                 size = hal_tbm_bo_get_size(bo_data->hal_bo, (hal_tbm_error *)error);
1160                 break;
1161 /* LCOV_EXCL_START */
1162         case TBM_MODULE_TYPE_TBM_BACKEND:
1163                 bo_func = module->bo_func;
1164                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func, 0, *error, TBM_ERROR_INVALID_OPERATION);
1165                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func->bo_get_size, 0, *error, TBM_ERROR_NOT_SUPPORTED);
1166
1167                 size = bo_func->bo_get_size(bo_data->backend_bo_data, error);
1168                 break;
1169         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1170                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1171                 backend = module->backend;
1172                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend, 0, *error, TBM_ERROR_INVALID_OPERATION);
1173                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend->bo_size, 0, *error, TBM_ERROR_NOT_SUPPORTED);
1174
1175                 size = backend->bo_size(bo_data->priv);
1176                 if (size == 0)
1177                         *error = TBM_ERROR_INVALID_OPERATION;
1178                 else
1179                         *error = TBM_ERROR_NONE;
1180                 break;
1181         default:
1182                 TBM_ERR("Wrong module type:%d", module->type);
1183                 *error = TBM_ERROR_INVALID_OPERATION;
1184                 break;
1185 /* LCOV_EXCL_STOP */
1186         }
1187
1188         return size;
1189 }
1190
1191 int
1192 tbm_bo_data_get_memory_types(tbm_bo_data *bo_data, tbm_error_e *error)
1193 {
1194         tbm_module *module = NULL;
1195         tbm_backend_bo_func *bo_func = NULL;
1196         tbm_bufmgr_backend backend = NULL;
1197         int memory_types = TBM_BO_DEFAULT;
1198
1199         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data, 0, *error, TBM_ERROR_INVALID_PARAMETER);
1200         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data->module, 0, *error, TBM_ERROR_INVALID_PARAMETER);
1201
1202         module = bo_data->module;
1203
1204         switch (module->type) {
1205         case TBM_MODULE_TYPE_HAL_TBM:
1206                 memory_types = (tbm_bo_memory_type)hal_tbm_bo_get_memory_types(bo_data->hal_bo, (hal_tbm_error *)error);
1207                 break;
1208 /* LCOV_EXCL_START */
1209         case TBM_MODULE_TYPE_TBM_BACKEND:
1210                 bo_func = module->bo_func;
1211                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func, 0, *error, TBM_ERROR_INVALID_OPERATION);
1212                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func->bo_get_memory_types, 0, *error, TBM_ERROR_NOT_SUPPORTED);
1213
1214                 memory_types = bo_func->bo_get_memory_types(bo_data->backend_bo_data, error);
1215                 break;
1216         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1217                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1218                 backend = module->backend;
1219                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend, 0, *error, TBM_ERROR_INVALID_OPERATION);
1220                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend->bo_get_flags, 0, *error, TBM_ERROR_NOT_SUPPORTED);
1221
1222                 memory_types = backend->bo_get_flags(bo_data->priv);
1223                 *error = TBM_ERROR_NONE;
1224                 break;
1225         default:
1226                 TBM_ERR("Wrong module type:%d", module->type);
1227                 *error = TBM_ERROR_INVALID_OPERATION;
1228                 break;
1229 /* LCOV_EXCL_STOP */
1230         }
1231
1232         return memory_types;
1233 }
1234
1235 tbm_bo_handle
1236 tbm_bo_data_get_handle(tbm_bo_data *bo_data, int device, tbm_error_e *error)
1237 {
1238         tbm_module *module = NULL;
1239         tbm_backend_bo_func *bo_func = NULL;
1240         tbm_bufmgr_backend backend = NULL;
1241         tbm_bo_handle bo_handle = (tbm_bo_handle)NULL;
1242         hal_tbm_bo_handle hbo_handle;
1243
1244         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data, (tbm_bo_handle)NULL, *error, TBM_ERROR_INVALID_PARAMETER);
1245         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data->module, (tbm_bo_handle)NULL, *error, TBM_ERROR_INVALID_PARAMETER);
1246
1247         module = bo_data->module;
1248
1249         switch (module->type) {
1250         case TBM_MODULE_TYPE_HAL_TBM:
1251                 hbo_handle = hal_tbm_bo_get_handle(bo_data->hal_bo, device, (hal_tbm_error *)error);
1252                 if (hbo_handle.ptr != NULL)
1253                         memcpy(&bo_handle.ptr, &hbo_handle.ptr, sizeof(tbm_bo_handle));
1254                 break;
1255 /* LCOV_EXCL_START */
1256         case TBM_MODULE_TYPE_TBM_BACKEND:
1257                 bo_func = module->bo_func;
1258                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func, (tbm_bo_handle)NULL, *error, TBM_ERROR_INVALID_OPERATION);
1259                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func->bo_get_handle, (tbm_bo_handle)NULL, *error, TBM_ERROR_NOT_SUPPORTED);
1260
1261                 bo_handle = bo_func->bo_get_handle(bo_data->backend_bo_data, device, error);
1262                 break;
1263         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1264                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1265                 backend = module->backend;
1266                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend, (tbm_bo_handle)NULL, *error, TBM_ERROR_INVALID_OPERATION);
1267                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend->bo_get_handle, (tbm_bo_handle)NULL, *error, TBM_ERROR_NOT_SUPPORTED);
1268
1269                 bo_handle = backend->bo_get_handle(bo_data->priv, device);
1270                 if (!bo_handle.ptr)
1271                         *error = TBM_ERROR_INVALID_OPERATION;
1272                 else
1273                         *error = TBM_ERROR_NONE;
1274                 break;
1275         default:
1276                 TBM_ERR("Wrong module type:%d", module->type);
1277                 bo_handle.ptr = NULL;
1278                 *error = TBM_ERROR_INVALID_OPERATION;
1279                 break;
1280 /* LCOV_EXCL_STOP */
1281         }
1282
1283         return bo_handle;
1284 }
1285
1286 tbm_bo_handle
1287 tbm_bo_data_map(tbm_bo_data *bo_data, int device, int opt, tbm_error_e *error)
1288 {
1289         tbm_module *module = NULL;
1290         tbm_backend_bo_func *bo_func = NULL;
1291         tbm_bufmgr_backend backend = NULL;
1292         tbm_bo_handle bo_handle = (tbm_bo_handle)NULL;
1293         hal_tbm_bo_handle hbo_handle;
1294
1295         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data, (tbm_bo_handle)NULL, *error, TBM_ERROR_INVALID_PARAMETER);
1296         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data->module, (tbm_bo_handle)NULL, *error, TBM_ERROR_INVALID_PARAMETER);
1297
1298         module = bo_data->module;
1299
1300         switch (module->type) {
1301         case TBM_MODULE_TYPE_HAL_TBM:
1302                 hbo_handle = hal_tbm_bo_map(bo_data->hal_bo, device, opt, (hal_tbm_error *)error);
1303                 if (hbo_handle.ptr != NULL)
1304                         memcpy(&bo_handle.ptr, &hbo_handle.ptr, sizeof(tbm_bo_handle));
1305                 break;
1306 /* LCOV_EXCL_START */
1307         case TBM_MODULE_TYPE_TBM_BACKEND:
1308                 bo_func = module->bo_func;
1309                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func, (tbm_bo_handle)NULL, *error, TBM_ERROR_INVALID_OPERATION);
1310                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func->bo_map, (tbm_bo_handle)NULL, *error, TBM_ERROR_NOT_SUPPORTED);
1311
1312                 bo_handle = bo_func->bo_map(bo_data->backend_bo_data, device, opt, error);
1313                 break;
1314         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1315                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1316                 backend = module->backend;
1317                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend, (tbm_bo_handle)NULL, *error, TBM_ERROR_INVALID_OPERATION);
1318                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend->bo_map, (tbm_bo_handle)NULL, *error, TBM_ERROR_NOT_SUPPORTED);
1319
1320                 bo_handle = backend->bo_map(bo_data->priv, device, opt);
1321                 if (!bo_handle.ptr)
1322                         *error = TBM_ERROR_INVALID_OPERATION;
1323                 else
1324                         *error = TBM_ERROR_NONE;
1325                 break;
1326         default:
1327                 TBM_ERR("Wrong module type:%d", module->type);
1328                 bo_handle.ptr = NULL;
1329                 *error = TBM_ERROR_INVALID_OPERATION;
1330                 break;
1331 /* LCOV_EXCL_STOP */
1332         }
1333
1334         return bo_handle;
1335 }
1336
1337 tbm_error_e
1338 tbm_bo_data_unmap(tbm_bo_data *bo_data)
1339 {
1340         tbm_module *module = NULL;
1341         tbm_backend_bo_func *bo_func = NULL;
1342         tbm_bufmgr_backend backend = NULL;
1343         tbm_error_e error;
1344         int ret = 0;
1345
1346         TBM_RETURN_VAL_IF_FAIL(bo_data, TBM_ERROR_INVALID_PARAMETER);
1347         TBM_RETURN_VAL_IF_FAIL(bo_data->module, TBM_ERROR_INVALID_PARAMETER);
1348
1349         module = bo_data->module;
1350
1351         switch (module->type) {
1352         case TBM_MODULE_TYPE_HAL_TBM:
1353                 error = (hal_tbm_error)hal_tbm_bo_unmap(bo_data->hal_bo);
1354                 break;
1355 /* LCOV_EXCL_START */
1356         case TBM_MODULE_TYPE_TBM_BACKEND:
1357                 bo_func = module->bo_func;
1358                 TBM_RETURN_VAL_IF_FAIL(bo_func, TBM_ERROR_INVALID_OPERATION);
1359                 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_unmap, TBM_ERROR_NOT_SUPPORTED);
1360
1361                 error = bo_func->bo_unmap(bo_data->backend_bo_data);
1362                 break;
1363         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1364                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1365                 backend = module->backend;
1366                 TBM_RETURN_VAL_IF_FAIL(backend, TBM_ERROR_INVALID_OPERATION);
1367                 TBM_RETURN_VAL_IF_FAIL(backend->bo_unmap, TBM_ERROR_NOT_SUPPORTED);
1368
1369                 ret = backend->bo_unmap(bo_data->priv);
1370                 if (!ret)
1371                         error = TBM_ERROR_INVALID_OPERATION;
1372                 else
1373                         error = TBM_ERROR_NONE;
1374                 break;
1375         default:
1376                 TBM_ERR("Wrong module type:%d", module->type);
1377                 error = TBM_ERROR_INVALID_OPERATION;
1378                 break;
1379 /* LCOV_EXCL_STOP */
1380         }
1381
1382         return error;
1383 }
1384
1385 tbm_error_e
1386 tbm_bo_data_lock(tbm_bo_data *bo_data, int device, int opt)
1387 {
1388         tbm_module *module = NULL;
1389         tbm_backend_bo_func *bo_func = NULL;
1390         tbm_bufmgr_backend backend = NULL;
1391         tbm_error_e error;
1392         int ret = 0;
1393
1394         TBM_RETURN_VAL_IF_FAIL(bo_data, TBM_ERROR_INVALID_PARAMETER);
1395         TBM_RETURN_VAL_IF_FAIL(bo_data->module, TBM_ERROR_INVALID_PARAMETER);
1396
1397         module = bo_data->module;
1398
1399         switch (module->type) {
1400         case TBM_MODULE_TYPE_HAL_TBM:
1401                 error = (tbm_error_e)hal_tbm_bo_lock(bo_data->hal_bo, device, opt);
1402                 break;
1403 /* LCOV_EXCL_START */
1404         case TBM_MODULE_TYPE_TBM_BACKEND:
1405                 bo_func = module->bo_func;
1406                 TBM_RETURN_VAL_IF_FAIL(bo_func, TBM_ERROR_INVALID_OPERATION);
1407                 if (!bo_func->bo_lock)
1408                         return TBM_ERROR_NOT_SUPPORTED;
1409
1410                 error = bo_func->bo_lock(bo_data->backend_bo_data, device, opt);
1411                 break;
1412         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1413                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1414                 backend = module->backend;
1415                 TBM_RETURN_VAL_IF_FAIL(backend, TBM_ERROR_INVALID_OPERATION);
1416                 if (!backend->bo_unmap)
1417                         return TBM_ERROR_NOT_SUPPORTED;
1418
1419                 ret = backend->bo_lock(bo_data->priv, device, opt);
1420                 if (!ret)
1421                         error = TBM_ERROR_INVALID_OPERATION;
1422                 else
1423                         error = TBM_ERROR_NONE;
1424                 break;
1425         default:
1426                 TBM_ERR("Wrong module type:%d", module->type);
1427                 error = TBM_ERROR_INVALID_OPERATION;
1428                 break;
1429 /* LCOV_EXCL_STOP */
1430         }
1431
1432         return error;
1433 }
1434
1435 tbm_error_e
1436 tbm_bo_data_unlock(tbm_bo_data *bo_data)
1437 {
1438         tbm_module *module = NULL;
1439         tbm_backend_bo_func *bo_func = NULL;
1440         tbm_bufmgr_backend backend = NULL;
1441         tbm_error_e error;
1442
1443         TBM_RETURN_VAL_IF_FAIL(bo_data, TBM_ERROR_INVALID_PARAMETER);
1444         TBM_RETURN_VAL_IF_FAIL(bo_data->module, TBM_ERROR_INVALID_PARAMETER);
1445
1446         module = bo_data->module;
1447
1448         switch (module->type) {
1449         case TBM_MODULE_TYPE_HAL_TBM:
1450                 error = (tbm_error_e)hal_tbm_bo_unlock(bo_data->hal_bo);
1451                 break;
1452 /* LCOV_EXCL_START */
1453         case TBM_MODULE_TYPE_TBM_BACKEND:
1454                 bo_func = module->bo_func;
1455                 TBM_RETURN_VAL_IF_FAIL(bo_func, TBM_ERROR_INVALID_OPERATION);
1456                 if (!bo_func->bo_unlock)
1457                         return TBM_ERROR_NOT_SUPPORTED;
1458
1459                 error = bo_func->bo_unlock(bo_data->backend_bo_data);
1460                 break;
1461         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1462                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1463                 backend = module->backend;
1464                 TBM_RETURN_VAL_IF_FAIL(backend, TBM_ERROR_INVALID_OPERATION);
1465                 if (!backend->bo_unlock)
1466                         return TBM_ERROR_NOT_SUPPORTED;
1467
1468                 backend->bo_unlock(bo_data->priv);
1469                 error = TBM_ERROR_NONE;
1470                 break;
1471         default:
1472                 TBM_ERR("Wrong module type:%d", module->type);
1473                 error = TBM_ERROR_INVALID_OPERATION;
1474                 break;
1475 /* LCOV_EXCL_STOP */
1476         }
1477
1478         return error;
1479 }
1480
1481 tbm_fd
1482 tbm_bo_data_export_fd(tbm_bo_data *bo_data, tbm_error_e *error)
1483 {
1484         tbm_module *module = NULL;
1485         tbm_backend_bo_func *bo_func = NULL;
1486         tbm_bufmgr_backend backend = NULL;
1487         tbm_fd fd;
1488
1489         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data, -1, *error, TBM_ERROR_INVALID_PARAMETER);
1490         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data->module, -1, *error, TBM_ERROR_INVALID_PARAMETER);
1491
1492         module = bo_data->module;
1493
1494         switch (module->type) {
1495         case TBM_MODULE_TYPE_HAL_TBM:
1496                 fd = (hal_tbm_fd)hal_tbm_bo_export_fd(bo_data->hal_bo, (hal_tbm_error *)error);
1497                 break;
1498 /* LCOV_EXCL_START */
1499         case TBM_MODULE_TYPE_TBM_BACKEND:
1500                 bo_func = module->bo_func;
1501                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func, -1, *error, TBM_ERROR_INVALID_OPERATION);
1502                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func->bo_export_fd, -1, *error, TBM_ERROR_NOT_SUPPORTED);
1503
1504                 fd = bo_func->bo_export_fd(bo_data->backend_bo_data, error);
1505                 break;
1506         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1507                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1508                 backend = module->backend;
1509                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend, -1, *error, TBM_ERROR_INVALID_OPERATION);
1510                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend->bo_export_fd, -1, *error, TBM_ERROR_NOT_SUPPORTED);
1511
1512                 fd = backend->bo_export_fd(bo_data->priv);
1513                 if (fd < 0)
1514                         *error = TBM_ERROR_INVALID_OPERATION;
1515                 else
1516                         *error = TBM_ERROR_NONE;
1517                 break;
1518         default:
1519                 TBM_ERR("Wrong module type:%d", module->type);
1520                 fd = -1;
1521                 *error = TBM_ERROR_INVALID_OPERATION;
1522                 break;
1523 /* LCOV_EXCL_STOP */
1524         }
1525
1526         return fd;
1527 }
1528
1529 tbm_key
1530 tbm_bo_data_export_key(tbm_bo_data *bo_data, tbm_error_e *error)
1531 {
1532         tbm_module *module = NULL;
1533         tbm_backend_bo_func *bo_func = NULL;
1534         tbm_bufmgr_backend backend = NULL;
1535         tbm_key ret;
1536
1537         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data, 0, *error, TBM_ERROR_INVALID_PARAMETER);
1538         TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_data->module, 0, *error, TBM_ERROR_INVALID_PARAMETER);
1539
1540         module = bo_data->module;
1541
1542         switch (module->type) {
1543         case TBM_MODULE_TYPE_HAL_TBM:
1544                 ret = (hal_tbm_fd)hal_tbm_bo_export_key(bo_data->hal_bo, (hal_tbm_error *)error);
1545                 break;
1546 /* LCOV_EXCL_START */
1547         case TBM_MODULE_TYPE_TBM_BACKEND:
1548                 bo_func = module->bo_func;
1549                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func, 0, *error, TBM_ERROR_INVALID_OPERATION);
1550                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bo_func->bo_export_key, 0, *error, TBM_ERROR_NOT_SUPPORTED);
1551
1552                 ret = bo_func->bo_export_key(bo_data->backend_bo_data, error);
1553                 break;
1554         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
1555                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
1556                 backend = module->backend;
1557                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend, 0, *error, TBM_ERROR_INVALID_OPERATION);
1558                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend->bo_export, 0, *error, TBM_ERROR_NOT_SUPPORTED);
1559
1560                 ret = backend->bo_export(bo_data->priv);
1561                 if (!ret)
1562                         *error = TBM_ERROR_INVALID_OPERATION;
1563                 else
1564                         *error = TBM_ERROR_NONE;
1565                 break;
1566         default:
1567                 TBM_ERR("Wrong module type:%d", module->type);
1568                 ret = -1;
1569                 *error = TBM_ERROR_INVALID_OPERATION;
1570                 break;
1571 /* LCOV_EXCL_STOP */
1572         }
1573
1574         return ret;
1575 }