blob: f2b7594b3ffe31d29209d42f2df8526760132a67 [file] [log] [blame]
Marissa Wallbd1ca512018-12-30 10:59:41 -08001/*
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
21namespace android {
22namespace hardware {
23namespace graphics {
24namespace mapper {
25namespace V3_0 {
26namespace vts {
27
28Gralloc::Gralloc(const std::string& allocatorServiceName, const std::string& mapperServiceName) {
29 init(allocatorServiceName, mapperServiceName);
30}
31
32void 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
41Gralloc::~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
56sp<IAllocator> Gralloc::getAllocator() const {
57 return mAllocator;
58}
59
60std::string Gralloc::dumpDebugInfo() {
61 std::string debugInfo;
62 mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
63
64 return debugInfo;
65}
66
67const 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
78std::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
109const 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
124sp<IMapper> Gralloc::getMapper() const {
125 return mMapper;
126}
127
128BufferDescriptor 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
138const 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
153void 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
166void* Gralloc::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
Marissa Wall69292fa2018-12-30 12:37:18 -0800167 const IMapper::Rect& accessRegion, int acquireFence, int32_t* outBytesPerPixel,
168 int32_t* outBytesPerStride) {
Marissa Wallbd1ca512018-12-30 10:59:41 -0800169 auto buffer = const_cast<native_handle_t*>(bufferHandle);
170
171 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
172 hidl_handle acquireFenceHandle;
173 if (acquireFence >= 0) {
174 auto h = native_handle_init(acquireFenceStorage, 1, 0);
175 h->data[0] = acquireFence;
176 acquireFenceHandle = h;
177 }
178
Marissa Walla6a30b12018-12-30 12:48:46 -0800179 *outBytesPerPixel = -1;
180 *outBytesPerStride = -1;
181
Marissa Wallbd1ca512018-12-30 10:59:41 -0800182 void* data = nullptr;
183 mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
Marissa Wall69292fa2018-12-30 12:37:18 -0800184 [&](const auto& tmpError, const auto& tmpData, int32_t tmpBytesPerPixel,
185 int32_t tmpBytesPerStride) {
Marissa Wallbd1ca512018-12-30 10:59:41 -0800186 ASSERT_EQ(Error::NONE, tmpError) << "failed to lock buffer " << buffer;
187 data = tmpData;
Marissa Wall69292fa2018-12-30 12:37:18 -0800188 *outBytesPerPixel = tmpBytesPerPixel;
189 *outBytesPerStride = tmpBytesPerStride;
Marissa Wallbd1ca512018-12-30 10:59:41 -0800190 });
191
192 if (acquireFence >= 0) {
193 close(acquireFence);
194 }
195
196 return data;
197}
198
199YCbCrLayout Gralloc::lockYCbCr(const native_handle_t* bufferHandle, uint64_t cpuUsage,
200 const IMapper::Rect& accessRegion, int acquireFence) {
201 auto buffer = const_cast<native_handle_t*>(bufferHandle);
202
203 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
204 hidl_handle acquireFenceHandle;
205 if (acquireFence >= 0) {
206 auto h = native_handle_init(acquireFenceStorage, 1, 0);
207 h->data[0] = acquireFence;
208 acquireFenceHandle = h;
209 }
210
211 YCbCrLayout layout = {};
212 mMapper->lockYCbCr(buffer, cpuUsage, accessRegion, acquireFenceHandle,
213 [&](const auto& tmpError, const auto& tmpLayout) {
214 ASSERT_EQ(Error::NONE, tmpError)
215 << "failed to lockYCbCr buffer " << buffer;
216 layout = tmpLayout;
217 });
218
219 if (acquireFence >= 0) {
220 close(acquireFence);
221 }
222
223 return layout;
224}
225
226int Gralloc::unlock(const native_handle_t* bufferHandle) {
227 auto buffer = const_cast<native_handle_t*>(bufferHandle);
228
229 int releaseFence = -1;
230 mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
231 ASSERT_EQ(Error::NONE, tmpError) << "failed to unlock buffer " << buffer;
232
233 auto fenceHandle = tmpReleaseFence.getNativeHandle();
234 if (fenceHandle) {
235 ASSERT_EQ(0, fenceHandle->numInts) << "invalid fence handle " << fenceHandle;
236 if (fenceHandle->numFds == 1) {
237 releaseFence = dup(fenceHandle->data[0]);
238 ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
239 } else {
240 ASSERT_EQ(0, fenceHandle->numFds) << " invalid fence handle " << fenceHandle;
241 }
242 }
243 });
244
245 return releaseFence;
246}
247
248bool Gralloc::validateBufferSize(const native_handle_t* bufferHandle,
249 const IMapper::BufferDescriptorInfo& descriptorInfo,
250 uint32_t stride) {
251 auto buffer = const_cast<native_handle_t*>(bufferHandle);
252
253 Error error = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
254 return error == Error::NONE;
255}
256
257void Gralloc::getTransportSize(const native_handle_t* bufferHandle, uint32_t* outNumFds,
258 uint32_t* outNumInts) {
259 auto buffer = const_cast<native_handle_t*>(bufferHandle);
260
261 *outNumFds = 0;
262 *outNumInts = 0;
263 mMapper->getTransportSize(
264 buffer, [&](const auto& tmpError, const auto& tmpNumFds, const auto& tmpNumInts) {
265 ASSERT_EQ(Error::NONE, tmpError) << "failed to get transport size";
266 ASSERT_GE(bufferHandle->numFds, int(tmpNumFds)) << "invalid numFds " << tmpNumFds;
267 ASSERT_GE(bufferHandle->numInts, int(tmpNumInts)) << "invalid numInts " << tmpNumInts;
268
269 *outNumFds = tmpNumFds;
270 *outNumInts = tmpNumInts;
271 });
272}
273
Marissa Walla6a30b12018-12-30 12:48:46 -0800274bool Gralloc::isSupported(const IMapper::BufferDescriptorInfo& descriptorInfo) {
275 bool supported = false;
276 mMapper->isSupported(descriptorInfo, [&](const auto& tmpError, const auto& tmpSupported) {
277 ASSERT_EQ(Error::NONE, tmpError) << "failed to check is supported";
278 supported = tmpSupported;
279 });
280 return supported;
281}
282
Marissa Wallbd1ca512018-12-30 10:59:41 -0800283} // namespace vts
284} // namespace V3_0
285} // namespace mapper
286} // namespace graphics
287} // namespace hardware
288} // namespace android