• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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/2.0/MapperVts.h>
18 
19 #include <VtsHalHidlTargetTestBase.h>
20 
21 namespace android {
22 namespace hardware {
23 namespace graphics {
24 namespace mapper {
25 namespace V2_0 {
26 namespace vts {
27 
Gralloc(const std::string & allocatorServiceName,const std::string & mapperServiceName)28 Gralloc::Gralloc(const std::string& allocatorServiceName, const std::string& mapperServiceName) {
29     init(allocatorServiceName, mapperServiceName);
30 }
31 
init(const std::string & allocatorServiceName,const std::string & mapperServiceName)32 void Gralloc::init(const std::string& allocatorServiceName, const std::string& mapperServiceName) {
33     mAllocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>(allocatorServiceName);
34     ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
35 
36     mMapper = ::testing::VtsHalHidlTargetTestBase::getService<IMapper>(mapperServiceName);
37     ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
38     ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
39 }
40 
~Gralloc()41 Gralloc::~Gralloc() {
42     for (auto bufferHandle : mClonedBuffers) {
43         auto buffer = const_cast<native_handle_t*>(bufferHandle);
44         native_handle_close(buffer);
45         native_handle_delete(buffer);
46     }
47     mClonedBuffers.clear();
48 
49     for (auto bufferHandle : mImportedBuffers) {
50         auto buffer = const_cast<native_handle_t*>(bufferHandle);
51         EXPECT_EQ(Error::NONE, mMapper->freeBuffer(buffer)) << "failed to free buffer " << buffer;
52     }
53     mImportedBuffers.clear();
54 }
55 
getAllocator() const56 sp<IAllocator> Gralloc::getAllocator() const {
57     return mAllocator;
58 }
59 
dumpDebugInfo()60 std::string Gralloc::dumpDebugInfo() {
61     std::string debugInfo;
62     mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
63 
64     return debugInfo;
65 }
66 
cloneBuffer(const hidl_handle & rawHandle)67 const native_handle_t* Gralloc::cloneBuffer(const hidl_handle& rawHandle) {
68     const native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle());
69     EXPECT_NE(nullptr, bufferHandle);
70 
71     if (bufferHandle) {
72         mClonedBuffers.insert(bufferHandle);
73     }
74 
75     return bufferHandle;
76 }
77 
allocate(const BufferDescriptor & descriptor,uint32_t count,bool import,uint32_t * outStride)78 std::vector<const native_handle_t*> Gralloc::allocate(const BufferDescriptor& descriptor,
79                                                       uint32_t count, bool import,
80                                                       uint32_t* outStride) {
81     std::vector<const native_handle_t*> bufferHandles;
82     bufferHandles.reserve(count);
83     mAllocator->allocate(
84         descriptor, count,
85         [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) {
86             ASSERT_EQ(Error::NONE, tmpError) << "failed to allocate buffers";
87             ASSERT_EQ(count, tmpBuffers.size()) << "invalid buffer array";
88 
89             for (uint32_t i = 0; i < count; i++) {
90                 if (import) {
91                     ASSERT_NO_FATAL_FAILURE(bufferHandles.push_back(importBuffer(tmpBuffers[i])));
92                 } else {
93                     ASSERT_NO_FATAL_FAILURE(bufferHandles.push_back(cloneBuffer(tmpBuffers[i])));
94                 }
95             }
96 
97             if (outStride) {
98                 *outStride = tmpStride;
99             }
100         });
101 
102     if (::testing::Test::HasFatalFailure()) {
103         bufferHandles.clear();
104     }
105 
106     return bufferHandles;
107 }
108 
allocate(const IMapper::BufferDescriptorInfo & descriptorInfo,bool import,uint32_t * outStride)109 const native_handle_t* Gralloc::allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
110                                          bool import, uint32_t* outStride) {
111     BufferDescriptor descriptor = createDescriptor(descriptorInfo);
112     if (::testing::Test::HasFatalFailure()) {
113         return nullptr;
114     }
115 
116     auto buffers = allocate(descriptor, 1, import, outStride);
117     if (::testing::Test::HasFatalFailure()) {
118         return nullptr;
119     }
120 
121     return buffers[0];
122 }
123 
getMapper() const124 sp<IMapper> Gralloc::getMapper() const {
125     return mMapper;
126 }
127 
createDescriptor(const IMapper::BufferDescriptorInfo & descriptorInfo)128 BufferDescriptor Gralloc::createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo) {
129     BufferDescriptor descriptor;
130     mMapper->createDescriptor(descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) {
131         ASSERT_EQ(Error::NONE, tmpError) << "failed to create descriptor";
132         descriptor = tmpDescriptor;
133     });
134 
135     return descriptor;
136 }
137 
importBuffer(const hidl_handle & rawHandle)138 const native_handle_t* Gralloc::importBuffer(const hidl_handle& rawHandle) {
139     const native_handle_t* bufferHandle = nullptr;
140     mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
141         ASSERT_EQ(Error::NONE, tmpError)
142             << "failed to import buffer %p" << rawHandle.getNativeHandle();
143         bufferHandle = static_cast<const native_handle_t*>(tmpBuffer);
144     });
145 
146     if (bufferHandle) {
147         mImportedBuffers.insert(bufferHandle);
148     }
149 
150     return bufferHandle;
151 }
152 
freeBuffer(const native_handle_t * bufferHandle)153 void Gralloc::freeBuffer(const native_handle_t* bufferHandle) {
154     auto buffer = const_cast<native_handle_t*>(bufferHandle);
155 
156     if (mImportedBuffers.erase(bufferHandle)) {
157         Error error = mMapper->freeBuffer(buffer);
158         ASSERT_EQ(Error::NONE, error) << "failed to free buffer " << buffer;
159     } else {
160         mClonedBuffers.erase(bufferHandle);
161         native_handle_close(buffer);
162         native_handle_delete(buffer);
163     }
164 }
165 
lock(const native_handle_t * bufferHandle,uint64_t cpuUsage,const IMapper::Rect & accessRegion,int acquireFence)166 void* Gralloc::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
167                     const IMapper::Rect& accessRegion, int acquireFence) {
168     auto buffer = const_cast<native_handle_t*>(bufferHandle);
169 
170     NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
171     hidl_handle acquireFenceHandle;
172     if (acquireFence >= 0) {
173         auto h = native_handle_init(acquireFenceStorage, 1, 0);
174         h->data[0] = acquireFence;
175         acquireFenceHandle = h;
176     }
177 
178     void* data = nullptr;
179     mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
180                   [&](const auto& tmpError, const auto& tmpData) {
181                       ASSERT_EQ(Error::NONE, tmpError) << "failed to lock buffer " << buffer;
182                       data = tmpData;
183                   });
184 
185     if (acquireFence >= 0) {
186         close(acquireFence);
187     }
188 
189     return data;
190 }
191 
lockYCbCr(const native_handle_t * bufferHandle,uint64_t cpuUsage,const IMapper::Rect & accessRegion,int acquireFence)192 YCbCrLayout Gralloc::lockYCbCr(const native_handle_t* bufferHandle, uint64_t cpuUsage,
193                                const IMapper::Rect& accessRegion, int acquireFence) {
194     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 
204     YCbCrLayout layout = {};
205     mMapper->lockYCbCr(buffer, cpuUsage, accessRegion, acquireFenceHandle,
206                        [&](const auto& tmpError, const auto& tmpLayout) {
207                            ASSERT_EQ(Error::NONE, tmpError)
208                                << "failed to lockYCbCr buffer " << buffer;
209                            layout = tmpLayout;
210                        });
211 
212     if (acquireFence >= 0) {
213         close(acquireFence);
214     }
215 
216     return layout;
217 }
218 
unlock(const native_handle_t * bufferHandle)219 int Gralloc::unlock(const native_handle_t* bufferHandle) {
220     auto buffer = const_cast<native_handle_t*>(bufferHandle);
221 
222     int releaseFence = -1;
223     mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
224         ASSERT_EQ(Error::NONE, tmpError) << "failed to unlock buffer " << buffer;
225 
226         auto fenceHandle = tmpReleaseFence.getNativeHandle();
227         if (fenceHandle) {
228             ASSERT_EQ(0, fenceHandle->numInts) << "invalid fence handle " << fenceHandle;
229             if (fenceHandle->numFds == 1) {
230                 releaseFence = dup(fenceHandle->data[0]);
231                 ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
232             } else {
233                 ASSERT_EQ(0, fenceHandle->numFds) << " invalid fence handle " << fenceHandle;
234             }
235         }
236     });
237 
238     return releaseFence;
239 }
240 
241 }  // namespace vts
242 }  // namespace V2_0
243 }  // namespace mapper
244 }  // namespace graphics
245 }  // namespace hardware
246 }  // namespace android
247