blob: 3637936cf4fa9b2564d5eb3b419f85f9bc34c557 [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#include "include/private/dvr/sync_util.h"
2
3#include <errno.h>
4#include <sys/ioctl.h>
5
6// TODO: http://b/33239638 Move GetSyncFenceInfo() into upstream libsync instead
7// of duplicating functionality and structure definitions from it.
8struct sync_fence_info_data {
9 uint32_t len;
10 char name[32];
11 int32_t status;
12 uint8_t pt_info[0];
13};
14
15struct sync_pt_info {
16 uint32_t len;
17 char obj_name[32];
18 char driver_name[32];
19 int32_t status;
20 uint64_t timestamp_ns;
21 uint8_t driver_data[0];
22};
23
24#define SYNC_IOC_MAGIC '>'
25#define SYNC_IOC_WAIT _IOW(SYNC_IOC_MAGIC, 0, __s32)
26#define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 1, struct sync_merge_data)
27#define SYNC_IOC_FENCE_INFO _IOWR(SYNC_IOC_MAGIC, 2, struct sync_fence_info_data)
28
29namespace android {
30namespace dvr {
31
32namespace {
33
34// This is copied from sync_pt_info() in libsync/sync.c. It's been cleaned up to
35// remove lint warnings.
36sync_pt_info* GetSyncPtInfo(sync_fence_info_data* info, sync_pt_info* itr) {
37 if (itr == nullptr)
38 itr = reinterpret_cast<sync_pt_info*>(info->pt_info);
39 else
40 itr = reinterpret_cast<sync_pt_info*>(reinterpret_cast<uint8_t*>(itr) +
41 itr->len);
42
43 if (reinterpret_cast<uint8_t*>(itr) - reinterpret_cast<uint8_t*>(info) >=
44 static_cast<int>(info->len))
45 return nullptr;
46
47 return itr;
48}
49
50} // namespace
51
52int GetSyncFenceInfo(int fence_fd, FenceInfoBuffer* buffer) {
53 // If the implementation of sync_fence_info() in libsync/sync.c changes, this
54 // function should be changed to match.
55 if (buffer == nullptr) {
56 errno = EINVAL;
57 return -1;
58 }
59
60 sync_fence_info_data* fence_info =
61 reinterpret_cast<sync_fence_info_data*>(buffer);
62 fence_info->len = kFenceInfoBufferSize;
63 return ioctl(fence_fd, SYNC_IOC_FENCE_INFO, fence_info);
64}
65
66int GetFenceSignaledTimestamp(int fence_fd, FenceInfoBuffer* buffer,
67 int64_t* timestamp) {
68 int result = GetSyncFenceInfo(fence_fd, buffer);
69 if (result < 0)
70 return result;
71
72 sync_fence_info_data* fence_info =
73 reinterpret_cast<sync_fence_info_data*>(buffer);
74 struct sync_pt_info* pt_info = nullptr;
75 while ((pt_info = GetSyncPtInfo(fence_info, pt_info)) != nullptr) {
76 if (pt_info->status == 1) {
77 *timestamp = pt_info->timestamp_ns;
78 return 0;
79 }
80 }
81
82 errno = EAGAIN;
83 return -1;
84}
85
86} // namespace dvr
87} // namespace android