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