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_handle->fd = fd;
165 timeline = timeline_handle;
173 _tbm_sync_mutex_unlock();
179 tbm_sync_timeline_destroy(tbm_sync_timeline_h timeline)
181 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
183 _tbm_sync_mutex_lock();
185 /* check the tbm_sync capability */
186 ret = _tbm_sync_check_capability();;
187 if (ret != TBM_SYNC_ERROR_NONE)
191 struct _tbm_sync_timeline *timeline_handle = timeline;
193 if (timeline_handle->fd != -1)
194 close(timeline_handle->fd);
197 ret = TBM_SYNC_ERROR_INVALID_PARAMETER;
201 _tbm_sync_mutex_unlock();
207 tbm_sync_timeline_import(int fd, tbm_sync_error_e *error)
209 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
210 tbm_sync_timeline_h timeline = NULL;
212 _tbm_sync_mutex_lock();
214 /* check the tbm_sync capability */
215 ret = _tbm_sync_check_capability();;
216 if (ret != TBM_SYNC_ERROR_NONE)
220 ret = TBM_SYNC_ERROR_INVALID_PARAMETER;
222 struct _tbm_sync_timeline *timeline_handle =
223 calloc(1, sizeof(struct _tbm_sync_timeline));
225 if (timeline_handle == NULL) {
226 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
227 TBM_LOG_E("%s\n", "TBM_SYNC calloc failed");
229 timeline_handle->fd = fd;
230 timeline = timeline_handle;
238 _tbm_sync_mutex_unlock();
244 tbm_sync_timeline_export(tbm_sync_timeline_h timeline, tbm_sync_error_e *error)
246 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
249 _tbm_sync_mutex_lock();
251 /* check the tbm_sync capability */
252 ret = _tbm_sync_check_capability();;
253 if (ret != TBM_SYNC_ERROR_NONE)
257 struct _tbm_sync_timeline *timeline_handle = timeline;
258 fd = dup(timeline_handle->fd);
260 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
261 TBM_LOG_E("%s:%d(%s)\n", "TBM_SYNC timeline dup failed",
262 errno, strerror(errno));
265 ret = TBM_SYNC_ERROR_INVALID_PARAMETER;
272 _tbm_sync_mutex_unlock();
278 tbm_sync_timeline_increase_count(tbm_sync_timeline_h timeline, unsigned int interval)
280 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
282 _tbm_sync_mutex_lock();
284 /* check the tbm_sync capability */
285 ret = _tbm_sync_check_capability();;
286 if (ret != TBM_SYNC_ERROR_NONE)
290 struct _tbm_sync_timeline *timeline_handle = timeline;
291 __u32 arg = interval;
293 if (ioctl(timeline_handle->fd, SW_SYNC_IOC_INC, &arg) == -1) {
294 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
295 TBM_LOG_E("%s:%d(%s)\n", "TBM_SYNC timeline inc failed", errno, strerror(errno));
298 ret = TBM_SYNC_ERROR_INVALID_PARAMETER;
302 _tbm_sync_mutex_unlock();
308 tbm_sync_timeline_get_cur_count(tbm_sync_timeline_h timeline, tbm_sync_error_e *error)
310 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
311 unsigned int cur_count = 0;
313 _tbm_sync_mutex_lock();
315 /* check the tbm_sync capability */
316 ret = _tbm_sync_check_capability();;
317 if (ret != TBM_SYNC_ERROR_NONE)
320 /* TODO: sync_timeline_get_cur_count */
326 _tbm_sync_mutex_unlock();
332 tbm_sync_fence_create(tbm_sync_timeline_h timeline, const char *name, unsigned int count_val, tbm_sync_error_e *error)
334 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
335 tbm_sync_fence_h fence = NULL;
337 _tbm_sync_mutex_lock();
339 /* check the tbm_sync capability */
340 ret = _tbm_sync_check_capability();;
341 if (ret != TBM_SYNC_ERROR_NONE)
345 struct _tbm_sync_timeline *timeline_handle = timeline;
346 struct sw_sync_create_fence_data {
352 data.value = count_val;
353 strncpy(data.name, name ? name : "", 32);
354 data.name[31] = '\0';
356 if (ioctl(timeline_handle->fd, SW_SYNC_IOC_CREATE_FENCE, &data) == -1) {
357 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
358 TBM_LOG_E("%s:%d(%s)\n", "TBM_SYNC create fence failed",
359 errno, strerror(errno));
361 struct _tbm_sync_fence *fence_handle =
362 calloc(1, sizeof(struct _tbm_sync_fence));
364 if (fence_handle == NULL) {
365 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
366 TBM_LOG_E("%s\n", "TBM_SYNC calloc failed");
369 fence_handle->fd = data.fence;
370 fence = fence_handle;
374 ret = TBM_SYNC_ERROR_INVALID_PARAMETER;
381 _tbm_sync_mutex_unlock();
387 tbm_sync_fence_destroy(tbm_sync_fence_h fence)
389 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
391 _tbm_sync_mutex_lock();
393 /* check the tbm_sync capability */
394 ret = _tbm_sync_check_capability();;
395 if (ret != TBM_SYNC_ERROR_NONE)
399 struct _tbm_sync_fence *fence_handle = fence;
401 if (fence_handle->fd != -1)
402 close(fence_handle->fd);
407 _tbm_sync_mutex_unlock();
413 tbm_sync_fence_wait(tbm_sync_fence_h fence, int timeout)
415 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
417 _tbm_sync_mutex_lock();
419 /* check the tbm_sync capability */
420 ret = _tbm_sync_check_capability();;
421 if (ret != TBM_SYNC_ERROR_NONE)
425 struct _tbm_sync_fence *fence_handle = fence;
428 if (ioctl(fence_handle->fd, SYNC_IOC_WAIT, &to) == -1) {
429 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
430 TBM_LOG_E("%s:%d(%s)\n", "TBM_SYNC fence wait failed", errno, strerror(errno));
433 ret = TBM_SYNC_ERROR_INVALID_PARAMETER;
437 _tbm_sync_mutex_unlock();
443 tbm_sync_fence_merge(tbm_sync_fence_h fence1, tbm_sync_fence_h fence2, const char *name, tbm_sync_error_e *error)
445 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
446 tbm_sync_fence_h fence = NULL;
448 _tbm_sync_mutex_lock();
450 /* check the tbm_sync capability */
451 ret = _tbm_sync_check_capability();;
452 if (ret != TBM_SYNC_ERROR_NONE)
455 if (fence1 && fence2) {
456 struct _tbm_sync_fence *fence_handle1 = fence1;
457 struct _tbm_sync_fence *fence_handle2 = fence2;
459 struct sync_merge_data {
465 data.fd2 = fence_handle2->fd;
466 strncpy(data.name, name ? name : "", 32);
467 data.name[31] = '\0';
469 if (ioctl(fence_handle1->fd, SYNC_IOC_MERGE, &data) == -1) {
470 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
471 TBM_LOG_E("%s:%d(%s)\n", "TBM_SYNC fence merge failed",
472 errno, strerror(errno));
474 struct _tbm_sync_fence *fence_handle =
475 calloc(1, sizeof(struct _tbm_sync_fence));
477 if (fence_handle == NULL) {
478 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
479 TBM_LOG_E("%s\n", "TBM_SYNC calloc failed");
482 fence_handle->fd = data.fence;
486 ret = TBM_SYNC_ERROR_INVALID_PARAMETER;
493 _tbm_sync_mutex_unlock();
499 tbm_sync_fence_get_count_val(tbm_sync_fence_h fence, tbm_sync_error_e *error)
501 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
502 unsigned int count_val = 0;
504 _tbm_sync_mutex_lock();
506 /* check the tbm_sync capability */
507 ret = _tbm_sync_check_capability();;
508 if (ret != TBM_SYNC_ERROR_NONE)
511 /* TODO: sync_fence_get_count_val */
517 _tbm_sync_mutex_unlock();
523 tbm_sync_fence_import(int fd, tbm_sync_error_e *error)
525 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
526 tbm_sync_fence_h fence = NULL;
528 _tbm_sync_mutex_lock();
530 /* check the tbm_sync capability */
531 ret = _tbm_sync_check_capability();;
532 if (ret != TBM_SYNC_ERROR_NONE)
536 ret = TBM_SYNC_ERROR_INVALID_PARAMETER;
538 struct _tbm_sync_fence *fence_handle =
539 calloc(1, sizeof(struct _tbm_sync_fence));
541 if (fence_handle == NULL) {
542 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
543 TBM_LOG_E("%s\n", "TBM_SYNC calloc failed");
545 fence_handle->fd = fd;
546 fence = fence_handle;
554 _tbm_sync_mutex_unlock();
560 tbm_sync_fence_export(tbm_sync_fence_h fence, tbm_sync_error_e *error)
562 tbm_sync_error_e ret = TBM_SYNC_ERROR_NONE;
565 _tbm_sync_mutex_lock();
567 /* check the tbm_sync capability */
568 ret = _tbm_sync_check_capability();;
569 if (ret != TBM_SYNC_ERROR_NONE)
573 struct _tbm_sync_fence *fence_handle = fence;
574 fd = dup(fence_handle->fd);
576 ret = TBM_SYNC_ERROR_INVALID_OPERATION;
577 TBM_LOG_E("%s:%d(%s)\n", "TBM_SYNC fence dup failed",
578 errno, strerror(errno));
581 ret = TBM_SYNC_ERROR_INVALID_PARAMETER;
588 _tbm_sync_mutex_unlock();