blob: de886a9c705084bd145669e61a9f8e34087b5191 [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
Marissa Wallbd1ca512018-12-30 10:59:41 -080019namespace android {
20namespace hardware {
21namespace graphics {
22namespace mapper {
23namespace V3_0 {
24namespace vts {
25
Valerie Haudca469c2019-06-13 09:49:44 -070026Gralloc::Gralloc(const std::string& allocatorServiceName, const std::string& mapperServiceName,
27 bool errOnFailure) {
28 if (errOnFailure) {
29 init(allocatorServiceName, mapperServiceName);
30 } else {
31 initNoErr(allocatorServiceName, mapperServiceName);
32 }
Marissa Wallbd1ca512018-12-30 10:59:41 -080033}
34
35void Gralloc::init(const std::string& allocatorServiceName, const std::string& mapperServiceName) {
Dan Shi5a955bc2019-12-06 15:43:01 -080036 mAllocator = IAllocator::getService(allocatorServiceName);
Marissa Wallbd1ca512018-12-30 10:59:41 -080037 ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
38
Dan Shi5a955bc2019-12-06 15:43:01 -080039 mMapper = IMapper::getService(mapperServiceName);
Marissa Wallbd1ca512018-12-30 10:59:41 -080040 ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
41 ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
42}
43
Valerie Haudca469c2019-06-13 09:49:44 -070044void Gralloc::initNoErr(const std::string& allocatorServiceName,
45 const std::string& mapperServiceName) {
Dan Shi5a955bc2019-12-06 15:43:01 -080046 mAllocator = IAllocator::getService(allocatorServiceName);
Valerie Haudca469c2019-06-13 09:49:44 -070047
Dan Shi5a955bc2019-12-06 15:43:01 -080048 mMapper = IMapper::getService(mapperServiceName);
Valerie Haudca469c2019-06-13 09:49:44 -070049 if (mMapper.get()) {
50 ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
51 }
52}
53
Marissa Wallbd1ca512018-12-30 10:59:41 -080054Gralloc::~Gralloc() {
55 for (auto bufferHandle : mClonedBuffers) {
56 auto buffer = const_cast<native_handle_t*>(bufferHandle);
57 native_handle_close(buffer);
58 native_handle_delete(buffer);
59 }
60 mClonedBuffers.clear();
61
62 for (auto bufferHandle : mImportedBuffers) {
63 auto buffer = const_cast<native_handle_t*>(bufferHandle);
64 EXPECT_EQ(Error::NONE, mMapper->freeBuffer(buffer)) << "failed to free buffer " << buffer;
65 }
66 mImportedBuffers.clear();
67}
68
69sp<IAllocator> Gralloc::getAllocator() const {
70 return mAllocator;
71}
72
73std::string Gralloc::dumpDebugInfo() {
74 std::string debugInfo;
75 mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
76
77 return debugInfo;
78}
79
80const native_handle_t* Gralloc::cloneBuffer(const hidl_handle& rawHandle) {
81 const native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle());
82 EXPECT_NE(nullptr, bufferHandle);
83
84 if (bufferHandle) {
85 mClonedBuffers.insert(bufferHandle);
86 }
87
88 return bufferHandle;
89}
90
91std::vector<const native_handle_t*> Gralloc::allocate(const BufferDescriptor& descriptor,
92 uint32_t count, bool import,
93 uint32_t* outStride) {
94 std::vector<const native_handle_t*> bufferHandles;
95 bufferHandles.reserve(count);
96 mAllocator->allocate(
97 descriptor, count,
98 [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) {
99 ASSERT_EQ(Error::NONE, tmpError) << "failed to allocate buffers";
100 ASSERT_EQ(count, tmpBuffers.size()) << "invalid buffer array";
101
102 for (uint32_t i = 0; i < count; i++) {
103 if (import) {
104 ASSERT_NO_FATAL_FAILURE(bufferHandles.push_back(importBuffer(tmpBuffers[i])));
105 } else {
106 ASSERT_NO_FATAL_FAILURE(bufferHandles.push_back(cloneBuffer(tmpBuffers[i])));
107 }
108 }
109
110 if (outStride) {
111 *outStride = tmpStride;
112 }
113 });
114
115 if (::testing::Test::HasFatalFailure()) {
116 bufferHandles.clear();
117 }
118
119 return bufferHandles;
120}
121
122const native_handle_t* Gralloc::allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
123 bool import, uint32_t* outStride) {
124 BufferDescriptor descriptor = createDescriptor(descriptorInfo);
125 if (::testing::Test::HasFatalFailure()) {
126 return nullptr;
127 }
128
129 auto buffers = allocate(descriptor, 1, import, outStride);
130 if (::testing::Test::HasFatalFailure()) {
131 return nullptr;
132 }
133
134 return buffers[0];
135}
136
137sp<IMapper> Gralloc::getMapper() const {
138 return mMapper;
139}
140
141BufferDescriptor Gralloc::createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo) {
142 BufferDescriptor descriptor;
143 mMapper->createDescriptor(descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) {
144 ASSERT_EQ(Error::NONE, tmpError) << "failed to create descriptor";
145 descriptor = tmpDescriptor;
146 });
147
148 return descriptor;
149}
150
151const native_handle_t* Gralloc::importBuffer(const hidl_handle& rawHandle) {
152 const native_handle_t* bufferHandle = nullptr;
153 mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
154 ASSERT_EQ(Error::NONE, tmpError)
155 << "failed to import buffer %p" << rawHandle.getNativeHandle();
156 bufferHandle = static_cast<const native_handle_t*>(tmpBuffer);
157 });
158
159 if (bufferHandle) {
160 mImportedBuffers.insert(bufferHandle);
161 }
162
163 return bufferHandle;
164}
165
166void Gralloc::freeBuffer(const native_handle_t* bufferHandle) {
167 auto buffer = const_cast<native_handle_t*>(bufferHandle);
168
169 if (mImportedBuffers.erase(bufferHandle)) {
170 Error error = mMapper->freeBuffer(buffer);
171 ASSERT_EQ(Error::NONE, error) << "failed to free buffer " << buffer;
172 } else {
173 mClonedBuffers.erase(bufferHandle);
174 native_handle_close(buffer);
175 native_handle_delete(buffer);
176 }
177}
178
179void* Gralloc::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
Marissa Wall69292fa2018-12-30 12:37:18 -0800180 const IMapper::Rect& accessRegion, int acquireFence, int32_t* outBytesPerPixel,
181 int32_t* outBytesPerStride) {
Marissa Wallbd1ca512018-12-30 10:59:41 -0800182 auto buffer = const_cast<native_handle_t*>(bufferHandle);
183
184 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
185 hidl_handle acquireFenceHandle;
186 if (acquireFence >= 0) {
187 auto h = native_handle_init(acquireFenceStorage, 1, 0);
188 h->data[0] = acquireFence;
189 acquireFenceHandle = h;
190 }
191
Marissa Walla6a30b12018-12-30 12:48:46 -0800192 *outBytesPerPixel = -1;
193 *outBytesPerStride = -1;
194
Marissa Wallbd1ca512018-12-30 10:59:41 -0800195 void* data = nullptr;
196 mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
Marissa Wall69292fa2018-12-30 12:37:18 -0800197 [&](const auto& tmpError, const auto& tmpData, int32_t tmpBytesPerPixel,
198 int32_t tmpBytesPerStride) {
Marissa Wallbd1ca512018-12-30 10:59:41 -0800199 ASSERT_EQ(Error::NONE, tmpError) << "failed to lock buffer " << buffer;
200 data = tmpData;
Marissa Wall69292fa2018-12-30 12:37:18 -0800201 *outBytesPerPixel = tmpBytesPerPixel;
202 *outBytesPerStride = tmpBytesPerStride;
Marissa Wallbd1ca512018-12-30 10:59:41 -0800203 });
204
205 if (acquireFence >= 0) {
206 close(acquireFence);
207 }
208
209 return data;
210}
211
212YCbCrLayout Gralloc::lockYCbCr(const native_handle_t* bufferHandle, uint64_t cpuUsage,
213 const IMapper::Rect& accessRegion, int acquireFence) {
214 auto buffer = const_cast<native_handle_t*>(bufferHandle);
215
216 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
217 hidl_handle acquireFenceHandle;
218 if (acquireFence >= 0) {
219 auto h = native_handle_init(acquireFenceStorage, 1, 0);
220 h->data[0] = acquireFence;
221 acquireFenceHandle = h;
222 }
223
224 YCbCrLayout layout = {};
225 mMapper->lockYCbCr(buffer, cpuUsage, accessRegion, acquireFenceHandle,
226 [&](const auto& tmpError, const auto& tmpLayout) {
227 ASSERT_EQ(Error::NONE, tmpError)
228 << "failed to lockYCbCr buffer " << buffer;
229 layout = tmpLayout;
230 });
231
232 if (acquireFence >= 0) {
233 close(acquireFence);
234 }
235
236 return layout;
237}
238
239int Gralloc::unlock(const native_handle_t* bufferHandle) {
240 auto buffer = const_cast<native_handle_t*>(bufferHandle);
241
242 int releaseFence = -1;
243 mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
244 ASSERT_EQ(Error::NONE, tmpError) << "failed to unlock buffer " << buffer;
245
246 auto fenceHandle = tmpReleaseFence.getNativeHandle();
247 if (fenceHandle) {
248 ASSERT_EQ(0, fenceHandle->numInts) << "invalid fence handle " << fenceHandle;
249 if (fenceHandle->numFds == 1) {
250 releaseFence = dup(fenceHandle->data[0]);
251 ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
252 } else {
253 ASSERT_EQ(0, fenceHandle->numFds) << " invalid fence handle " << fenceHandle;
254 }
255 }
256 });
257
258 return releaseFence;
259}
260
261bool Gralloc::validateBufferSize(const native_handle_t* bufferHandle,
262 const IMapper::BufferDescriptorInfo& descriptorInfo,
263 uint32_t stride) {
264 auto buffer = const_cast<native_handle_t*>(bufferHandle);
265
266 Error error = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
267 return error == Error::NONE;
268}
269
270void Gralloc::getTransportSize(const native_handle_t* bufferHandle, uint32_t* outNumFds,
271 uint32_t* outNumInts) {
272 auto buffer = const_cast<native_handle_t*>(bufferHandle);
273
274 *outNumFds = 0;
275 *outNumInts = 0;
276 mMapper->getTransportSize(
277 buffer, [&](const auto& tmpError, const auto& tmpNumFds, const auto& tmpNumInts) {
278 ASSERT_EQ(Error::NONE, tmpError) << "failed to get transport size";
279 ASSERT_GE(bufferHandle->numFds, int(tmpNumFds)) << "invalid numFds " << tmpNumFds;
280 ASSERT_GE(bufferHandle->numInts, int(tmpNumInts)) << "invalid numInts " << tmpNumInts;
281
282 *outNumFds = tmpNumFds;
283 *outNumInts = tmpNumInts;
284 });
285}
286
Marissa Walla6a30b12018-12-30 12:48:46 -0800287bool Gralloc::isSupported(const IMapper::BufferDescriptorInfo& descriptorInfo) {
288 bool supported = false;
289 mMapper->isSupported(descriptorInfo, [&](const auto& tmpError, const auto& tmpSupported) {
290 ASSERT_EQ(Error::NONE, tmpError) << "failed to check is supported";
291 supported = tmpSupported;
292 });
293 return supported;
294}
295
Marissa Wallbd1ca512018-12-30 10:59:41 -0800296} // namespace vts
297} // namespace V3_0
298} // namespace mapper
299} // namespace graphics
300} // namespace hardware
301} // namespace android