blob: 4a6f68da26e6138c78c942bbcf41cd9afb310a22 [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 Mouri18339992022-04-04 21:53:57 +000017#include <android-base/properties.h>
Marissa Wall88d87fa2019-11-05 14:57:51 -080018#include <gralloctypes/Gralloc4.h>
Marissa Wall65341642019-06-20 13:21:06 -070019#include <mapper-vts/4.0/MapperVts.h>
20
Marissa Wall65341642019-06-20 13:21:06 -070021namespace android {
22namespace hardware {
23namespace graphics {
24namespace mapper {
25namespace V4_0 {
26namespace vts {
27
28Gralloc::Gralloc(const std::string& allocatorServiceName, const std::string& mapperServiceName,
29 bool errOnFailure) {
30 if (errOnFailure) {
31 init(allocatorServiceName, mapperServiceName);
32 } else {
33 initNoErr(allocatorServiceName, mapperServiceName);
34 }
35}
36
37void Gralloc::init(const std::string& allocatorServiceName, const std::string& mapperServiceName) {
Dan Shi46245c52019-12-06 16:12:53 -080038 mAllocator = IAllocator::getService(allocatorServiceName);
Marissa Wall65341642019-06-20 13:21:06 -070039 ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
40
Dan Shi46245c52019-12-06 16:12:53 -080041 mMapper = IMapper::getService(mapperServiceName);
Marissa Wall65341642019-06-20 13:21:06 -070042 ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
43 ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
44}
45
46void Gralloc::initNoErr(const std::string& allocatorServiceName,
47 const std::string& mapperServiceName) {
Dan Shi46245c52019-12-06 16:12:53 -080048 mAllocator = IAllocator::getService(allocatorServiceName);
Marissa Wall65341642019-06-20 13:21:06 -070049
Dan Shi46245c52019-12-06 16:12:53 -080050 mMapper = IMapper::getService(mapperServiceName);
Marissa Wall65341642019-06-20 13:21:06 -070051 if (mMapper.get()) {
52 ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
53 }
54}
55
56Gralloc::~Gralloc() {
57 for (auto bufferHandle : mClonedBuffers) {
58 auto buffer = const_cast<native_handle_t*>(bufferHandle);
59 native_handle_close(buffer);
60 native_handle_delete(buffer);
61 }
62 mClonedBuffers.clear();
63
64 for (auto bufferHandle : mImportedBuffers) {
65 auto buffer = const_cast<native_handle_t*>(bufferHandle);
66 EXPECT_EQ(Error::NONE, mMapper->freeBuffer(buffer)) << "failed to free buffer " << buffer;
67 }
68 mImportedBuffers.clear();
69}
70
71sp<IAllocator> Gralloc::getAllocator() const {
72 return mAllocator;
73}
74
Yichi Chenc6394ff2020-05-12 08:58:08 +080075const native_handle_t* Gralloc::cloneBuffer(const hidl_handle& rawHandle,
76 enum Tolerance /*tolerance*/) {
Marissa Wall65341642019-06-20 13:21:06 -070077 const native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle());
78 EXPECT_NE(nullptr, bufferHandle);
79
80 if (bufferHandle) {
81 mClonedBuffers.insert(bufferHandle);
82 }
83
84 return bufferHandle;
85}
86
87std::vector<const native_handle_t*> Gralloc::allocate(const BufferDescriptor& descriptor,
88 uint32_t count, bool import,
Yichi Chenc6394ff2020-05-12 08:58:08 +080089 enum Tolerance tolerance,
90 uint32_t* outStride) {
Marissa Wall65341642019-06-20 13:21:06 -070091 std::vector<const native_handle_t*> bufferHandles;
92 bufferHandles.reserve(count);
Yichi Chenc6394ff2020-05-12 08:58:08 +080093 mAllocator->allocate(descriptor, count,
94 [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) {
95 if (canTolerate(tolerance, tmpError)) {
96 return;
97 }
Marissa Wall65341642019-06-20 13:21:06 -070098
Alec Mouri18339992022-04-04 21:53:57 +000099 if (tmpError != Error::NONE) {
100 if (base::GetIntProperty("ro.vendor.build.version.sdk", 0, 0,
101 INT_MAX) < 33) {
102 GTEST_SKIP() << "Old vendor grallocs may not support P010";
103 } else {
104 GTEST_FAIL() << "failed to allocate buffers";
105 }
106 }
Yichi Chenc6394ff2020-05-12 08:58:08 +0800107 ASSERT_EQ(count, tmpBuffers.size()) << "invalid buffer array";
Marissa Wall65341642019-06-20 13:21:06 -0700108
Yichi Chenc6394ff2020-05-12 08:58:08 +0800109 for (uint32_t i = 0; i < count; i++) {
110 const native_handle_t* bufferHandle = nullptr;
111 if (import) {
112 ASSERT_NO_FATAL_FAILURE(
113 bufferHandle = importBuffer(tmpBuffers[i], tolerance));
114 } else {
115 ASSERT_NO_FATAL_FAILURE(
116 bufferHandle = cloneBuffer(tmpBuffers[i], tolerance));
117 }
118 if (bufferHandle) {
119 bufferHandles.push_back(bufferHandle);
120 }
121 }
122
123 if (outStride) {
124 *outStride = tmpStride;
125 }
126 });
Marissa Wall65341642019-06-20 13:21:06 -0700127
128 if (::testing::Test::HasFatalFailure()) {
129 bufferHandles.clear();
130 }
131
132 return bufferHandles;
133}
134
135const native_handle_t* Gralloc::allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
Yichi Chenc6394ff2020-05-12 08:58:08 +0800136 bool import, enum Tolerance tolerance,
137 uint32_t* outStride) {
Marissa Wall65341642019-06-20 13:21:06 -0700138 BufferDescriptor descriptor = createDescriptor(descriptorInfo);
139 if (::testing::Test::HasFatalFailure()) {
140 return nullptr;
141 }
142
Yichi Chenc6394ff2020-05-12 08:58:08 +0800143 auto buffers = allocate(descriptor, 1, import, tolerance, outStride);
Alec Mouri18339992022-04-04 21:53:57 +0000144 if (::testing::Test::HasFatalFailure() || ::testing::Test::IsSkipped() || buffers.size() != 1) {
Marissa Wall88d87fa2019-11-05 14:57:51 -0800145 return nullptr;
146 }
Marissa Wall65341642019-06-20 13:21:06 -0700147 return buffers[0];
148}
149
150sp<IMapper> Gralloc::getMapper() const {
151 return mMapper;
152}
153
154BufferDescriptor Gralloc::createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo) {
155 BufferDescriptor descriptor;
156 mMapper->createDescriptor(descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) {
157 ASSERT_EQ(Error::NONE, tmpError) << "failed to create descriptor";
158 descriptor = tmpDescriptor;
159 });
160
161 return descriptor;
162}
163
Yichi Chenc6394ff2020-05-12 08:58:08 +0800164const native_handle_t* Gralloc::importBuffer(const hidl_handle& rawHandle,
165 enum Tolerance tolerance) {
Marissa Wall65341642019-06-20 13:21:06 -0700166 const native_handle_t* bufferHandle = nullptr;
167 mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
Yichi Chenc6394ff2020-05-12 08:58:08 +0800168 if (!canTolerate(tolerance, tmpError)) {
169 ASSERT_EQ(Error::NONE, tmpError)
170 << "failed to import buffer %p" << rawHandle.getNativeHandle();
171 }
Marissa Wall65341642019-06-20 13:21:06 -0700172 bufferHandle = static_cast<const native_handle_t*>(tmpBuffer);
173 });
174
175 if (bufferHandle) {
176 mImportedBuffers.insert(bufferHandle);
177 }
178
179 return bufferHandle;
180}
181
182void Gralloc::freeBuffer(const native_handle_t* bufferHandle) {
Marissa Wall88d87fa2019-11-05 14:57:51 -0800183 if (bufferHandle == nullptr) {
184 return;
185 }
186
Marissa Wall65341642019-06-20 13:21:06 -0700187 auto buffer = const_cast<native_handle_t*>(bufferHandle);
188
189 if (mImportedBuffers.erase(bufferHandle)) {
190 Error error = mMapper->freeBuffer(buffer);
191 ASSERT_EQ(Error::NONE, error) << "failed to free buffer " << buffer;
192 } else {
193 mClonedBuffers.erase(bufferHandle);
194 native_handle_close(buffer);
195 native_handle_delete(buffer);
196 }
197}
198
199void* Gralloc::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
Marissa Wall9c5ebfc2019-11-05 14:59:27 -0800200 const IMapper::Rect& accessRegion, int acquireFence) {
Marissa Wall65341642019-06-20 13:21:06 -0700201 auto buffer = const_cast<native_handle_t*>(bufferHandle);
202
203 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
204 hidl_handle acquireFenceHandle;
205 if (acquireFence >= 0) {
206 auto h = native_handle_init(acquireFenceStorage, 1, 0);
207 h->data[0] = acquireFence;
208 acquireFenceHandle = h;
209 }
210
Marissa Wall65341642019-06-20 13:21:06 -0700211 void* data = nullptr;
212 mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
Marissa Wall9c5ebfc2019-11-05 14:59:27 -0800213 [&](const auto& tmpError, const auto& tmpData) {
Marissa Wall65341642019-06-20 13:21:06 -0700214 ASSERT_EQ(Error::NONE, tmpError) << "failed to lock buffer " << buffer;
215 data = tmpData;
Marissa Wall65341642019-06-20 13:21:06 -0700216 });
217
218 if (acquireFence >= 0) {
219 close(acquireFence);
220 }
221
222 return data;
223}
224
Marissa Wall65341642019-06-20 13:21:06 -0700225int Gralloc::unlock(const native_handle_t* bufferHandle) {
226 auto buffer = const_cast<native_handle_t*>(bufferHandle);
227
228 int releaseFence = -1;
229 mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
230 ASSERT_EQ(Error::NONE, tmpError) << "failed to unlock buffer " << buffer;
231
232 auto fenceHandle = tmpReleaseFence.getNativeHandle();
233 if (fenceHandle) {
234 ASSERT_EQ(0, fenceHandle->numInts) << "invalid fence handle " << fenceHandle;
235 if (fenceHandle->numFds == 1) {
236 releaseFence = dup(fenceHandle->data[0]);
237 ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
238 } else {
239 ASSERT_EQ(0, fenceHandle->numFds) << " invalid fence handle " << fenceHandle;
240 }
241 }
242 });
243
244 return releaseFence;
245}
246
Marissa Wall2c45bb12019-10-18 13:31:36 -0700247int Gralloc::flushLockedBuffer(const native_handle_t* bufferHandle) {
248 auto buffer = const_cast<native_handle_t*>(bufferHandle);
249
250 int releaseFence = -1;
251 mMapper->flushLockedBuffer(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
252 ASSERT_EQ(Error::NONE, tmpError) << "failed to flush locked buffer " << buffer;
253
254 auto fenceHandle = tmpReleaseFence.getNativeHandle();
255 if (fenceHandle) {
256 ASSERT_EQ(0, fenceHandle->numInts) << "invalid fence handle " << fenceHandle;
257 if (fenceHandle->numFds == 1) {
258 releaseFence = dup(fenceHandle->data[0]);
259 ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
260 } else {
261 ASSERT_EQ(0, fenceHandle->numFds) << " invalid fence handle " << fenceHandle;
262 }
263 }
264 });
265
266 return releaseFence;
267}
268
269void Gralloc::rereadLockedBuffer(const native_handle_t* bufferHandle) {
270 auto buffer = const_cast<native_handle_t*>(bufferHandle);
271
272 ASSERT_EQ(Error::NONE, mMapper->rereadLockedBuffer(buffer));
273}
274
Marissa Wall65341642019-06-20 13:21:06 -0700275bool Gralloc::validateBufferSize(const native_handle_t* bufferHandle,
276 const IMapper::BufferDescriptorInfo& descriptorInfo,
277 uint32_t stride) {
278 auto buffer = const_cast<native_handle_t*>(bufferHandle);
279
280 Error error = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
281 return error == Error::NONE;
282}
283
284void Gralloc::getTransportSize(const native_handle_t* bufferHandle, uint32_t* outNumFds,
285 uint32_t* outNumInts) {
286 auto buffer = const_cast<native_handle_t*>(bufferHandle);
287
288 *outNumFds = 0;
289 *outNumInts = 0;
290 mMapper->getTransportSize(buffer, [&](const auto& tmpError, const auto& tmpNumFds,
291 const auto& tmpNumInts) {
292 ASSERT_EQ(Error::NONE, tmpError) << "failed to get transport size";
293 ASSERT_GE(bufferHandle->numFds, int(tmpNumFds)) << "invalid numFds " << tmpNumFds;
294 ASSERT_GE(bufferHandle->numInts, int(tmpNumInts)) << "invalid numInts " << tmpNumInts;
295
296 *outNumFds = tmpNumFds;
297 *outNumInts = tmpNumInts;
298 });
299}
300
301bool Gralloc::isSupported(const IMapper::BufferDescriptorInfo& descriptorInfo) {
302 bool supported = false;
303 mMapper->isSupported(descriptorInfo, [&](const auto& tmpError, const auto& tmpSupported) {
304 ASSERT_EQ(Error::NONE, tmpError) << "failed to check is supported";
305 supported = tmpSupported;
306 });
307 return supported;
308}
309
Leon Scroggins IIIcd5e4692022-02-16 16:36:27 -0500310bool Gralloc::isSupportedNoFailure(const IMapper::BufferDescriptorInfo& descriptorInfo) {
311 bool supported = false;
312 mMapper->isSupported(descriptorInfo, [&](const auto& tmpError, const auto& tmpSupported) {
313 supported = tmpSupported && tmpError == Error::NONE;
314 });
315 return supported;
316}
317
Marissa Wall88d87fa2019-11-05 14:57:51 -0800318Error Gralloc::get(const native_handle_t* bufferHandle, const IMapper::MetadataType& metadataType,
319 hidl_vec<uint8_t>* outVec) {
320 Error err;
321 mMapper->get(const_cast<native_handle_t*>(bufferHandle), metadataType,
322 [&](const auto& tmpError, const hidl_vec<uint8_t>& tmpVec) {
323 err = tmpError;
324 *outVec = tmpVec;
325 });
326 return err;
327}
328
329Error Gralloc::set(const native_handle_t* bufferHandle, const IMapper::MetadataType& metadataType,
330 const hidl_vec<uint8_t>& vec) {
331 return mMapper->set(const_cast<native_handle_t*>(bufferHandle), metadataType, vec);
332}
333
334Error Gralloc::getFromBufferDescriptorInfo(const IMapper::BufferDescriptorInfo& descriptorInfo,
335 const IMapper::MetadataType& metadataType,
336 hidl_vec<uint8_t>* outVec) {
337 Error err;
338 mMapper->getFromBufferDescriptorInfo(
339 descriptorInfo, metadataType,
340 [&](const auto& tmpError, const hidl_vec<uint8_t>& tmpVec) {
341 err = tmpError;
342 *outVec = tmpVec;
343 });
344 return err;
345}
346
Marissa Walld36e1272019-11-26 11:33:32 -0800347Error Gralloc::getReservedRegion(const native_handle_t* bufferHandle, void** outReservedRegion,
348 uint64_t* outReservedSize) {
349 Error err;
350 mMapper->getReservedRegion(
351 const_cast<native_handle_t*>(bufferHandle),
352 [&](const auto& tmpError, const auto& tmpReservedRegion, const auto& tmpReservedSize) {
353 err = tmpError;
354 *outReservedRegion = tmpReservedRegion;
355 *outReservedSize = tmpReservedSize;
356 });
357 return err;
358}
359
Marissa Wall65341642019-06-20 13:21:06 -0700360} // namespace vts
361} // namespace V4_0
362} // namespace mapper
363} // namespace graphics
364} // namespace hardware
365} // namespace android