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