blob: 531f31131c14dfc17b9debd4109f06716b757642 [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
Marissa Wall88d87fa2019-11-05 14:57:51 -080017#include <gralloctypes/Gralloc4.h>
Marissa Wall65341642019-06-20 13:21:06 -070018#include <mapper-vts/4.0/MapperVts.h>
19
20#include <VtsHalHidlTargetTestBase.h>
21
22namespace android {
23namespace hardware {
24namespace graphics {
25namespace mapper {
26namespace V4_0 {
27namespace vts {
28
29Gralloc::Gralloc(const std::string& allocatorServiceName, const std::string& mapperServiceName,
30 bool errOnFailure) {
31 if (errOnFailure) {
32 init(allocatorServiceName, mapperServiceName);
33 } else {
34 initNoErr(allocatorServiceName, mapperServiceName);
35 }
36}
37
38void Gralloc::init(const std::string& allocatorServiceName, const std::string& mapperServiceName) {
39 mAllocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>(allocatorServiceName);
40 ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
41
42 mMapper = ::testing::VtsHalHidlTargetTestBase::getService<IMapper>(mapperServiceName);
43 ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
44 ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
45}
46
47void Gralloc::initNoErr(const std::string& allocatorServiceName,
48 const std::string& mapperServiceName) {
49 mAllocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>(allocatorServiceName);
50
51 mMapper = ::testing::VtsHalHidlTargetTestBase::getService<IMapper>(mapperServiceName);
52 if (mMapper.get()) {
53 ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
54 }
55}
56
57Gralloc::~Gralloc() {
58 for (auto bufferHandle : mClonedBuffers) {
59 auto buffer = const_cast<native_handle_t*>(bufferHandle);
60 native_handle_close(buffer);
61 native_handle_delete(buffer);
62 }
63 mClonedBuffers.clear();
64
65 for (auto bufferHandle : mImportedBuffers) {
66 auto buffer = const_cast<native_handle_t*>(bufferHandle);
67 EXPECT_EQ(Error::NONE, mMapper->freeBuffer(buffer)) << "failed to free buffer " << buffer;
68 }
69 mImportedBuffers.clear();
70}
71
72sp<IAllocator> Gralloc::getAllocator() const {
73 return mAllocator;
74}
75
76std::string Gralloc::dumpDebugInfo() {
77 std::string debugInfo;
78 mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
79
80 return debugInfo;
81}
82
83const native_handle_t* Gralloc::cloneBuffer(const hidl_handle& rawHandle) {
84 const native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle());
85 EXPECT_NE(nullptr, bufferHandle);
86
87 if (bufferHandle) {
88 mClonedBuffers.insert(bufferHandle);
89 }
90
91 return bufferHandle;
92}
93
94std::vector<const native_handle_t*> Gralloc::allocate(const BufferDescriptor& descriptor,
95 uint32_t count, bool import,
Marissa Wall88d87fa2019-11-05 14:57:51 -080096 bool allowFailure, uint32_t* outStride) {
Marissa Wall65341642019-06-20 13:21:06 -070097 std::vector<const native_handle_t*> bufferHandles;
98 bufferHandles.reserve(count);
Marissa Wall88d87fa2019-11-05 14:57:51 -080099 mAllocator->allocate(
100 descriptor, count,
101 [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) {
102 ASSERT_EQ(Error::NONE, tmpError) << "failed to allocate buffers";
103 ASSERT_EQ(count, tmpBuffers.size()) << "invalid buffer array";
Marissa Wall65341642019-06-20 13:21:06 -0700104
Marissa Wall88d87fa2019-11-05 14:57:51 -0800105 for (uint32_t i = 0; i < count; i++) {
106 const native_handle_t* bufferHandle = nullptr;
107 if (import) {
108 if (allowFailure) {
109 bufferHandle = importBuffer(tmpBuffers[i]);
110 } else {
111 ASSERT_NO_FATAL_FAILURE(bufferHandle = importBuffer(tmpBuffers[i]));
112 }
113 } else {
114 if (allowFailure) {
115 bufferHandle = cloneBuffer(tmpBuffers[i]);
116 } else {
117 ASSERT_NO_FATAL_FAILURE(bufferHandle = cloneBuffer(tmpBuffers[i]));
118 }
119 }
120 if (bufferHandle) {
121 bufferHandles.push_back(bufferHandle);
122 }
123 }
Marissa Wall65341642019-06-20 13:21:06 -0700124
Marissa Wall88d87fa2019-11-05 14:57:51 -0800125 if (outStride) {
126 *outStride = tmpStride;
127 }
128 });
Marissa Wall65341642019-06-20 13:21:06 -0700129
130 if (::testing::Test::HasFatalFailure()) {
131 bufferHandles.clear();
132 }
133
134 return bufferHandles;
135}
136
137const native_handle_t* Gralloc::allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
Marissa Wall88d87fa2019-11-05 14:57:51 -0800138 bool import, bool allowFailure, uint32_t* outStride) {
Marissa Wall65341642019-06-20 13:21:06 -0700139 BufferDescriptor descriptor = createDescriptor(descriptorInfo);
140 if (::testing::Test::HasFatalFailure()) {
141 return nullptr;
142 }
143
Marissa Wall88d87fa2019-11-05 14:57:51 -0800144 auto buffers = allocate(descriptor, 1, import, allowFailure, outStride);
Marissa Wall65341642019-06-20 13:21:06 -0700145 if (::testing::Test::HasFatalFailure()) {
146 return nullptr;
147 }
148
Marissa Wall88d87fa2019-11-05 14:57:51 -0800149 if (buffers.size() != 1) {
150 return nullptr;
151 }
Marissa Wall65341642019-06-20 13:21:06 -0700152 return buffers[0];
153}
154
155sp<IMapper> Gralloc::getMapper() const {
156 return mMapper;
157}
158
159BufferDescriptor Gralloc::createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo) {
160 BufferDescriptor descriptor;
161 mMapper->createDescriptor(descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) {
162 ASSERT_EQ(Error::NONE, tmpError) << "failed to create descriptor";
163 descriptor = tmpDescriptor;
164 });
165
166 return descriptor;
167}
168
169const native_handle_t* Gralloc::importBuffer(const hidl_handle& rawHandle) {
170 const native_handle_t* bufferHandle = nullptr;
171 mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
172 ASSERT_EQ(Error::NONE, tmpError)
173 << "failed to import buffer %p" << rawHandle.getNativeHandle();
174 bufferHandle = static_cast<const native_handle_t*>(tmpBuffer);
175 });
176
177 if (bufferHandle) {
178 mImportedBuffers.insert(bufferHandle);
179 }
180
181 return bufferHandle;
182}
183
184void Gralloc::freeBuffer(const native_handle_t* bufferHandle) {
Marissa Wall88d87fa2019-11-05 14:57:51 -0800185 if (bufferHandle == nullptr) {
186 return;
187 }
188
Marissa Wall65341642019-06-20 13:21:06 -0700189 auto buffer = const_cast<native_handle_t*>(bufferHandle);
190
191 if (mImportedBuffers.erase(bufferHandle)) {
192 Error error = mMapper->freeBuffer(buffer);
193 ASSERT_EQ(Error::NONE, error) << "failed to free buffer " << buffer;
194 } else {
195 mClonedBuffers.erase(bufferHandle);
196 native_handle_close(buffer);
197 native_handle_delete(buffer);
198 }
199}
200
201void* Gralloc::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
202 const IMapper::Rect& accessRegion, int acquireFence, int32_t* outBytesPerPixel,
203 int32_t* outBytesPerStride) {
204 auto buffer = const_cast<native_handle_t*>(bufferHandle);
205
206 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
207 hidl_handle acquireFenceHandle;
208 if (acquireFence >= 0) {
209 auto h = native_handle_init(acquireFenceStorage, 1, 0);
210 h->data[0] = acquireFence;
211 acquireFenceHandle = h;
212 }
213
214 *outBytesPerPixel = -1;
215 *outBytesPerStride = -1;
216
217 void* data = nullptr;
218 mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
219 [&](const auto& tmpError, const auto& tmpData, int32_t tmpBytesPerPixel,
220 int32_t tmpBytesPerStride) {
221 ASSERT_EQ(Error::NONE, tmpError) << "failed to lock buffer " << buffer;
222 data = tmpData;
223 *outBytesPerPixel = tmpBytesPerPixel;
224 *outBytesPerStride = tmpBytesPerStride;
225 });
226
227 if (acquireFence >= 0) {
228 close(acquireFence);
229 }
230
231 return data;
232}
233
234YCbCrLayout Gralloc::lockYCbCr(const native_handle_t* bufferHandle, uint64_t cpuUsage,
235 const IMapper::Rect& accessRegion, int acquireFence) {
236 auto buffer = const_cast<native_handle_t*>(bufferHandle);
237
238 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
239 hidl_handle acquireFenceHandle;
240 if (acquireFence >= 0) {
241 auto h = native_handle_init(acquireFenceStorage, 1, 0);
242 h->data[0] = acquireFence;
243 acquireFenceHandle = h;
244 }
245
246 YCbCrLayout layout = {};
247 mMapper->lockYCbCr(buffer, cpuUsage, accessRegion, acquireFenceHandle,
248 [&](const auto& tmpError, const auto& tmpLayout) {
249 ASSERT_EQ(Error::NONE, tmpError)
250 << "failed to lockYCbCr buffer " << buffer;
251 layout = tmpLayout;
252 });
253
254 if (acquireFence >= 0) {
255 close(acquireFence);
256 }
257
258 return layout;
259}
260
261int Gralloc::unlock(const native_handle_t* bufferHandle) {
262 auto buffer = const_cast<native_handle_t*>(bufferHandle);
263
264 int releaseFence = -1;
265 mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
266 ASSERT_EQ(Error::NONE, tmpError) << "failed to unlock buffer " << buffer;
267
268 auto fenceHandle = tmpReleaseFence.getNativeHandle();
269 if (fenceHandle) {
270 ASSERT_EQ(0, fenceHandle->numInts) << "invalid fence handle " << fenceHandle;
271 if (fenceHandle->numFds == 1) {
272 releaseFence = dup(fenceHandle->data[0]);
273 ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
274 } else {
275 ASSERT_EQ(0, fenceHandle->numFds) << " invalid fence handle " << fenceHandle;
276 }
277 }
278 });
279
280 return releaseFence;
281}
282
283bool Gralloc::validateBufferSize(const native_handle_t* bufferHandle,
284 const IMapper::BufferDescriptorInfo& descriptorInfo,
285 uint32_t stride) {
286 auto buffer = const_cast<native_handle_t*>(bufferHandle);
287
288 Error error = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
289 return error == Error::NONE;
290}
291
292void Gralloc::getTransportSize(const native_handle_t* bufferHandle, uint32_t* outNumFds,
293 uint32_t* outNumInts) {
294 auto buffer = const_cast<native_handle_t*>(bufferHandle);
295
296 *outNumFds = 0;
297 *outNumInts = 0;
298 mMapper->getTransportSize(buffer, [&](const auto& tmpError, const auto& tmpNumFds,
299 const auto& tmpNumInts) {
300 ASSERT_EQ(Error::NONE, tmpError) << "failed to get transport size";
301 ASSERT_GE(bufferHandle->numFds, int(tmpNumFds)) << "invalid numFds " << tmpNumFds;
302 ASSERT_GE(bufferHandle->numInts, int(tmpNumInts)) << "invalid numInts " << tmpNumInts;
303
304 *outNumFds = tmpNumFds;
305 *outNumInts = tmpNumInts;
306 });
307}
308
309bool Gralloc::isSupported(const IMapper::BufferDescriptorInfo& descriptorInfo) {
310 bool supported = false;
311 mMapper->isSupported(descriptorInfo, [&](const auto& tmpError, const auto& tmpSupported) {
312 ASSERT_EQ(Error::NONE, tmpError) << "failed to check is supported";
313 supported = tmpSupported;
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 Wall65341642019-06-20 13:21:06 -0700347} // namespace vts
348} // namespace V4_0
349} // namespace mapper
350} // namespace graphics
351} // namespace hardware
352} // namespace android