1 /**************************************************************************
5 Copyright 2012 - 2016 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: SooChan Lim <sc1.lim@samsung.com>,
8 Changyeon Lee <cyeon.lee@samsung.com>,
9 Boram Park <boram1288.park@samsung.com>,
10 Sangjin Lee <lsj119@samsung.com>
12 Permission is hereby granted, free of charge, to any person obtaining a
13 copy of this software and associated documentation files (the
14 "Software"), to deal in the Software without restriction, including
15 without limitation the rights to use, copy, modify, merge, publish,
16 distribute, sub license, and/or sell copies of the Software, and to
17 permit persons to whom the Software is furnished to do so, subject to
18 the following conditions:
20 The above copyright notice and this permission notice (including the
21 next paragraph) shall be included in all copies or substantial portions
24 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
27 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
28 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 **************************************************************************/
34 #include "tbm_bufmgr.h"
35 #include "tbm_bufmgr_int.h"
40 #include <sys/ioctl.h>
41 #include <linux/types.h>
43 #define SYNC_IOC_MAGIC '>'
44 #define SYNC_IOC_WAIT _IOW(SYNC_IOC_MAGIC, 0, __s32)
45 #define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 1, struct sync_merge_data)
46 #define SW_SYNC_IOC_MAGIC 'W'
47 #define SW_SYNC_IOC_CREATE_FENCE _IOWR(SW_SYNC_IOC_MAGIC, 0,\
48 struct sw_sync_create_fence_data)
49 #define SW_SYNC_IOC_INC _IOW(SW_SYNC_IOC_MAGIC, 1, __u32)
51 #define SYNC_DEVICE_PATH "/dev/sw_sync"
53 struct _tbm_sync_timeline {
57 struct _tbm_sync_fence {
61 static pthread_mutex_t tbm_sync_lock;
62 static int tbm_sync_support = 0;
65 _tbm_sync_mutex_init(void)
67 static bool tbm_sync_mutex_init = false;
69 if (tbm_sync_mutex_init)
72 if (pthread_mutex_init(&tbm_sync_lock, NULL)) {
73 TBM_LOG_E("fail: tbm_sync mutex init\n");
77 tbm_sync_mutex_init = true;
83 _tbm_sync_mutex_lock(void)
85 if (!_tbm_sync_mutex_init())
88 pthread_mutex_lock(&tbm_sync_lock);
92 _tbm_sync_mutex_unlock(void)
94 pthread_mutex_unlock(&tbm_sync_lock);
97 static tbm_sync_error_e
98 _tbm_sync_check_capability(void)
100 #ifdef NOT_IMPELMENT_YET
101 tbm_bufmgr bufmgr = NULL;
102 unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
106 if (tbm_sync_support)
107 return TBM_SYNC_ERROR_NONE;
109 #ifdef NOT_IMPELMENT_YET
110 /* check the bufmgr */
111 bufmgr = _tbm_bufmgr_get_bufmgr();
113 return TBM_SYNC_ERROR_INVALID_OPERATION;
116 /* check the tbm_sync capability */
117 capabilities = tbm_bufmgr_get_capability(bufmgr);
119 if ((capabilities&TBM_BUFMGR_CAPABILITY_TBM_SYNC) != TBM_BUFMGR_CAPABILITY_TBM_SYNC) {
120 //TODO: check the sw_sync device node... to verify the timeline sync
121 tbm_sync_support = 1;
123 return TBM_SYNC_ERROR_INVALID_OPERATION;
127 if (stat(SYNC_DEVICE_PATH, &st_buf) == 0) {
128 tbm_sync_support = 1;
130 TBM_LOG_E("TBM_SYNC not supported\n");
131 return TBM_SYNC_ERROR_INVALID_OPERATION;
134 return TBM_SYNC_ERROR_NONE;
138 tbm_sync_timeline_create(tbm_sync_error_e *error)
140 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
141 tbm_sync_timeline_h timeline = NULL;
144 _tbm_sync_mutex_lock();
146 /* check the tbm_sync capability */
147 ret = _tbm_sync_check_capability();;
148 if (ret != TBM_SYNC_ERROR_NONE)
151 fd = open(SYNC_DEVICE_PATH, O_RDWR);
153 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
154 TBM_LOG_E("%s:%d(%s)\n", "TBM_SYNC open failed", errno, strerror(errno));
156 struct _tbm_sync_timeline *timeline_handle =
157 calloc(1, sizeof(struct _tbm_sync_timeline));
159 if (timeline_handle == NULL) {
160 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
161 TBM_LOG_E("%s\n", "TBM_SYNC calloc failed");
164 timeline = timeline_handle;
172 _tbm_sync_mutex_unlock();
178 tbm_sync_timeline_destroy(tbm_sync_timeline_h timeline)
180 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
182 _tbm_sync_mutex_lock();
184 /* check the tbm_sync capability */
185 ret = _tbm_sync_check_capability();;
186 if (ret != TBM_SYNC_ERROR_NONE)
190 struct _tbm_sync_timeline *timeline_handle = timeline;
192 if (timeline_handle->fd != -1)
193 close(timeline_handle->fd);
196 ret = TBM_SYNC_ERROR_INVALID_PARAMETER;
200 _tbm_sync_mutex_unlock();
206 tbm_sync_timeline_import(int fd, tbm_sync_error_e *error)
208 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
209 tbm_sync_timeline_h timeline = NULL;
211 _tbm_sync_mutex_lock();
213 /* check the tbm_sync capability */
214 ret = _tbm_sync_check_capability();;
215 if (ret != TBM_SYNC_ERROR_NONE)
219 ret = TBM_SYNC_ERROR_INVALID_PARAMETER;
221 struct _tbm_sync_timeline *timeline_handle =
222 calloc(1, sizeof(struct _tbm_sync_timeline));
224 if (timeline_handle == NULL) {
225 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
226 TBM_LOG_E("%s\n", "TBM_SYNC calloc failed");
228 timeline_handle->fd = fd;
229 timeline = timeline_handle;
237 _tbm_sync_mutex_unlock();
243 tbm_sync_timeline_export(tbm_sync_timeline_h timeline, tbm_sync_error_e *error)
245 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
248 _tbm_sync_mutex_lock();
250 /* check the tbm_sync capability */
251 ret = _tbm_sync_check_capability();;
252 if (ret != TBM_SYNC_ERROR_NONE)
256 struct _tbm_sync_timeline *timeline_handle = timeline;
257 fd = dup(timeline_handle->fd);
259 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
260 TBM_LOG_E("%s:%d(%s)\n", "TBM_SYNC timeline dup failed",
261 errno, strerror(errno));
264 ret = TBM_SYNC_ERROR_INVALID_PARAMETER;
271 _tbm_sync_mutex_unlock();
277 tbm_sync_timeline_increase_count(tbm_sync_timeline_h timeline, unsigned int interval)
279 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
281 _tbm_sync_mutex_lock();
283 /* check the tbm_sync capability */
284 ret = _tbm_sync_check_capability();;
285 if (ret != TBM_SYNC_ERROR_NONE)
289 struct _tbm_sync_timeline *timeline_handle = timeline;
290 __u32 arg = interval;
292 if (ioctl(timeline_handle->fd, SW_SYNC_IOC_INC, &arg) == -1) {
293 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
294 TBM_LOG_E("%s:%d(%s)\n", "TBM_SYNC timeline inc failed", errno, strerror(errno));
297 ret = TBM_SYNC_ERROR_INVALID_PARAMETER;
301 _tbm_sync_mutex_unlock();
307 tbm_sync_timeline_get_cur_count(tbm_sync_timeline_h timeline, tbm_sync_error_e *error)
309 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
310 unsigned int cur_count = 0;
312 _tbm_sync_mutex_lock();
314 /* check the tbm_sync capability */
315 ret = _tbm_sync_check_capability();;
316 if (ret != TBM_SYNC_ERROR_NONE)
319 /* TODO: sync_timeline_get_cur_count */
325 _tbm_sync_mutex_unlock();
331 tbm_sync_fence_create(tbm_sync_timeline_h timeline, const char *name, unsigned int count_val, tbm_sync_error_e *error)
333 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
334 tbm_sync_fence_h fence = NULL;
336 _tbm_sync_mutex_lock();
338 /* check the tbm_sync capability */
339 ret = _tbm_sync_check_capability();;
340 if (ret != TBM_SYNC_ERROR_NONE)
344 struct _tbm_sync_timeline *timeline_handle = timeline;
345 struct sw_sync_create_fence_data {
351 data.value = count_val;
352 strncpy(data.name, name ? name : "", 32);
353 data.name[31] = '\0';
355 if (ioctl(timeline_handle->fd, SW_SYNC_IOC_CREATE_FENCE, &data) == -1) {
356 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
357 TBM_LOG_E("%s:%d(%s)\n", "TBM_SYNC create fence failed",
358 errno, strerror(errno));
360 struct _tbm_sync_fence *fence_handle =
361 calloc(1, sizeof(struct _tbm_sync_fence));
363 if (fence_handle == NULL) {
364 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
365 TBM_LOG_E("%s\n", "TBM_SYNC calloc failed");
368 fence_handle->fd = data.fence;
369 fence = fence_handle;
373 ret = TBM_SYNC_ERROR_INVALID_PARAMETER;
380 _tbm_sync_mutex_unlock();
386 tbm_sync_fence_destroy(tbm_sync_fence_h fence)
388 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
390 _tbm_sync_mutex_lock();
392 /* check the tbm_sync capability */
393 ret = _tbm_sync_check_capability();;
394 if (ret != TBM_SYNC_ERROR_NONE)
398 struct _tbm_sync_fence *fence_handle = fence;
400 if (fence_handle->fd != -1)
401 close(fence_handle->fd);
406 _tbm_sync_mutex_unlock();
412 tbm_sync_fence_wait(tbm_sync_fence_h fence, int timeout)
414 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
416 _tbm_sync_mutex_lock();
418 /* check the tbm_sync capability */
419 ret = _tbm_sync_check_capability();;
420 if (ret != TBM_SYNC_ERROR_NONE)
424 struct _tbm_sync_fence *fence_handle = fence;
427 if (ioctl(fence_handle->fd, SYNC_IOC_WAIT, &to) == -1) {
428 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
429 TBM_LOG_E("%s:%d(%s)\n", "TBM_SYNC fence wait failed", errno, strerror(errno));
432 ret = TBM_SYNC_ERROR_INVALID_PARAMETER;
436 _tbm_sync_mutex_unlock();
442 tbm_sync_fence_merge(tbm_sync_fence_h fence1, tbm_sync_fence_h fence2, const char *name, tbm_sync_error_e *error)
444 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
445 tbm_sync_fence_h fence = NULL;
447 _tbm_sync_mutex_lock();
449 /* check the tbm_sync capability */
450 ret = _tbm_sync_check_capability();;
451 if (ret != TBM_SYNC_ERROR_NONE)
454 if (fence1 && fence2) {
455 struct _tbm_sync_fence *fence_handle1 = fence1;
456 struct _tbm_sync_fence *fence_handle2 = fence2;
458 struct sync_merge_data {
464 data.fd2 = fence_handle2->fd;
465 strncpy(data.name, name ? name : "", 32);
466 data.name[31] = '\0';
468 if (ioctl(fence_handle1->fd, SYNC_IOC_MERGE, &data) == -1) {
469 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
470 TBM_LOG_E("%s:%d(%s)\n", "TBM_SYNC fence merge failed",
471 errno, strerror(errno));
473 struct _tbm_sync_fence *fence_handle =
474 calloc(1, sizeof(struct _tbm_sync_fence));
476 if (fence_handle == NULL) {
477 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
478 TBM_LOG_E("%s\n", "TBM_SYNC calloc failed");
481 fence_handle->fd = data.fence;
485 ret = TBM_SYNC_ERROR_INVALID_PARAMETER;
492 _tbm_sync_mutex_unlock();
498 tbm_sync_fence_get_count_val(tbm_sync_fence_h fence, tbm_sync_error_e *error)
500 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
501 unsigned int count_val = 0;
503 _tbm_sync_mutex_lock();
505 /* check the tbm_sync capability */
506 ret = _tbm_sync_check_capability();;
507 if (ret != TBM_SYNC_ERROR_NONE)
510 /* TODO: sync_fence_get_count_val */
516 _tbm_sync_mutex_unlock();
522 tbm_sync_fence_import(int fd, tbm_sync_error_e *error)
524 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
525 tbm_sync_fence_h fence = NULL;
527 _tbm_sync_mutex_lock();
529 /* check the tbm_sync capability */
530 ret = _tbm_sync_check_capability();;
531 if (ret != TBM_SYNC_ERROR_NONE)
535 ret = TBM_SYNC_ERROR_INVALID_PARAMETER;
537 struct _tbm_sync_fence *fence_handle =
538 calloc(1, sizeof(struct _tbm_sync_fence));
540 if (fence_handle == NULL) {
541 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
542 TBM_LOG_E("%s\n", "TBM_SYNC calloc failed");
544 fence_handle->fd = fd;
545 fence = fence_handle;
553 _tbm_sync_mutex_unlock();
559 tbm_sync_fence_export(tbm_sync_fence_h fence, tbm_sync_error_e *error)
561 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
564 _tbm_sync_mutex_lock();
566 /* check the tbm_sync capability */
567 ret = _tbm_sync_check_capability();;
568 if (ret != TBM_SYNC_ERROR_NONE)
572 struct _tbm_sync_fence *fence_handle = fence;
573 fd = dup(fence_handle->fd);
575 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
576 TBM_LOG_E("%s:%d(%s)\n", "TBM_SYNC fence dup failed",
577 errno, strerror(errno));
580 ret = TBM_SYNC_ERROR_INVALID_PARAMETER;
587 _tbm_sync_mutex_unlock();