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