blob: b8c40e95b8f0042d6b50a650c906cabd539df8fc [file] [log] [blame]
Yin-Chia Yeh248ed702017-01-23 17:27:26 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
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#define LOG_TAG "HandleImporter"
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080018#include "HandleImporter.h"
Steven Moreland4e7a3072017-04-06 12:15:23 -070019#include <log/log.h>
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080020
21namespace android {
22namespace hardware {
23namespace camera {
24namespace common {
25namespace V1_0 {
26namespace helper {
27
Shuzhen Wang915115e2019-05-10 12:07:14 -070028using MapperErrorV2 = android::hardware::graphics::mapper::V2_0::Error;
29using MapperErrorV3 = android::hardware::graphics::mapper::V3_0::Error;
30using IMapperV3 = android::hardware::graphics::mapper::V3_0::IMapper;
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080031
Yin-Chia Yeh519c1672017-04-21 14:59:31 -070032HandleImporter::HandleImporter() : mInitialized(false) {}
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080033
Yin-Chia Yeh519c1672017-04-21 14:59:31 -070034void HandleImporter::initializeLocked() {
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080035 if (mInitialized) {
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080036 return;
37 }
38
Shuzhen Wang915115e2019-05-10 12:07:14 -070039 mMapperV3 = IMapperV3::getService();
40 if (mMapperV3 != nullptr) {
41 mInitialized = true;
42 return;
43 }
44
45 mMapperV2 = IMapper::getService();
46 if (mMapperV2 == nullptr) {
Yin-Chia Yeh519c1672017-04-21 14:59:31 -070047 ALOGE("%s: cannnot acccess graphics mapper HAL!", __FUNCTION__);
48 return;
49 }
50
51 mInitialized = true;
52 return;
53}
54
55void HandleImporter::cleanup() {
Shuzhen Wang915115e2019-05-10 12:07:14 -070056 mMapperV3.clear();
57 mMapperV2.clear();
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080058 mInitialized = false;
59}
60
Shuzhen Wang915115e2019-05-10 12:07:14 -070061template<class M, class E>
62bool HandleImporter::importBufferInternal(const sp<M> mapper, buffer_handle_t& handle) {
63 E error;
64 buffer_handle_t importedHandle;
65 auto ret = mapper->importBuffer(
66 hidl_handle(handle),
67 [&](const auto& tmpError, const auto& tmpBufferHandle) {
68 error = tmpError;
69 importedHandle = static_cast<buffer_handle_t>(tmpBufferHandle);
70 });
71
72 if (!ret.isOk()) {
73 ALOGE("%s: mapper importBuffer failed: %s",
74 __FUNCTION__, ret.description().c_str());
75 return false;
76 }
77
78 if (error != E::NONE) {
79 return false;
80 }
81
82 handle = importedHandle;
83 return true;
84}
85
86template<class M, class E>
87YCbCrLayout HandleImporter::lockYCbCrInternal(const sp<M> mapper, buffer_handle_t& buf,
88 uint64_t cpuUsage, const IMapper::Rect& accessRegion) {
89 hidl_handle acquireFenceHandle;
90 auto buffer = const_cast<native_handle_t*>(buf);
91 YCbCrLayout layout = {};
92
93 typename M::Rect accessRegionCopy = {accessRegion.left, accessRegion.top,
94 accessRegion.width, accessRegion.height};
95 mapper->lockYCbCr(buffer, cpuUsage, accessRegionCopy, acquireFenceHandle,
96 [&](const auto& tmpError, const auto& tmpLayout) {
97 if (tmpError == E::NONE) {
98 // Member by member copy from different versions of YCbCrLayout.
99 layout.y = tmpLayout.y;
100 layout.cb = tmpLayout.cb;
101 layout.cr = tmpLayout.cr;
102 layout.yStride = tmpLayout.yStride;
103 layout.cStride = tmpLayout.cStride;
104 layout.chromaStep = tmpLayout.chromaStep;
105 } else {
106 ALOGE("%s: failed to lockYCbCr error %d!", __FUNCTION__, tmpError);
107 }
108 });
109 return layout;
110}
111
112template<class M, class E>
113int HandleImporter::unlockInternal(const sp<M> mapper, buffer_handle_t& buf) {
114 int releaseFence = -1;
115 auto buffer = const_cast<native_handle_t*>(buf);
116
117 mapper->unlock(
118 buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
119 if (tmpError == E::NONE) {
120 auto fenceHandle = tmpReleaseFence.getNativeHandle();
121 if (fenceHandle) {
122 if (fenceHandle->numInts != 0 || fenceHandle->numFds != 1) {
123 ALOGE("%s: bad release fence numInts %d numFds %d",
124 __FUNCTION__, fenceHandle->numInts, fenceHandle->numFds);
125 return;
126 }
127 releaseFence = dup(fenceHandle->data[0]);
128 if (releaseFence < 0) {
129 ALOGE("%s: bad release fence FD %d",
130 __FUNCTION__, releaseFence);
131 }
132 }
133 } else {
134 ALOGE("%s: failed to unlock error %d!", __FUNCTION__, tmpError);
135 }
136 });
137 return releaseFence;
138}
139
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800140// In IComposer, any buffer_handle_t is owned by the caller and we need to
141// make a clone for hwcomposer2. We also need to translate empty handle
142// to nullptr. This function does that, in-place.
143bool HandleImporter::importBuffer(buffer_handle_t& handle) {
144 if (!handle->numFds && !handle->numInts) {
145 handle = nullptr;
146 return true;
147 }
148
Yin-Chia Yeh519c1672017-04-21 14:59:31 -0700149 Mutex::Autolock lock(mLock);
150 if (!mInitialized) {
151 initializeLocked();
152 }
153
Shuzhen Wang915115e2019-05-10 12:07:14 -0700154 if (mMapperV3 != nullptr) {
155 return importBufferInternal<IMapperV3, MapperErrorV3>(mMapperV3, handle);
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800156 }
157
Shuzhen Wang915115e2019-05-10 12:07:14 -0700158 if (mMapperV2 != nullptr) {
159 return importBufferInternal<IMapper, MapperErrorV2>(mMapperV2, handle);
Yin-Chia Yeh519c1672017-04-21 14:59:31 -0700160 }
161
Shuzhen Wang915115e2019-05-10 12:07:14 -0700162 ALOGE("%s: mMapperV3 and mMapperV2 are both null!", __FUNCTION__);
163 return false;
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800164}
165
166void HandleImporter::freeBuffer(buffer_handle_t handle) {
167 if (!handle) {
168 return;
169 }
170
Yin-Chia Yeh519c1672017-04-21 14:59:31 -0700171 Mutex::Autolock lock(mLock);
Shuzhen Wang915115e2019-05-10 12:07:14 -0700172 if (mMapperV3 == nullptr && mMapperV2 == nullptr) {
173 ALOGE("%s: mMapperV3 and mMapperV2 are both null!", __FUNCTION__);
Yin-Chia Yeh519c1672017-04-21 14:59:31 -0700174 return;
175 }
176
Shuzhen Wang915115e2019-05-10 12:07:14 -0700177 if (mMapperV3 != nullptr) {
178 auto ret = mMapperV3->freeBuffer(const_cast<native_handle_t*>(handle));
179 if (!ret.isOk()) {
180 ALOGE("%s: mapper freeBuffer failed: %s",
181 __FUNCTION__, ret.description().c_str());
182 }
183 } else {
184 auto ret = mMapperV2->freeBuffer(const_cast<native_handle_t*>(handle));
185 if (!ret.isOk()) {
186 ALOGE("%s: mapper freeBuffer failed: %s",
187 __FUNCTION__, ret.description().c_str());
188 }
Yin-Chia Yeh519c1672017-04-21 14:59:31 -0700189 }
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800190}
191
Yin-Chia Yeh519c1672017-04-21 14:59:31 -0700192bool HandleImporter::importFence(const native_handle_t* handle, int& fd) const {
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800193 if (handle == nullptr || handle->numFds == 0) {
194 fd = -1;
195 } else if (handle->numFds == 1) {
196 fd = dup(handle->data[0]);
197 if (fd < 0) {
198 ALOGE("failed to dup fence fd %d", handle->data[0]);
199 return false;
200 }
201 } else {
202 ALOGE("invalid fence handle with %d file descriptors",
203 handle->numFds);
204 return false;
205 }
206
207 return true;
208}
209
Yin-Chia Yeh519c1672017-04-21 14:59:31 -0700210void HandleImporter::closeFence(int fd) const {
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800211 if (fd >= 0) {
212 close(fd);
213 }
214}
215
Yuriy Romanenkod0bd4f12018-01-19 16:00:00 -0800216void* HandleImporter::lock(
217 buffer_handle_t& buf, uint64_t cpuUsage, size_t size) {
218 Mutex::Autolock lock(mLock);
219 void *ret = 0;
Yuriy Romanenkod0bd4f12018-01-19 16:00:00 -0800220
221 if (!mInitialized) {
222 initializeLocked();
223 }
224
Shuzhen Wang915115e2019-05-10 12:07:14 -0700225 if (mMapperV3 == nullptr && mMapperV2 == nullptr) {
226 ALOGE("%s: mMapperV3 and mMapperV2 are both null!", __FUNCTION__);
Yuriy Romanenkod0bd4f12018-01-19 16:00:00 -0800227 return ret;
228 }
229
230 hidl_handle acquireFenceHandle;
231 auto buffer = const_cast<native_handle_t*>(buf);
Shuzhen Wang915115e2019-05-10 12:07:14 -0700232 if (mMapperV3 != nullptr) {
233 IMapperV3::Rect accessRegion { 0, 0, static_cast<int>(size), 1 };
234 // No need to use bytesPerPixel and bytesPerStride because we are using
235 // an 1-D buffer and accressRegion.
236 mMapperV3->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
237 [&](const auto& tmpError, const auto& tmpPtr, const auto& /*bytesPerPixel*/,
238 const auto& /*bytesPerStride*/) {
239 if (tmpError == MapperErrorV3::NONE) {
240 ret = tmpPtr;
241 } else {
242 ALOGE("%s: failed to lock error %d!",
243 __FUNCTION__, tmpError);
244 }
245 });
246 } else {
247 IMapper::Rect accessRegion { 0, 0, static_cast<int>(size), 1 };
248 mMapperV2->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
249 [&](const auto& tmpError, const auto& tmpPtr) {
250 if (tmpError == MapperErrorV2::NONE) {
251 ret = tmpPtr;
252 } else {
253 ALOGE("%s: failed to lock error %d!",
254 __FUNCTION__, tmpError);
255 }
256 });
257 }
Yuriy Romanenkod0bd4f12018-01-19 16:00:00 -0800258
259 ALOGV("%s: ptr %p size: %zu", __FUNCTION__, ret, size);
260 return ret;
261}
262
Yin-Chia Yeh19030592017-10-19 17:30:11 -0700263YCbCrLayout HandleImporter::lockYCbCr(
264 buffer_handle_t& buf, uint64_t cpuUsage,
265 const IMapper::Rect& accessRegion) {
266 Mutex::Autolock lock(mLock);
Yin-Chia Yeh19030592017-10-19 17:30:11 -0700267
268 if (!mInitialized) {
269 initializeLocked();
270 }
271
Shuzhen Wang915115e2019-05-10 12:07:14 -0700272 if (mMapperV3 != nullptr) {
273 return lockYCbCrInternal<IMapperV3, MapperErrorV3>(
274 mMapperV3, buf, cpuUsage, accessRegion);
Yin-Chia Yeh19030592017-10-19 17:30:11 -0700275 }
276
Shuzhen Wang915115e2019-05-10 12:07:14 -0700277 if (mMapperV2 != nullptr) {
278 return lockYCbCrInternal<IMapper, MapperErrorV2>(
279 mMapperV2, buf, cpuUsage, accessRegion);
280 }
Yin-Chia Yeh19030592017-10-19 17:30:11 -0700281
Shuzhen Wang915115e2019-05-10 12:07:14 -0700282 ALOGE("%s: mMapperV3 and mMapperV2 are both null!", __FUNCTION__);
283 return {};
Yin-Chia Yeh19030592017-10-19 17:30:11 -0700284}
285
286int HandleImporter::unlock(buffer_handle_t& buf) {
Shuzhen Wang915115e2019-05-10 12:07:14 -0700287 if (mMapperV3 != nullptr) {
288 return unlockInternal<IMapperV3, MapperErrorV3>(mMapperV3, buf);
289 }
290 if (mMapperV2 != nullptr) {
291 return unlockInternal<IMapper, MapperErrorV2>(mMapperV2, buf);
292 }
Yin-Chia Yeh19030592017-10-19 17:30:11 -0700293
Shuzhen Wang915115e2019-05-10 12:07:14 -0700294 ALOGE("%s: mMapperV3 and mMapperV2 are both null!", __FUNCTION__);
295 return -1;
Yin-Chia Yeh19030592017-10-19 17:30:11 -0700296}
297
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800298} // namespace helper
299} // namespace V1_0
300} // namespace common
301} // namespace camera
302} // namespace hardware
303} // namespace android