blob: 40cb4e0dae9aef830a644dc2d58847830cc97c12 [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;
Marissa Walla51eb932019-06-21 09:13:35 -070030using MapperErrorV4 = android::hardware::graphics::mapper::V4_0::Error;
Shuzhen Wang915115e2019-05-10 12:07:14 -070031using IMapperV3 = android::hardware::graphics::mapper::V3_0::IMapper;
Marissa Walla51eb932019-06-21 09:13:35 -070032using IMapperV4 = android::hardware::graphics::mapper::V4_0::IMapper;
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080033
Yin-Chia Yeh519c1672017-04-21 14:59:31 -070034HandleImporter::HandleImporter() : mInitialized(false) {}
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080035
Yin-Chia Yeh519c1672017-04-21 14:59:31 -070036void HandleImporter::initializeLocked() {
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080037 if (mInitialized) {
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080038 return;
39 }
40
Marissa Walla51eb932019-06-21 09:13:35 -070041 mMapperV4 = IMapperV4::getService();
42 if (mMapperV4 != nullptr) {
43 mInitialized = true;
44 return;
45 }
46
Shuzhen Wang915115e2019-05-10 12:07:14 -070047 mMapperV3 = IMapperV3::getService();
48 if (mMapperV3 != nullptr) {
49 mInitialized = true;
50 return;
51 }
52
53 mMapperV2 = IMapper::getService();
54 if (mMapperV2 == nullptr) {
Yin-Chia Yeh519c1672017-04-21 14:59:31 -070055 ALOGE("%s: cannnot acccess graphics mapper HAL!", __FUNCTION__);
56 return;
57 }
58
59 mInitialized = true;
60 return;
61}
62
63void HandleImporter::cleanup() {
Marissa Walla51eb932019-06-21 09:13:35 -070064 mMapperV4.clear();
Shuzhen Wang915115e2019-05-10 12:07:14 -070065 mMapperV3.clear();
66 mMapperV2.clear();
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080067 mInitialized = false;
68}
69
Shuzhen Wang915115e2019-05-10 12:07:14 -070070template<class M, class E>
71bool HandleImporter::importBufferInternal(const sp<M> mapper, buffer_handle_t& handle) {
72 E error;
73 buffer_handle_t importedHandle;
74 auto ret = mapper->importBuffer(
75 hidl_handle(handle),
76 [&](const auto& tmpError, const auto& tmpBufferHandle) {
77 error = tmpError;
78 importedHandle = static_cast<buffer_handle_t>(tmpBufferHandle);
79 });
80
81 if (!ret.isOk()) {
82 ALOGE("%s: mapper importBuffer failed: %s",
83 __FUNCTION__, ret.description().c_str());
84 return false;
85 }
86
87 if (error != E::NONE) {
88 return false;
89 }
90
91 handle = importedHandle;
92 return true;
93}
94
95template<class M, class E>
96YCbCrLayout HandleImporter::lockYCbCrInternal(const sp<M> mapper, buffer_handle_t& buf,
97 uint64_t cpuUsage, const IMapper::Rect& accessRegion) {
98 hidl_handle acquireFenceHandle;
99 auto buffer = const_cast<native_handle_t*>(buf);
100 YCbCrLayout layout = {};
101
102 typename M::Rect accessRegionCopy = {accessRegion.left, accessRegion.top,
103 accessRegion.width, accessRegion.height};
104 mapper->lockYCbCr(buffer, cpuUsage, accessRegionCopy, acquireFenceHandle,
105 [&](const auto& tmpError, const auto& tmpLayout) {
106 if (tmpError == E::NONE) {
107 // Member by member copy from different versions of YCbCrLayout.
108 layout.y = tmpLayout.y;
109 layout.cb = tmpLayout.cb;
110 layout.cr = tmpLayout.cr;
111 layout.yStride = tmpLayout.yStride;
112 layout.cStride = tmpLayout.cStride;
113 layout.chromaStep = tmpLayout.chromaStep;
114 } else {
115 ALOGE("%s: failed to lockYCbCr error %d!", __FUNCTION__, tmpError);
116 }
117 });
118 return layout;
119}
120
121template<class M, class E>
122int HandleImporter::unlockInternal(const sp<M> mapper, buffer_handle_t& buf) {
123 int releaseFence = -1;
124 auto buffer = const_cast<native_handle_t*>(buf);
125
126 mapper->unlock(
127 buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
128 if (tmpError == E::NONE) {
129 auto fenceHandle = tmpReleaseFence.getNativeHandle();
130 if (fenceHandle) {
131 if (fenceHandle->numInts != 0 || fenceHandle->numFds != 1) {
132 ALOGE("%s: bad release fence numInts %d numFds %d",
133 __FUNCTION__, fenceHandle->numInts, fenceHandle->numFds);
134 return;
135 }
136 releaseFence = dup(fenceHandle->data[0]);
137 if (releaseFence < 0) {
138 ALOGE("%s: bad release fence FD %d",
139 __FUNCTION__, releaseFence);
140 }
141 }
142 } else {
143 ALOGE("%s: failed to unlock error %d!", __FUNCTION__, tmpError);
144 }
145 });
146 return releaseFence;
147}
148
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800149// In IComposer, any buffer_handle_t is owned by the caller and we need to
150// make a clone for hwcomposer2. We also need to translate empty handle
151// to nullptr. This function does that, in-place.
152bool HandleImporter::importBuffer(buffer_handle_t& handle) {
153 if (!handle->numFds && !handle->numInts) {
154 handle = nullptr;
155 return true;
156 }
157
Yin-Chia Yeh519c1672017-04-21 14:59:31 -0700158 Mutex::Autolock lock(mLock);
159 if (!mInitialized) {
160 initializeLocked();
161 }
162
Marissa Walla51eb932019-06-21 09:13:35 -0700163 if (mMapperV4 != nullptr) {
164 return importBufferInternal<IMapperV4, MapperErrorV4>(mMapperV4, handle);
165 }
166
Shuzhen Wang915115e2019-05-10 12:07:14 -0700167 if (mMapperV3 != nullptr) {
168 return importBufferInternal<IMapperV3, MapperErrorV3>(mMapperV3, handle);
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800169 }
170
Shuzhen Wang915115e2019-05-10 12:07:14 -0700171 if (mMapperV2 != nullptr) {
172 return importBufferInternal<IMapper, MapperErrorV2>(mMapperV2, handle);
Yin-Chia Yeh519c1672017-04-21 14:59:31 -0700173 }
174
Marissa Walla51eb932019-06-21 09:13:35 -0700175 ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
Shuzhen Wang915115e2019-05-10 12:07:14 -0700176 return false;
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800177}
178
179void HandleImporter::freeBuffer(buffer_handle_t handle) {
180 if (!handle) {
181 return;
182 }
183
Yin-Chia Yeh519c1672017-04-21 14:59:31 -0700184 Mutex::Autolock lock(mLock);
Yin-Chia Yeh97978fb2020-01-25 18:15:00 -0800185 if (!mInitialized) {
186 initializeLocked();
Yin-Chia Yeh519c1672017-04-21 14:59:31 -0700187 }
188
Marissa Walla51eb932019-06-21 09:13:35 -0700189 if (mMapperV4 != nullptr) {
190 auto ret = mMapperV4->freeBuffer(const_cast<native_handle_t*>(handle));
191 if (!ret.isOk()) {
192 ALOGE("%s: mapper freeBuffer failed: %s", __FUNCTION__, ret.description().c_str());
193 }
194 } else if (mMapperV3 != nullptr) {
Shuzhen Wang915115e2019-05-10 12:07:14 -0700195 auto ret = mMapperV3->freeBuffer(const_cast<native_handle_t*>(handle));
196 if (!ret.isOk()) {
197 ALOGE("%s: mapper freeBuffer failed: %s",
198 __FUNCTION__, ret.description().c_str());
199 }
200 } else {
201 auto ret = mMapperV2->freeBuffer(const_cast<native_handle_t*>(handle));
202 if (!ret.isOk()) {
203 ALOGE("%s: mapper freeBuffer failed: %s",
204 __FUNCTION__, ret.description().c_str());
205 }
Yin-Chia Yeh519c1672017-04-21 14:59:31 -0700206 }
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800207}
208
Yin-Chia Yeh519c1672017-04-21 14:59:31 -0700209bool HandleImporter::importFence(const native_handle_t* handle, int& fd) const {
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800210 if (handle == nullptr || handle->numFds == 0) {
211 fd = -1;
212 } else if (handle->numFds == 1) {
213 fd = dup(handle->data[0]);
214 if (fd < 0) {
215 ALOGE("failed to dup fence fd %d", handle->data[0]);
216 return false;
217 }
218 } else {
219 ALOGE("invalid fence handle with %d file descriptors",
220 handle->numFds);
221 return false;
222 }
223
224 return true;
225}
226
Yin-Chia Yeh519c1672017-04-21 14:59:31 -0700227void HandleImporter::closeFence(int fd) const {
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800228 if (fd >= 0) {
229 close(fd);
230 }
231}
232
Yuriy Romanenkod0bd4f12018-01-19 16:00:00 -0800233void* HandleImporter::lock(
234 buffer_handle_t& buf, uint64_t cpuUsage, size_t size) {
Jason Macnakf2c9ed12020-04-20 14:43:58 -0700235 IMapper::Rect accessRegion{0, 0, static_cast<int>(size), 1};
236 return lock(buf, cpuUsage, accessRegion);
237}
238
239void* HandleImporter::lock(buffer_handle_t& buf, uint64_t cpuUsage,
240 const IMapper::Rect& accessRegion) {
Yuriy Romanenkod0bd4f12018-01-19 16:00:00 -0800241 Mutex::Autolock lock(mLock);
Yuriy Romanenkod0bd4f12018-01-19 16:00:00 -0800242
243 if (!mInitialized) {
244 initializeLocked();
245 }
246
Jason Macnakf2c9ed12020-04-20 14:43:58 -0700247 void* ret = nullptr;
248
Marissa Walla51eb932019-06-21 09:13:35 -0700249 if (mMapperV4 == nullptr && mMapperV3 == nullptr && mMapperV2 == nullptr) {
250 ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
Yuriy Romanenkod0bd4f12018-01-19 16:00:00 -0800251 return ret;
252 }
253
254 hidl_handle acquireFenceHandle;
255 auto buffer = const_cast<native_handle_t*>(buf);
Marissa Walla51eb932019-06-21 09:13:35 -0700256 if (mMapperV4 != nullptr) {
Jason Macnakf2c9ed12020-04-20 14:43:58 -0700257 IMapperV4::Rect accessRegionV4{accessRegion.left, accessRegion.top, accessRegion.width,
258 accessRegion.height};
259
260 mMapperV4->lock(buffer, cpuUsage, accessRegionV4, acquireFenceHandle,
Marissa Wall9c5ebfc2019-11-05 14:59:27 -0800261 [&](const auto& tmpError, const auto& tmpPtr) {
Marissa Walla51eb932019-06-21 09:13:35 -0700262 if (tmpError == MapperErrorV4::NONE) {
263 ret = tmpPtr;
264 } else {
265 ALOGE("%s: failed to lock error %d!", __FUNCTION__, tmpError);
266 }
267 });
268 } else if (mMapperV3 != nullptr) {
Jason Macnakf2c9ed12020-04-20 14:43:58 -0700269 IMapperV3::Rect accessRegionV3{accessRegion.left, accessRegion.top, accessRegion.width,
270 accessRegion.height};
271
272 mMapperV3->lock(buffer, cpuUsage, accessRegionV3, acquireFenceHandle,
273 [&](const auto& tmpError, const auto& tmpPtr, const auto& /*bytesPerPixel*/,
274 const auto& /*bytesPerStride*/) {
275 if (tmpError == MapperErrorV3::NONE) {
276 ret = tmpPtr;
277 } else {
278 ALOGE("%s: failed to lock error %d!", __FUNCTION__, tmpError);
279 }
280 });
Shuzhen Wang915115e2019-05-10 12:07:14 -0700281 } else {
Shuzhen Wang915115e2019-05-10 12:07:14 -0700282 mMapperV2->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
283 [&](const auto& tmpError, const auto& tmpPtr) {
284 if (tmpError == MapperErrorV2::NONE) {
285 ret = tmpPtr;
286 } else {
Jason Macnakf2c9ed12020-04-20 14:43:58 -0700287 ALOGE("%s: failed to lock error %d!", __FUNCTION__, tmpError);
Shuzhen Wang915115e2019-05-10 12:07:14 -0700288 }
289 });
290 }
Yuriy Romanenkod0bd4f12018-01-19 16:00:00 -0800291
Jason Macnakf2c9ed12020-04-20 14:43:58 -0700292 ALOGV("%s: ptr %p accessRegion.top: %d accessRegion.left: %d accessRegion.width: %d "
293 "accessRegion.height: %d",
294 __FUNCTION__, ret, accessRegion.top, accessRegion.left, accessRegion.width,
295 accessRegion.height);
Yuriy Romanenkod0bd4f12018-01-19 16:00:00 -0800296 return ret;
297}
298
Yin-Chia Yeh19030592017-10-19 17:30:11 -0700299YCbCrLayout HandleImporter::lockYCbCr(
300 buffer_handle_t& buf, uint64_t cpuUsage,
301 const IMapper::Rect& accessRegion) {
302 Mutex::Autolock lock(mLock);
Yin-Chia Yeh19030592017-10-19 17:30:11 -0700303
304 if (!mInitialized) {
305 initializeLocked();
306 }
307
Marissa Walla51eb932019-06-21 09:13:35 -0700308 if (mMapperV4 != nullptr) {
Marissa Wall9c5ebfc2019-11-05 14:59:27 -0800309 // No device currently supports IMapper 4.0 so it is safe to just return an error code here.
310 //
311 // This will be supported by a combination of lock and BufferMetadata getters. We are going
312 // to refactor all the IAllocator/IMapper versioning code into a shared library. We will
313 // then add the IMapper 4.0 lockYCbCr support then.
314 ALOGE("%s: MapperV4 doesn't support lockYCbCr directly!", __FUNCTION__);
315 return {};
Marissa Walla51eb932019-06-21 09:13:35 -0700316 }
317
Shuzhen Wang915115e2019-05-10 12:07:14 -0700318 if (mMapperV3 != nullptr) {
319 return lockYCbCrInternal<IMapperV3, MapperErrorV3>(
320 mMapperV3, buf, cpuUsage, accessRegion);
Yin-Chia Yeh19030592017-10-19 17:30:11 -0700321 }
322
Shuzhen Wang915115e2019-05-10 12:07:14 -0700323 if (mMapperV2 != nullptr) {
324 return lockYCbCrInternal<IMapper, MapperErrorV2>(
325 mMapperV2, buf, cpuUsage, accessRegion);
326 }
Yin-Chia Yeh19030592017-10-19 17:30:11 -0700327
Marissa Walla51eb932019-06-21 09:13:35 -0700328 ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
Shuzhen Wang915115e2019-05-10 12:07:14 -0700329 return {};
Yin-Chia Yeh19030592017-10-19 17:30:11 -0700330}
331
332int HandleImporter::unlock(buffer_handle_t& buf) {
Marissa Walla51eb932019-06-21 09:13:35 -0700333 if (mMapperV4 != nullptr) {
334 return unlockInternal<IMapperV4, MapperErrorV4>(mMapperV4, buf);
335 }
Shuzhen Wang915115e2019-05-10 12:07:14 -0700336 if (mMapperV3 != nullptr) {
337 return unlockInternal<IMapperV3, MapperErrorV3>(mMapperV3, buf);
338 }
339 if (mMapperV2 != nullptr) {
340 return unlockInternal<IMapper, MapperErrorV2>(mMapperV2, buf);
341 }
Yin-Chia Yeh19030592017-10-19 17:30:11 -0700342
Marissa Walla51eb932019-06-21 09:13:35 -0700343 ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
Shuzhen Wang915115e2019-05-10 12:07:14 -0700344 return -1;
Yin-Chia Yeh19030592017-10-19 17:30:11 -0700345}
346
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800347} // namespace helper
348} // namespace V1_0
349} // namespace common
350} // namespace camera
351} // namespace hardware
352} // namespace android