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