blob: cb90fa05973bb4aa7918385c6ec5ab2bb17a8976 [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
Marissa Wall65341642019-06-20 13:21:06 -070020namespace android {
21namespace hardware {
22namespace graphics {
23namespace mapper {
24namespace V4_0 {
25namespace vts {
26
27Gralloc::Gralloc(const std::string& allocatorServiceName, const std::string& mapperServiceName,
28 bool errOnFailure) {
29 if (errOnFailure) {
30 init(allocatorServiceName, mapperServiceName);
31 } else {
32 initNoErr(allocatorServiceName, mapperServiceName);
33 }
34}
35
36void Gralloc::init(const std::string& allocatorServiceName, const std::string& mapperServiceName) {
Dan Shi46245c52019-12-06 16:12:53 -080037 mAllocator = IAllocator::getService(allocatorServiceName);
Marissa Wall65341642019-06-20 13:21:06 -070038 ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
39
Dan Shi46245c52019-12-06 16:12:53 -080040 mMapper = IMapper::getService(mapperServiceName);
Marissa Wall65341642019-06-20 13:21:06 -070041 ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
42 ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
43}
44
45void Gralloc::initNoErr(const std::string& allocatorServiceName,
46 const std::string& mapperServiceName) {
Dan Shi46245c52019-12-06 16:12:53 -080047 mAllocator = IAllocator::getService(allocatorServiceName);
Marissa Wall65341642019-06-20 13:21:06 -070048
Dan Shi46245c52019-12-06 16:12:53 -080049 mMapper = IMapper::getService(mapperServiceName);
Marissa Wall65341642019-06-20 13:21:06 -070050 if (mMapper.get()) {
51 ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
52 }
53}
54
55Gralloc::~Gralloc() {
56 for (auto bufferHandle : mClonedBuffers) {
57 auto buffer = const_cast<native_handle_t*>(bufferHandle);
58 native_handle_close(buffer);
59 native_handle_delete(buffer);
60 }
61 mClonedBuffers.clear();
62
63 for (auto bufferHandle : mImportedBuffers) {
64 auto buffer = const_cast<native_handle_t*>(bufferHandle);
65 EXPECT_EQ(Error::NONE, mMapper->freeBuffer(buffer)) << "failed to free buffer " << buffer;
66 }
67 mImportedBuffers.clear();
68}
69
70sp<IAllocator> Gralloc::getAllocator() const {
71 return mAllocator;
72}
73
Marissa Wall65341642019-06-20 13:21:06 -070074const native_handle_t* Gralloc::cloneBuffer(const hidl_handle& rawHandle) {
75 const native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle());
76 EXPECT_NE(nullptr, bufferHandle);
77
78 if (bufferHandle) {
79 mClonedBuffers.insert(bufferHandle);
80 }
81
82 return bufferHandle;
83}
84
85std::vector<const native_handle_t*> Gralloc::allocate(const BufferDescriptor& descriptor,
86 uint32_t count, bool import,
Marissa Wall88d87fa2019-11-05 14:57:51 -080087 bool allowFailure, uint32_t* outStride) {
Marissa Wall65341642019-06-20 13:21:06 -070088 std::vector<const native_handle_t*> bufferHandles;
89 bufferHandles.reserve(count);
Marissa Wall88d87fa2019-11-05 14:57:51 -080090 mAllocator->allocate(
91 descriptor, count,
92 [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) {
93 ASSERT_EQ(Error::NONE, tmpError) << "failed to allocate buffers";
94 ASSERT_EQ(count, tmpBuffers.size()) << "invalid buffer array";
Marissa Wall65341642019-06-20 13:21:06 -070095
Marissa Wall88d87fa2019-11-05 14:57:51 -080096 for (uint32_t i = 0; i < count; i++) {
97 const native_handle_t* bufferHandle = nullptr;
98 if (import) {
99 if (allowFailure) {
100 bufferHandle = importBuffer(tmpBuffers[i]);
101 } else {
102 ASSERT_NO_FATAL_FAILURE(bufferHandle = importBuffer(tmpBuffers[i]));
103 }
104 } else {
105 if (allowFailure) {
106 bufferHandle = cloneBuffer(tmpBuffers[i]);
107 } else {
108 ASSERT_NO_FATAL_FAILURE(bufferHandle = cloneBuffer(tmpBuffers[i]));
109 }
110 }
111 if (bufferHandle) {
112 bufferHandles.push_back(bufferHandle);
113 }
114 }
Marissa Wall65341642019-06-20 13:21:06 -0700115
Marissa Wall88d87fa2019-11-05 14:57:51 -0800116 if (outStride) {
117 *outStride = tmpStride;
118 }
119 });
Marissa Wall65341642019-06-20 13:21:06 -0700120
121 if (::testing::Test::HasFatalFailure()) {
122 bufferHandles.clear();
123 }
124
125 return bufferHandles;
126}
127
128const native_handle_t* Gralloc::allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
Marissa Wall88d87fa2019-11-05 14:57:51 -0800129 bool import, bool allowFailure, uint32_t* outStride) {
Marissa Wall65341642019-06-20 13:21:06 -0700130 BufferDescriptor descriptor = createDescriptor(descriptorInfo);
131 if (::testing::Test::HasFatalFailure()) {
132 return nullptr;
133 }
134
Marissa Wall88d87fa2019-11-05 14:57:51 -0800135 auto buffers = allocate(descriptor, 1, import, allowFailure, outStride);
Marissa Wall65341642019-06-20 13:21:06 -0700136 if (::testing::Test::HasFatalFailure()) {
137 return nullptr;
138 }
139
Marissa Wall88d87fa2019-11-05 14:57:51 -0800140 if (buffers.size() != 1) {
141 return nullptr;
142 }
Marissa Wall65341642019-06-20 13:21:06 -0700143 return buffers[0];
144}
145
146sp<IMapper> Gralloc::getMapper() const {
147 return mMapper;
148}
149
150BufferDescriptor Gralloc::createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo) {
151 BufferDescriptor descriptor;
152 mMapper->createDescriptor(descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) {
153 ASSERT_EQ(Error::NONE, tmpError) << "failed to create descriptor";
154 descriptor = tmpDescriptor;
155 });
156
157 return descriptor;
158}
159
160const native_handle_t* Gralloc::importBuffer(const hidl_handle& rawHandle) {
161 const native_handle_t* bufferHandle = nullptr;
162 mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
163 ASSERT_EQ(Error::NONE, tmpError)
164 << "failed to import buffer %p" << rawHandle.getNativeHandle();
165 bufferHandle = static_cast<const native_handle_t*>(tmpBuffer);
166 });
167
168 if (bufferHandle) {
169 mImportedBuffers.insert(bufferHandle);
170 }
171
172 return bufferHandle;
173}
174
175void Gralloc::freeBuffer(const native_handle_t* bufferHandle) {
Marissa Wall88d87fa2019-11-05 14:57:51 -0800176 if (bufferHandle == nullptr) {
177 return;
178 }
179
Marissa Wall65341642019-06-20 13:21:06 -0700180 auto buffer = const_cast<native_handle_t*>(bufferHandle);
181
182 if (mImportedBuffers.erase(bufferHandle)) {
183 Error error = mMapper->freeBuffer(buffer);
184 ASSERT_EQ(Error::NONE, error) << "failed to free buffer " << buffer;
185 } else {
186 mClonedBuffers.erase(bufferHandle);
187 native_handle_close(buffer);
188 native_handle_delete(buffer);
189 }
190}
191
192void* Gralloc::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
Marissa Wall9c5ebfc2019-11-05 14:59:27 -0800193 const IMapper::Rect& accessRegion, int acquireFence) {
Marissa Wall65341642019-06-20 13:21:06 -0700194 auto buffer = const_cast<native_handle_t*>(bufferHandle);
195
196 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
197 hidl_handle acquireFenceHandle;
198 if (acquireFence >= 0) {
199 auto h = native_handle_init(acquireFenceStorage, 1, 0);
200 h->data[0] = acquireFence;
201 acquireFenceHandle = h;
202 }
203
Marissa Wall65341642019-06-20 13:21:06 -0700204 void* data = nullptr;
205 mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
Marissa Wall9c5ebfc2019-11-05 14:59:27 -0800206 [&](const auto& tmpError, const auto& tmpData) {
Marissa Wall65341642019-06-20 13:21:06 -0700207 ASSERT_EQ(Error::NONE, tmpError) << "failed to lock buffer " << buffer;
208 data = tmpData;
Marissa Wall65341642019-06-20 13:21:06 -0700209 });
210
211 if (acquireFence >= 0) {
212 close(acquireFence);
213 }
214
215 return data;
216}
217
Marissa Wall65341642019-06-20 13:21:06 -0700218int Gralloc::unlock(const native_handle_t* bufferHandle) {
219 auto buffer = const_cast<native_handle_t*>(bufferHandle);
220
221 int releaseFence = -1;
222 mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
223 ASSERT_EQ(Error::NONE, tmpError) << "failed to unlock buffer " << buffer;
224
225 auto fenceHandle = tmpReleaseFence.getNativeHandle();
226 if (fenceHandle) {
227 ASSERT_EQ(0, fenceHandle->numInts) << "invalid fence handle " << fenceHandle;
228 if (fenceHandle->numFds == 1) {
229 releaseFence = dup(fenceHandle->data[0]);
230 ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
231 } else {
232 ASSERT_EQ(0, fenceHandle->numFds) << " invalid fence handle " << fenceHandle;
233 }
234 }
235 });
236
237 return releaseFence;
238}
239
Marissa Wall2c45bb12019-10-18 13:31:36 -0700240int Gralloc::flushLockedBuffer(const native_handle_t* bufferHandle) {
241 auto buffer = const_cast<native_handle_t*>(bufferHandle);
242
243 int releaseFence = -1;
244 mMapper->flushLockedBuffer(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
245 ASSERT_EQ(Error::NONE, tmpError) << "failed to flush locked buffer " << buffer;
246
247 auto fenceHandle = tmpReleaseFence.getNativeHandle();
248 if (fenceHandle) {
249 ASSERT_EQ(0, fenceHandle->numInts) << "invalid fence handle " << fenceHandle;
250 if (fenceHandle->numFds == 1) {
251 releaseFence = dup(fenceHandle->data[0]);
252 ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
253 } else {
254 ASSERT_EQ(0, fenceHandle->numFds) << " invalid fence handle " << fenceHandle;
255 }
256 }
257 });
258
259 return releaseFence;
260}
261
262void Gralloc::rereadLockedBuffer(const native_handle_t* bufferHandle) {
263 auto buffer = const_cast<native_handle_t*>(bufferHandle);
264
265 ASSERT_EQ(Error::NONE, mMapper->rereadLockedBuffer(buffer));
266}
267
Marissa Wall65341642019-06-20 13:21:06 -0700268bool Gralloc::validateBufferSize(const native_handle_t* bufferHandle,
269 const IMapper::BufferDescriptorInfo& descriptorInfo,
270 uint32_t stride) {
271 auto buffer = const_cast<native_handle_t*>(bufferHandle);
272
273 Error error = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
274 return error == Error::NONE;
275}
276
277void Gralloc::getTransportSize(const native_handle_t* bufferHandle, uint32_t* outNumFds,
278 uint32_t* outNumInts) {
279 auto buffer = const_cast<native_handle_t*>(bufferHandle);
280
281 *outNumFds = 0;
282 *outNumInts = 0;
283 mMapper->getTransportSize(buffer, [&](const auto& tmpError, const auto& tmpNumFds,
284 const auto& tmpNumInts) {
285 ASSERT_EQ(Error::NONE, tmpError) << "failed to get transport size";
286 ASSERT_GE(bufferHandle->numFds, int(tmpNumFds)) << "invalid numFds " << tmpNumFds;
287 ASSERT_GE(bufferHandle->numInts, int(tmpNumInts)) << "invalid numInts " << tmpNumInts;
288
289 *outNumFds = tmpNumFds;
290 *outNumInts = tmpNumInts;
291 });
292}
293
294bool Gralloc::isSupported(const IMapper::BufferDescriptorInfo& descriptorInfo) {
295 bool supported = false;
296 mMapper->isSupported(descriptorInfo, [&](const auto& tmpError, const auto& tmpSupported) {
297 ASSERT_EQ(Error::NONE, tmpError) << "failed to check is supported";
298 supported = tmpSupported;
299 });
300 return supported;
301}
302
Marissa Wall88d87fa2019-11-05 14:57:51 -0800303Error Gralloc::get(const native_handle_t* bufferHandle, const IMapper::MetadataType& metadataType,
304 hidl_vec<uint8_t>* outVec) {
305 Error err;
306 mMapper->get(const_cast<native_handle_t*>(bufferHandle), metadataType,
307 [&](const auto& tmpError, const hidl_vec<uint8_t>& tmpVec) {
308 err = tmpError;
309 *outVec = tmpVec;
310 });
311 return err;
312}
313
314Error Gralloc::set(const native_handle_t* bufferHandle, const IMapper::MetadataType& metadataType,
315 const hidl_vec<uint8_t>& vec) {
316 return mMapper->set(const_cast<native_handle_t*>(bufferHandle), metadataType, vec);
317}
318
319Error Gralloc::getFromBufferDescriptorInfo(const IMapper::BufferDescriptorInfo& descriptorInfo,
320 const IMapper::MetadataType& metadataType,
321 hidl_vec<uint8_t>* outVec) {
322 Error err;
323 mMapper->getFromBufferDescriptorInfo(
324 descriptorInfo, metadataType,
325 [&](const auto& tmpError, const hidl_vec<uint8_t>& tmpVec) {
326 err = tmpError;
327 *outVec = tmpVec;
328 });
329 return err;
330}
331
Marissa Walld36e1272019-11-26 11:33:32 -0800332Error Gralloc::getReservedRegion(const native_handle_t* bufferHandle, void** outReservedRegion,
333 uint64_t* outReservedSize) {
334 Error err;
335 mMapper->getReservedRegion(
336 const_cast<native_handle_t*>(bufferHandle),
337 [&](const auto& tmpError, const auto& tmpReservedRegion, const auto& tmpReservedSize) {
338 err = tmpError;
339 *outReservedRegion = tmpReservedRegion;
340 *outReservedSize = tmpReservedSize;
341 });
342 return err;
343}
344
Marissa Wall65341642019-06-20 13:21:06 -0700345} // namespace vts
346} // namespace V4_0
347} // namespace mapper
348} // namespace graphics
349} // namespace hardware
350} // namespace android