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