summaryrefslogtreecommitdiff
path: root/hwc2/common/base/HwcFenceControl.cpp (plain)
blob: 15c24b54242c75ed53a7678230025a2ed773e0f3
1/*
2// Copyright(c) 2016 Amlogic Corporation
3*/
4
5#include <sync/sync.h>
6#include <sw_sync.h>
7
8#include <HwcFenceControl.h>
9#include <unistd.h>
10#include <utils/Log.h>
11#include <HwcTrace.h>
12
13namespace android {
14namespace amlogic {
15
16const sp<HwcFenceControl> HwcFenceControl::NO_FENCE = sp<HwcFenceControl>(new HwcFenceControl);
17
18HwcFenceControl::HwcFenceControl() :
19 mFenceFd(-1) {
20}
21
22HwcFenceControl::HwcFenceControl(int32_t fenceFd) :
23 mFenceFd(fenceFd) {
24}
25
26HwcFenceControl::~HwcFenceControl() {
27 if (mFenceFd != -1) {
28 close(mFenceFd);
29 }
30}
31
32int32_t HwcFenceControl::createFenceTimeline() {
33 int32_t syncTimelineFd;
34
35 syncTimelineFd = sw_sync_timeline_create();
36 if (syncTimelineFd < 0) {
37 ETRACE("Stark, can't create sw_sync_timeline:");
38 return -1;
39 }
40
41 return syncTimelineFd;
42}
43
44int32_t HwcFenceControl::createFence(int32_t syncTimelineFd,
45 char* str, uint32_t val) {
46
47 int32_t fenceFd = sw_sync_fence_create(syncTimelineFd, str, val);
48 if (fenceFd < 0) {
49 ETRACE("can't create sync pt %d: %s", val, strerror(errno));
50 return -1;
51 }
52
53 return fenceFd;
54}
55
56status_t HwcFenceControl::syncTimelineInc(int32_t syncTimelineFd) {
57 status_t err;
58
59 err = sw_sync_timeline_inc(syncTimelineFd, 1);
60 if (err < 0) {
61 ETRACE("can't increment sync obj:");
62 return -1;
63 }
64 return err;
65}
66
67status_t HwcFenceControl::traceFenceInfo(int32_t fence) {
68 status_t err;
69 struct sync_fence_info_data *info;
70
71 err = sync_wait(fence, 10000);
72
73 if (err < 0) {
74 ITRACE("wait %d failed: %s\n", fence, strerror(errno));
75 } else {
76 ITRACE("wait %d done\n", fence);
77 }
78 info = sync_fence_info(fence);
79 if (info) {
80 struct sync_pt_info *pt_info = NULL;
81 ITRACE(" fence %s %d\n", info->name, info->status);
82
83 while ((pt_info = sync_pt_info(info, pt_info))) {
84 int ts_sec = pt_info->timestamp_ns / 1000000000LL;
85 int ts_usec = (pt_info->timestamp_ns % 1000000000LL) / 1000LL;
86 ITRACE(" pt %s %s %d %d.%06d", pt_info->obj_name,
87 pt_info->driver_name, pt_info->status,
88 ts_sec, ts_usec);
89 if (!strcmp(pt_info->driver_name, "sw_sync"))
90 ITRACE(" val=%d\n", *(uint32_t *)pt_info->driver_data);
91 else
92 ITRACE("\n");
93 }
94 sync_fence_info_free(info);
95 }
96
97 // closeFd( fence);
98 return err;
99}
100
101status_t HwcFenceControl::wait(int32_t fence, int32_t timeout) {
102 if (fence == -1) {
103 return NO_ERROR;
104 }
105 int32_t err = sync_wait(fence, timeout);
106 return err < 0 ? -errno : status_t(NO_ERROR);
107}
108
109status_t HwcFenceControl::waitForever(const char* logname) {
110 if (mFenceFd == -1) {
111 return NO_ERROR;
112 }
113 int32_t warningTimeout = 3000;
114 int32_t err = sync_wait(mFenceFd, warningTimeout);
115 if (err < 0 && errno == ETIME) {
116 ETRACE("%s: fence %d didn't signal in %u ms", logname, mFenceFd,
117 warningTimeout);
118 err = sync_wait(mFenceFd, TIMEOUT_NEVER);
119 }
120 return err < 0 ? -errno : status_t(NO_ERROR);
121}
122
123int32_t HwcFenceControl::merge(const String8& name, const int32_t& f1,
124 const int32_t& f2) {
125 int32_t result;
126 // Merge the two fences. In the case where one of the fences is not a
127 // valid fence (e.g. NO_FENCE) we merge the one valid fence with itself so
128 // that a new fence with the given name is created.
129 if (f1 != -1 && f2 != -1) {
130 result = sync_merge(name.string(), f1, f2);
131 } else if (f1 != -1) {
132 result = sync_merge(name.string(), f1, f1);
133 } else if (f2 != -1) {
134 result = sync_merge(name.string(), f2, f2);
135 } else {
136 return -1;
137 }
138 if (result == -1) {
139 status_t err = -errno;
140 ETRACE("merge: sync_merge(\"%s\", %d, %d) returned an error: %s (%d)",
141 name.string(), f1, f2,
142 strerror(-err), err);
143 return -1;
144 }
145 return result;
146}
147
148int32_t HwcFenceControl::dupFence(int32_t fence) {
149 if (-1 == fence) {
150 DTRACE("acquire fence already been signaled.");
151 return -1;
152 }
153
154 int32_t dupFence = ::dup(fence);
155 if (dupFence < 0) {
156 ETRACE("acquire fence dup failed! please check it immeditely!");
157 }
158
159 return dupFence;
160}
161
162} // namespace amlogic
163} // namespace android
164