blob: c6c9834eaf754fbb9ac94438bb52de9f64939857 [file] [log] [blame]
Marissa Wall65341642019-06-20 13:21:06 -07001/*
2 * Copyright 2019 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
Alec Mouri38ccfd72022-05-16 20:20:28 +000017#include <aidlcommonsupport/NativeHandle.h>
Alec Mouri18339992022-04-04 21:53:57 +000018#include <android-base/properties.h>
Alec Mouri38ccfd72022-05-16 20:20:28 +000019#include <android/binder_manager.h>
Marissa Wall88d87fa2019-11-05 14:57:51 -080020#include <gralloctypes/Gralloc4.h>
Marissa Wall65341642019-06-20 13:21:06 -070021#include <mapper-vts/4.0/MapperVts.h>
22
Marissa Wall65341642019-06-20 13:21:06 -070023namespace android {
24namespace hardware {
25namespace graphics {
26namespace mapper {
27namespace V4_0 {
28namespace vts {
29
ramindanib2b747f2022-06-04 00:16:44 +000030Gralloc::Gralloc(const std::string& aidlAllocatorServiceName,
31 const std::string& hidlAllocatorServiceName, const std::string& mapperServiceName,
Marissa Wall65341642019-06-20 13:21:06 -070032 bool errOnFailure) {
33 if (errOnFailure) {
ramindanib2b747f2022-06-04 00:16:44 +000034 init(aidlAllocatorServiceName, hidlAllocatorServiceName, mapperServiceName);
Marissa Wall65341642019-06-20 13:21:06 -070035 } else {
ramindanib2b747f2022-06-04 00:16:44 +000036 initNoErr(aidlAllocatorServiceName, hidlAllocatorServiceName, mapperServiceName);
Marissa Wall65341642019-06-20 13:21:06 -070037 }
38}
39
ramindanib2b747f2022-06-04 00:16:44 +000040void Gralloc::init(const std::string& aidlAllocatorServiceName,
41 const std::string& hidlAllocatorServiceName,
42 const std::string& mapperServiceName) {
Alec Mouri38ccfd72022-05-16 20:20:28 +000043 mAidlAllocator = aidl::android::hardware::graphics::allocator::IAllocator::fromBinder(
ramindanib2b747f2022-06-04 00:16:44 +000044 ndk::SpAIBinder(AServiceManager_checkService(aidlAllocatorServiceName.c_str())));
Alec Mouri38ccfd72022-05-16 20:20:28 +000045
46 if (mAidlAllocator == nullptr) {
ramindanib2b747f2022-06-04 00:16:44 +000047 mHidlAllocator = IAllocator::getService(hidlAllocatorServiceName);
Alec Mouri38ccfd72022-05-16 20:20:28 +000048 }
49 ASSERT_TRUE(nullptr != mAidlAllocator || mHidlAllocator != nullptr)
50 << "failed to get allocator service";
Marissa Wall65341642019-06-20 13:21:06 -070051
Dan Shi46245c52019-12-06 16:12:53 -080052 mMapper = IMapper::getService(mapperServiceName);
Marissa Wall65341642019-06-20 13:21:06 -070053 ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
54 ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
55}
56
ramindanib2b747f2022-06-04 00:16:44 +000057void Gralloc::initNoErr(const std::string& aidlAllocatorServiceName,
58 const std::string& hidlAllocatorServiceName,
Marissa Wall65341642019-06-20 13:21:06 -070059 const std::string& mapperServiceName) {
Alec Mouri38ccfd72022-05-16 20:20:28 +000060 mAidlAllocator = aidl::android::hardware::graphics::allocator::IAllocator::fromBinder(
ramindanib2b747f2022-06-04 00:16:44 +000061 ndk::SpAIBinder(AServiceManager_checkService(aidlAllocatorServiceName.c_str())));
Alec Mouri38ccfd72022-05-16 20:20:28 +000062
63 if (mAidlAllocator == nullptr) {
ramindanib2b747f2022-06-04 00:16:44 +000064 mHidlAllocator = IAllocator::getService(hidlAllocatorServiceName);
Alec Mouri38ccfd72022-05-16 20:20:28 +000065 }
Marissa Wall65341642019-06-20 13:21:06 -070066
Dan Shi46245c52019-12-06 16:12:53 -080067 mMapper = IMapper::getService(mapperServiceName);
Marissa Wall65341642019-06-20 13:21:06 -070068 if (mMapper.get()) {
69 ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
70 }
71}
72
73Gralloc::~Gralloc() {
74 for (auto bufferHandle : mClonedBuffers) {
75 auto buffer = const_cast<native_handle_t*>(bufferHandle);
76 native_handle_close(buffer);
77 native_handle_delete(buffer);
78 }
79 mClonedBuffers.clear();
80
81 for (auto bufferHandle : mImportedBuffers) {
82 auto buffer = const_cast<native_handle_t*>(bufferHandle);
83 EXPECT_EQ(Error::NONE, mMapper->freeBuffer(buffer)) << "failed to free buffer " << buffer;
84 }
85 mImportedBuffers.clear();
86}
87
Yichi Chenc6394ff2020-05-12 08:58:08 +080088const native_handle_t* Gralloc::cloneBuffer(const hidl_handle& rawHandle,
89 enum Tolerance /*tolerance*/) {
Marissa Wall65341642019-06-20 13:21:06 -070090 const native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle());
91 EXPECT_NE(nullptr, bufferHandle);
92
93 if (bufferHandle) {
94 mClonedBuffers.insert(bufferHandle);
95 }
96
97 return bufferHandle;
98}
99
100std::vector<const native_handle_t*> Gralloc::allocate(const BufferDescriptor& descriptor,
101 uint32_t count, bool import,
Yichi Chenc6394ff2020-05-12 08:58:08 +0800102 enum Tolerance tolerance,
103 uint32_t* outStride) {
Marissa Wall65341642019-06-20 13:21:06 -0700104 std::vector<const native_handle_t*> bufferHandles;
105 bufferHandles.reserve(count);
Marissa Wall65341642019-06-20 13:21:06 -0700106
Alec Mouri38ccfd72022-05-16 20:20:28 +0000107 auto callback = [&](Error error, uint32_t stride,
108 const hidl_vec<hidl_handle>& buffers) -> void {
109 if (canTolerate(tolerance, error)) {
110 return;
111 }
Marissa Wall65341642019-06-20 13:21:06 -0700112
Alec Mouri38ccfd72022-05-16 20:20:28 +0000113 if (error != Error::NONE) {
114 if (base::GetIntProperty("ro.vendor.build.version.sdk", 0, 0, INT_MAX) < 33) {
115 GTEST_SKIP() << "Old vendor grallocs may not support P010";
116 } else {
117 GTEST_FAIL() << "failed to allocate buffers";
118 }
119 }
120 ASSERT_EQ(count, buffers.size()) << "invalid buffer array";
Yichi Chenc6394ff2020-05-12 08:58:08 +0800121
Alec Mouri38ccfd72022-05-16 20:20:28 +0000122 for (uint32_t i = 0; i < count; i++) {
123 const native_handle_t* bufferHandle = nullptr;
124 if (import) {
125 ASSERT_NO_FATAL_FAILURE(bufferHandle = importBuffer(buffers[i], tolerance));
126 } else {
127 ASSERT_NO_FATAL_FAILURE(bufferHandle = cloneBuffer(buffers[i], tolerance));
128 }
129 if (bufferHandle) {
130 bufferHandles.push_back(bufferHandle);
131 }
132 }
133
134 if (outStride) {
135 *outStride = stride;
136 }
137 };
138
139 rawAllocate(descriptor, count, callback);
Marissa Wall65341642019-06-20 13:21:06 -0700140
141 if (::testing::Test::HasFatalFailure()) {
142 bufferHandles.clear();
143 }
144
145 return bufferHandles;
146}
147
148const native_handle_t* Gralloc::allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
Yichi Chenc6394ff2020-05-12 08:58:08 +0800149 bool import, enum Tolerance tolerance,
150 uint32_t* outStride) {
Marissa Wall65341642019-06-20 13:21:06 -0700151 BufferDescriptor descriptor = createDescriptor(descriptorInfo);
152 if (::testing::Test::HasFatalFailure()) {
153 return nullptr;
154 }
155
Yichi Chenc6394ff2020-05-12 08:58:08 +0800156 auto buffers = allocate(descriptor, 1, import, tolerance, outStride);
Alec Mouri18339992022-04-04 21:53:57 +0000157 if (::testing::Test::HasFatalFailure() || ::testing::Test::IsSkipped() || buffers.size() != 1) {
Marissa Wall88d87fa2019-11-05 14:57:51 -0800158 return nullptr;
159 }
Marissa Wall65341642019-06-20 13:21:06 -0700160 return buffers[0];
161}
162
Alec Mouri38ccfd72022-05-16 20:20:28 +0000163void Gralloc::rawAllocate(
164 const BufferDescriptor& descriptor, uint32_t count,
165 std::function<void(Error, uint32_t, const hidl_vec<hidl_handle>&)> callback) {
166 if (mAidlAllocator) {
167 aidl::android::hardware::graphics::allocator::AllocationResult result;
168 auto status = mAidlAllocator->allocate(descriptor, count, &result);
169 const Error error = toHidlError(status);
170 std::vector<hidl_handle> handles;
171 for (const auto& aidlHandle : result.buffers) {
172 handles.push_back(hidl_handle(makeFromAidl(aidlHandle)));
173 }
174 callback(error, result.stride, handles);
175 } else {
176 mHidlAllocator->allocate(descriptor, count, callback);
177 }
178}
179
Marissa Wall65341642019-06-20 13:21:06 -0700180sp<IMapper> Gralloc::getMapper() const {
181 return mMapper;
182}
183
184BufferDescriptor Gralloc::createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo) {
185 BufferDescriptor descriptor;
186 mMapper->createDescriptor(descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) {
187 ASSERT_EQ(Error::NONE, tmpError) << "failed to create descriptor";
188 descriptor = tmpDescriptor;
189 });
190
191 return descriptor;
192}
193
Yichi Chenc6394ff2020-05-12 08:58:08 +0800194const native_handle_t* Gralloc::importBuffer(const hidl_handle& rawHandle,
195 enum Tolerance tolerance) {
Marissa Wall65341642019-06-20 13:21:06 -0700196 const native_handle_t* bufferHandle = nullptr;
197 mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
Yichi Chenc6394ff2020-05-12 08:58:08 +0800198 if (!canTolerate(tolerance, tmpError)) {
199 ASSERT_EQ(Error::NONE, tmpError)
200 << "failed to import buffer %p" << rawHandle.getNativeHandle();
201 }
Marissa Wall65341642019-06-20 13:21:06 -0700202 bufferHandle = static_cast<const native_handle_t*>(tmpBuffer);
203 });
204
205 if (bufferHandle) {
206 mImportedBuffers.insert(bufferHandle);
207 }
208
209 return bufferHandle;
210}
211
212void Gralloc::freeBuffer(const native_handle_t* bufferHandle) {
Marissa Wall88d87fa2019-11-05 14:57:51 -0800213 if (bufferHandle == nullptr) {
214 return;
215 }
216
Marissa Wall65341642019-06-20 13:21:06 -0700217 auto buffer = const_cast<native_handle_t*>(bufferHandle);
218
219 if (mImportedBuffers.erase(bufferHandle)) {
220 Error error = mMapper->freeBuffer(buffer);
221 ASSERT_EQ(Error::NONE, error) << "failed to free buffer " << buffer;
222 } else {
223 mClonedBuffers.erase(bufferHandle);
224 native_handle_close(buffer);
225 native_handle_delete(buffer);
226 }
227}
228
229void* Gralloc::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
Marissa Wall9c5ebfc2019-11-05 14:59:27 -0800230 const IMapper::Rect& accessRegion, int acquireFence) {
Marissa Wall65341642019-06-20 13:21:06 -0700231 auto buffer = const_cast<native_handle_t*>(bufferHandle);
232
233 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
234 hidl_handle acquireFenceHandle;
235 if (acquireFence >= 0) {
236 auto h = native_handle_init(acquireFenceStorage, 1, 0);
237 h->data[0] = acquireFence;
238 acquireFenceHandle = h;
239 }
240
Marissa Wall65341642019-06-20 13:21:06 -0700241 void* data = nullptr;
242 mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
Marissa Wall9c5ebfc2019-11-05 14:59:27 -0800243 [&](const auto& tmpError, const auto& tmpData) {
Marissa Wall65341642019-06-20 13:21:06 -0700244 ASSERT_EQ(Error::NONE, tmpError) << "failed to lock buffer " << buffer;
245 data = tmpData;
Marissa Wall65341642019-06-20 13:21:06 -0700246 });
247
248 if (acquireFence >= 0) {
249 close(acquireFence);
250 }
251
252 return data;
253}
254
Marissa Wall65341642019-06-20 13:21:06 -0700255int Gralloc::unlock(const native_handle_t* bufferHandle) {
256 auto buffer = const_cast<native_handle_t*>(bufferHandle);
257
258 int releaseFence = -1;
259 mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
260 ASSERT_EQ(Error::NONE, tmpError) << "failed to unlock buffer " << buffer;
261
262 auto fenceHandle = tmpReleaseFence.getNativeHandle();
263 if (fenceHandle) {
264 ASSERT_EQ(0, fenceHandle->numInts) << "invalid fence handle " << fenceHandle;
265 if (fenceHandle->numFds == 1) {
266 releaseFence = dup(fenceHandle->data[0]);
267 ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
268 } else {
269 ASSERT_EQ(0, fenceHandle->numFds) << " invalid fence handle " << fenceHandle;
270 }
271 }
272 });
273
274 return releaseFence;
275}
276
Marissa Wall2c45bb12019-10-18 13:31:36 -0700277int Gralloc::flushLockedBuffer(const native_handle_t* bufferHandle) {
278 auto buffer = const_cast<native_handle_t*>(bufferHandle);
279
280 int releaseFence = -1;
281 mMapper->flushLockedBuffer(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
282 ASSERT_EQ(Error::NONE, tmpError) << "failed to flush locked buffer " << buffer;
283
284 auto fenceHandle = tmpReleaseFence.getNativeHandle();
285 if (fenceHandle) {
286 ASSERT_EQ(0, fenceHandle->numInts) << "invalid fence handle " << fenceHandle;
287 if (fenceHandle->numFds == 1) {
288 releaseFence = dup(fenceHandle->data[0]);
289 ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
290 } else {
291 ASSERT_EQ(0, fenceHandle->numFds) << " invalid fence handle " << fenceHandle;
292 }
293 }
294 });
295
296 return releaseFence;
297}
298
299void Gralloc::rereadLockedBuffer(const native_handle_t* bufferHandle) {
300 auto buffer = const_cast<native_handle_t*>(bufferHandle);
301
302 ASSERT_EQ(Error::NONE, mMapper->rereadLockedBuffer(buffer));
303}
304
Marissa Wall65341642019-06-20 13:21:06 -0700305bool Gralloc::validateBufferSize(const native_handle_t* bufferHandle,
306 const IMapper::BufferDescriptorInfo& descriptorInfo,
307 uint32_t stride) {
308 auto buffer = const_cast<native_handle_t*>(bufferHandle);
309
310 Error error = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
311 return error == Error::NONE;
312}
313
314void Gralloc::getTransportSize(const native_handle_t* bufferHandle, uint32_t* outNumFds,
315 uint32_t* outNumInts) {
316 auto buffer = const_cast<native_handle_t*>(bufferHandle);
317
318 *outNumFds = 0;
319 *outNumInts = 0;
320 mMapper->getTransportSize(buffer, [&](const auto& tmpError, const auto& tmpNumFds,
321 const auto& tmpNumInts) {
322 ASSERT_EQ(Error::NONE, tmpError) << "failed to get transport size";
323 ASSERT_GE(bufferHandle->numFds, int(tmpNumFds)) << "invalid numFds " << tmpNumFds;
324 ASSERT_GE(bufferHandle->numInts, int(tmpNumInts)) << "invalid numInts " << tmpNumInts;
325
326 *outNumFds = tmpNumFds;
327 *outNumInts = tmpNumInts;
328 });
329}
330
331bool Gralloc::isSupported(const IMapper::BufferDescriptorInfo& descriptorInfo) {
332 bool supported = false;
333 mMapper->isSupported(descriptorInfo, [&](const auto& tmpError, const auto& tmpSupported) {
334 ASSERT_EQ(Error::NONE, tmpError) << "failed to check is supported";
335 supported = tmpSupported;
336 });
337 return supported;
338}
339
Leon Scroggins IIIcd5e4692022-02-16 16:36:27 -0500340bool Gralloc::isSupportedNoFailure(const IMapper::BufferDescriptorInfo& descriptorInfo) {
341 bool supported = false;
342 mMapper->isSupported(descriptorInfo, [&](const auto& tmpError, const auto& tmpSupported) {
343 supported = tmpSupported && tmpError == Error::NONE;
344 });
345 return supported;
346}
347
Marissa Wall88d87fa2019-11-05 14:57:51 -0800348Error Gralloc::get(const native_handle_t* bufferHandle, const IMapper::MetadataType& metadataType,
349 hidl_vec<uint8_t>* outVec) {
350 Error err;
351 mMapper->get(const_cast<native_handle_t*>(bufferHandle), metadataType,
352 [&](const auto& tmpError, const hidl_vec<uint8_t>& tmpVec) {
353 err = tmpError;
354 *outVec = tmpVec;
355 });
356 return err;
357}
358
359Error Gralloc::set(const native_handle_t* bufferHandle, const IMapper::MetadataType& metadataType,
360 const hidl_vec<uint8_t>& vec) {
361 return mMapper->set(const_cast<native_handle_t*>(bufferHandle), metadataType, vec);
362}
363
364Error Gralloc::getFromBufferDescriptorInfo(const IMapper::BufferDescriptorInfo& descriptorInfo,
365 const IMapper::MetadataType& metadataType,
366 hidl_vec<uint8_t>* outVec) {
367 Error err;
368 mMapper->getFromBufferDescriptorInfo(
369 descriptorInfo, metadataType,
370 [&](const auto& tmpError, const hidl_vec<uint8_t>& tmpVec) {
371 err = tmpError;
372 *outVec = tmpVec;
373 });
374 return err;
375}
376
Marissa Walld36e1272019-11-26 11:33:32 -0800377Error Gralloc::getReservedRegion(const native_handle_t* bufferHandle, void** outReservedRegion,
378 uint64_t* outReservedSize) {
379 Error err;
380 mMapper->getReservedRegion(
381 const_cast<native_handle_t*>(bufferHandle),
382 [&](const auto& tmpError, const auto& tmpReservedRegion, const auto& tmpReservedSize) {
383 err = tmpError;
384 *outReservedRegion = tmpReservedRegion;
385 *outReservedSize = tmpReservedSize;
386 });
387 return err;
388}
389
Marissa Wall65341642019-06-20 13:21:06 -0700390} // namespace vts
391} // namespace V4_0
392} // namespace mapper
393} // namespace graphics
394} // namespace hardware
395} // namespace android