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