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