• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 #include <aidlcommonsupport/NativeHandle.h>
18 #include <android-base/properties.h>
19 #include <android/binder_manager.h>
20 #include <gralloctypes/Gralloc4.h>
21 #include <mapper-vts/4.0/MapperVts.h>
22 
23 namespace android {
24 namespace hardware {
25 namespace graphics {
26 namespace mapper {
27 namespace V4_0 {
28 namespace vts {
29 
Gralloc(const std::string & aidlAllocatorServiceName,const std::string & hidlAllocatorServiceName,const std::string & mapperServiceName,bool errOnFailure)30 Gralloc::Gralloc(const std::string& aidlAllocatorServiceName,
31                  const std::string& hidlAllocatorServiceName, const std::string& mapperServiceName,
32                  bool errOnFailure) {
33     if (errOnFailure) {
34         init(aidlAllocatorServiceName, hidlAllocatorServiceName, mapperServiceName);
35     } else {
36         initNoErr(aidlAllocatorServiceName, hidlAllocatorServiceName, mapperServiceName);
37     }
38 }
39 
init(const std::string & aidlAllocatorServiceName,const std::string & hidlAllocatorServiceName,const std::string & mapperServiceName)40 void Gralloc::init(const std::string& aidlAllocatorServiceName,
41                    const std::string& hidlAllocatorServiceName,
42                    const std::string& mapperServiceName) {
43     mAidlAllocator = aidl::android::hardware::graphics::allocator::IAllocator::fromBinder(
44             ndk::SpAIBinder(AServiceManager_checkService(aidlAllocatorServiceName.c_str())));
45 
46     if (mAidlAllocator == nullptr) {
47         mHidlAllocator = IAllocator::getService(hidlAllocatorServiceName);
48     }
49     ASSERT_TRUE(nullptr != mAidlAllocator || mHidlAllocator != nullptr)
50             << "failed to get allocator service";
51 
52     mMapper = IMapper::getService(mapperServiceName);
53     ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
54     ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
55 }
56 
initNoErr(const std::string & aidlAllocatorServiceName,const std::string & hidlAllocatorServiceName,const std::string & mapperServiceName)57 void Gralloc::initNoErr(const std::string& aidlAllocatorServiceName,
58                         const std::string& hidlAllocatorServiceName,
59                         const std::string& mapperServiceName) {
60     mAidlAllocator = aidl::android::hardware::graphics::allocator::IAllocator::fromBinder(
61             ndk::SpAIBinder(AServiceManager_checkService(aidlAllocatorServiceName.c_str())));
62 
63     if (mAidlAllocator == nullptr) {
64         mHidlAllocator = IAllocator::getService(hidlAllocatorServiceName);
65     }
66 
67     mMapper = IMapper::getService(mapperServiceName);
68     if (mMapper.get()) {
69         ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
70     }
71 }
72 
~Gralloc()73 Gralloc::~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 
cloneBuffer(const hidl_handle & rawHandle,enum Tolerance)88 const native_handle_t* Gralloc::cloneBuffer(const hidl_handle& rawHandle,
89                                             enum Tolerance /*tolerance*/) {
90     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 
allocate(const BufferDescriptor & descriptor,uint32_t count,bool import,enum Tolerance tolerance,uint32_t * outStride)100 std::vector<const native_handle_t*> Gralloc::allocate(const BufferDescriptor& descriptor,
101                                                       uint32_t count, bool import,
102                                                       enum Tolerance tolerance,
103                                                       uint32_t* outStride) {
104     std::vector<const native_handle_t*> bufferHandles;
105     bufferHandles.reserve(count);
106 
107     auto callback = [&](Error error, uint32_t stride,
108                         const hidl_vec<hidl_handle>& buffers) -> void {
109         if (canTolerate(tolerance, error)) {
110             return;
111         }
112 
113         if (error != Error::NONE) {
114             GTEST_FAIL() << "failed to allocate buffers";
115         }
116         ASSERT_EQ(count, buffers.size()) << "invalid buffer array";
117 
118         for (uint32_t i = 0; i < count; i++) {
119             const native_handle_t* bufferHandle = nullptr;
120             if (import) {
121                 ASSERT_NO_FATAL_FAILURE(bufferHandle = importBuffer(buffers[i], tolerance));
122             } else {
123                 ASSERT_NO_FATAL_FAILURE(bufferHandle = cloneBuffer(buffers[i], tolerance));
124             }
125             if (bufferHandle) {
126                 bufferHandles.push_back(bufferHandle);
127             }
128         }
129 
130         if (outStride) {
131             *outStride = stride;
132         }
133     };
134 
135     rawAllocate(descriptor, count, callback);
136 
137     if (::testing::Test::HasFatalFailure()) {
138         bufferHandles.clear();
139     }
140 
141     return bufferHandles;
142 }
143 
allocate(const IMapper::BufferDescriptorInfo & descriptorInfo,bool import,enum Tolerance tolerance,uint32_t * outStride)144 const native_handle_t* Gralloc::allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
145                                          bool import, enum Tolerance tolerance,
146                                          uint32_t* outStride) {
147     BufferDescriptor descriptor = createDescriptor(descriptorInfo);
148     if (::testing::Test::HasFatalFailure()) {
149         return nullptr;
150     }
151 
152     auto buffers = allocate(descriptor, 1, import, tolerance, outStride);
153     if (::testing::Test::HasFatalFailure() || ::testing::Test::IsSkipped() || buffers.size() != 1) {
154         return nullptr;
155     }
156     return buffers[0];
157 }
158 
rawAllocate(const BufferDescriptor & descriptor,uint32_t count,std::function<void (Error,uint32_t,const hidl_vec<hidl_handle> &)> callback)159 void Gralloc::rawAllocate(
160         const BufferDescriptor& descriptor, uint32_t count,
161         std::function<void(Error, uint32_t, const hidl_vec<hidl_handle>&)> callback) {
162     if (mAidlAllocator) {
163         aidl::android::hardware::graphics::allocator::AllocationResult result;
164         auto status = mAidlAllocator->allocate(descriptor, count, &result);
165         const Error error = toHidlError(status);
166         std::vector<hidl_handle> handles;
167         for (const auto& aidlHandle : result.buffers) {
168             handles.push_back(hidl_handle(makeFromAidl(aidlHandle)));
169         }
170         callback(error, result.stride, handles);
171     } else {
172         mHidlAllocator->allocate(descriptor, count, callback);
173     }
174 }
175 
getMapper() const176 sp<IMapper> Gralloc::getMapper() const {
177     return mMapper;
178 }
179 
createDescriptor(const IMapper::BufferDescriptorInfo & descriptorInfo)180 BufferDescriptor Gralloc::createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo) {
181     BufferDescriptor descriptor;
182     mMapper->createDescriptor(descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) {
183         ASSERT_EQ(Error::NONE, tmpError) << "failed to create descriptor";
184         descriptor = tmpDescriptor;
185     });
186 
187     return descriptor;
188 }
189 
importBuffer(const hidl_handle & rawHandle,enum Tolerance tolerance)190 const native_handle_t* Gralloc::importBuffer(const hidl_handle& rawHandle,
191                                              enum Tolerance tolerance) {
192     const native_handle_t* bufferHandle = nullptr;
193     mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
194         if (!canTolerate(tolerance, tmpError)) {
195             ASSERT_EQ(Error::NONE, tmpError)
196                     << "failed to import buffer %p" << rawHandle.getNativeHandle();
197         }
198         bufferHandle = static_cast<const native_handle_t*>(tmpBuffer);
199     });
200 
201     if (bufferHandle) {
202         mImportedBuffers.insert(bufferHandle);
203     }
204 
205     return bufferHandle;
206 }
207 
freeBuffer(const native_handle_t * bufferHandle)208 void Gralloc::freeBuffer(const native_handle_t* bufferHandle) {
209     if (bufferHandle == nullptr) {
210         return;
211     }
212 
213     auto buffer = const_cast<native_handle_t*>(bufferHandle);
214 
215     if (mImportedBuffers.erase(bufferHandle)) {
216         Error error = mMapper->freeBuffer(buffer);
217         ASSERT_EQ(Error::NONE, error) << "failed to free buffer " << buffer;
218     } else {
219         mClonedBuffers.erase(bufferHandle);
220         native_handle_close(buffer);
221         native_handle_delete(buffer);
222     }
223 }
224 
lock(const native_handle_t * bufferHandle,uint64_t cpuUsage,const IMapper::Rect & accessRegion,int acquireFence)225 void* Gralloc::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
226                     const IMapper::Rect& accessRegion, int acquireFence) {
227     auto buffer = const_cast<native_handle_t*>(bufferHandle);
228 
229     NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
230     hidl_handle acquireFenceHandle;
231     if (acquireFence >= 0) {
232         auto h = native_handle_init(acquireFenceStorage, 1, 0);
233         h->data[0] = acquireFence;
234         acquireFenceHandle = h;
235     }
236 
237     void* data = nullptr;
238     mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
239                   [&](const auto& tmpError, const auto& tmpData) {
240                       ASSERT_EQ(Error::NONE, tmpError) << "failed to lock buffer " << buffer;
241                       data = tmpData;
242                   });
243 
244     if (acquireFence >= 0) {
245         close(acquireFence);
246     }
247 
248     return data;
249 }
250 
unlock(const native_handle_t * bufferHandle)251 int Gralloc::unlock(const native_handle_t* bufferHandle) {
252     auto buffer = const_cast<native_handle_t*>(bufferHandle);
253 
254     int releaseFence = -1;
255     mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
256         ASSERT_EQ(Error::NONE, tmpError) << "failed to unlock buffer " << buffer;
257 
258         auto fenceHandle = tmpReleaseFence.getNativeHandle();
259         if (fenceHandle) {
260             ASSERT_EQ(0, fenceHandle->numInts) << "invalid fence handle " << fenceHandle;
261             if (fenceHandle->numFds == 1) {
262                 releaseFence = dup(fenceHandle->data[0]);
263                 ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
264             } else {
265                 ASSERT_EQ(0, fenceHandle->numFds) << " invalid fence handle " << fenceHandle;
266             }
267         }
268     });
269 
270     return releaseFence;
271 }
272 
flushLockedBuffer(const native_handle_t * bufferHandle)273 int Gralloc::flushLockedBuffer(const native_handle_t* bufferHandle) {
274     auto buffer = const_cast<native_handle_t*>(bufferHandle);
275 
276     int releaseFence = -1;
277     mMapper->flushLockedBuffer(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
278         ASSERT_EQ(Error::NONE, tmpError) << "failed to flush locked buffer " << buffer;
279 
280         auto fenceHandle = tmpReleaseFence.getNativeHandle();
281         if (fenceHandle) {
282             ASSERT_EQ(0, fenceHandle->numInts) << "invalid fence handle " << fenceHandle;
283             if (fenceHandle->numFds == 1) {
284                 releaseFence = dup(fenceHandle->data[0]);
285                 ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
286             } else {
287                 ASSERT_EQ(0, fenceHandle->numFds) << " invalid fence handle " << fenceHandle;
288             }
289         }
290     });
291 
292     return releaseFence;
293 }
294 
rereadLockedBuffer(const native_handle_t * bufferHandle)295 void Gralloc::rereadLockedBuffer(const native_handle_t* bufferHandle) {
296     auto buffer = const_cast<native_handle_t*>(bufferHandle);
297 
298     ASSERT_EQ(Error::NONE, mMapper->rereadLockedBuffer(buffer));
299 }
300 
validateBufferSize(const native_handle_t * bufferHandle,const IMapper::BufferDescriptorInfo & descriptorInfo,uint32_t stride)301 bool Gralloc::validateBufferSize(const native_handle_t* bufferHandle,
302                                  const IMapper::BufferDescriptorInfo& descriptorInfo,
303                                  uint32_t stride) {
304     auto buffer = const_cast<native_handle_t*>(bufferHandle);
305 
306     Error error = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
307     return error == Error::NONE;
308 }
309 
getTransportSize(const native_handle_t * bufferHandle,uint32_t * outNumFds,uint32_t * outNumInts)310 void Gralloc::getTransportSize(const native_handle_t* bufferHandle, uint32_t* outNumFds,
311                                uint32_t* outNumInts) {
312     auto buffer = const_cast<native_handle_t*>(bufferHandle);
313 
314     *outNumFds = 0;
315     *outNumInts = 0;
316     mMapper->getTransportSize(buffer, [&](const auto& tmpError, const auto& tmpNumFds,
317                                           const auto& tmpNumInts) {
318         ASSERT_EQ(Error::NONE, tmpError) << "failed to get transport size";
319         ASSERT_GE(bufferHandle->numFds, int(tmpNumFds)) << "invalid numFds " << tmpNumFds;
320         ASSERT_GE(bufferHandle->numInts, int(tmpNumInts)) << "invalid numInts " << tmpNumInts;
321 
322         *outNumFds = tmpNumFds;
323         *outNumInts = tmpNumInts;
324     });
325 }
326 
isSupported(const IMapper::BufferDescriptorInfo & descriptorInfo)327 bool Gralloc::isSupported(const IMapper::BufferDescriptorInfo& descriptorInfo) {
328     bool supported = false;
329     mMapper->isSupported(descriptorInfo, [&](const auto& tmpError, const auto& tmpSupported) {
330         ASSERT_EQ(Error::NONE, tmpError) << "failed to check is supported";
331         supported = tmpSupported;
332     });
333     return supported;
334 }
335 
isSupportedNoFailure(const IMapper::BufferDescriptorInfo & descriptorInfo)336 bool Gralloc::isSupportedNoFailure(const IMapper::BufferDescriptorInfo& descriptorInfo) {
337     bool supported = false;
338     mMapper->isSupported(descriptorInfo, [&](const auto& tmpError, const auto& tmpSupported) {
339         supported = tmpSupported && tmpError == Error::NONE;
340     });
341     return supported;
342 }
343 
get(const native_handle_t * bufferHandle,const IMapper::MetadataType & metadataType,hidl_vec<uint8_t> * outVec)344 Error Gralloc::get(const native_handle_t* bufferHandle, const IMapper::MetadataType& metadataType,
345                    hidl_vec<uint8_t>* outVec) {
346     Error err;
347     mMapper->get(const_cast<native_handle_t*>(bufferHandle), metadataType,
348                  [&](const auto& tmpError, const hidl_vec<uint8_t>& tmpVec) {
349                      err = tmpError;
350                      *outVec = tmpVec;
351                  });
352     return err;
353 }
354 
set(const native_handle_t * bufferHandle,const IMapper::MetadataType & metadataType,const hidl_vec<uint8_t> & vec)355 Error Gralloc::set(const native_handle_t* bufferHandle, const IMapper::MetadataType& metadataType,
356                    const hidl_vec<uint8_t>& vec) {
357     return mMapper->set(const_cast<native_handle_t*>(bufferHandle), metadataType, vec);
358 }
359 
getFromBufferDescriptorInfo(const IMapper::BufferDescriptorInfo & descriptorInfo,const IMapper::MetadataType & metadataType,hidl_vec<uint8_t> * outVec)360 Error Gralloc::getFromBufferDescriptorInfo(const IMapper::BufferDescriptorInfo& descriptorInfo,
361                                            const IMapper::MetadataType& metadataType,
362                                            hidl_vec<uint8_t>* outVec) {
363     Error err;
364     mMapper->getFromBufferDescriptorInfo(
365             descriptorInfo, metadataType,
366             [&](const auto& tmpError, const hidl_vec<uint8_t>& tmpVec) {
367                 err = tmpError;
368                 *outVec = tmpVec;
369             });
370     return err;
371 }
372 
getReservedRegion(const native_handle_t * bufferHandle,void ** outReservedRegion,uint64_t * outReservedSize)373 Error Gralloc::getReservedRegion(const native_handle_t* bufferHandle, void** outReservedRegion,
374                                  uint64_t* outReservedSize) {
375     Error err;
376     mMapper->getReservedRegion(
377             const_cast<native_handle_t*>(bufferHandle),
378             [&](const auto& tmpError, const auto& tmpReservedRegion, const auto& tmpReservedSize) {
379                 err = tmpError;
380                 *outReservedRegion = tmpReservedRegion;
381                 *outReservedSize = tmpReservedSize;
382             });
383     return err;
384 }
385 
386 }  // namespace vts
387 }  // namespace V4_0
388 }  // namespace mapper
389 }  // namespace graphics
390 }  // namespace hardware
391 }  // namespace android
392