blob: d08ac5608570322c758352863ef97181c7fb62c5 [file] [log] [blame]
Chia-I Wu89d09dd2017-02-24 10:41:35 -08001/*
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
Chia-I Wu98923fc2018-01-14 21:45:18 -080017#include <mapper-vts/2.0/MapperVts.h>
Chia-I Wu89d09dd2017-02-24 10:41:35 -080018
Chia-I Wu98923fc2018-01-14 21:45:18 -080019#include <VtsHalHidlTargetTestBase.h>
Chia-I Wu89d09dd2017-02-24 10:41:35 -080020
21namespace android {
22namespace hardware {
23namespace graphics {
24namespace mapper {
25namespace V2_0 {
Chia-I Wu98923fc2018-01-14 21:45:18 -080026namespace vts {
Chia-I Wu89d09dd2017-02-24 10:41:35 -080027
Chia-I Wu98923fc2018-01-14 21:45:18 -080028Gralloc::Gralloc(const std::string& allocatorServiceName, const std::string& mapperServiceName) {
29 init(allocatorServiceName, mapperServiceName);
Chia-I Wu89d09dd2017-02-24 10:41:35 -080030}
31
Chia-I Wu98923fc2018-01-14 21:45:18 -080032void Gralloc::init(const std::string& allocatorServiceName, const std::string& mapperServiceName) {
33 mAllocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>(allocatorServiceName);
Chia-I Wu79d13ff2017-03-31 12:48:11 -070034 ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
35
Chia-I Wu98923fc2018-01-14 21:45:18 -080036 mMapper = ::testing::VtsHalHidlTargetTestBase::getService<IMapper>(mapperServiceName);
Chia-I Wu79d13ff2017-03-31 12:48:11 -070037 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);
Chia-I Wu89d09dd2017-02-24 10:41:35 -080046 }
Chia-I Wu79d13ff2017-03-31 12:48:11 -070047 mClonedBuffers.clear();
48
49 for (auto bufferHandle : mImportedBuffers) {
50 auto buffer = const_cast<native_handle_t*>(bufferHandle);
Chia-I Wu5255c352017-12-15 11:33:25 -080051 EXPECT_EQ(Error::NONE, mMapper->freeBuffer(buffer)) << "failed to free buffer " << buffer;
Chia-I Wu79d13ff2017-03-31 12:48:11 -070052 }
53 mImportedBuffers.clear();
Chia-I Wu89d09dd2017-02-24 10:41:35 -080054}
55
Chia-I Wu79d13ff2017-03-31 12:48:11 -070056sp<IAllocator> Gralloc::getAllocator() const {
57 return mAllocator;
Chia-I Wu89d09dd2017-02-24 10:41:35 -080058}
59
Chia-I Wu79d13ff2017-03-31 12:48:11 -070060std::string Gralloc::dumpDebugInfo() {
61 std::string debugInfo;
Chia-I Wu5255c352017-12-15 11:33:25 -080062 mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
Chia-I Wu89d09dd2017-02-24 10:41:35 -080063
Chia-I Wu79d13ff2017-03-31 12:48:11 -070064 return debugInfo;
Chia-I Wu89d09dd2017-02-24 10:41:35 -080065}
66
Chia-I Wu79d13ff2017-03-31 12:48:11 -070067const native_handle_t* Gralloc::cloneBuffer(const hidl_handle& rawHandle) {
Chia-I Wu5255c352017-12-15 11:33:25 -080068 const native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle());
Chia-I Wu79d13ff2017-03-31 12:48:11 -070069 EXPECT_NE(nullptr, bufferHandle);
Chia-I Wu89d09dd2017-02-24 10:41:35 -080070
Chia-I Wu79d13ff2017-03-31 12:48:11 -070071 if (bufferHandle) {
72 mClonedBuffers.insert(bufferHandle);
73 }
74
75 return bufferHandle;
Chia-I Wu89d09dd2017-02-24 10:41:35 -080076}
77
Chia-I Wu5255c352017-12-15 11:33:25 -080078std::vector<const native_handle_t*> Gralloc::allocate(const BufferDescriptor& descriptor,
79 uint32_t count, bool import,
80 uint32_t* outStride) {
Chia-I Wu79d13ff2017-03-31 12:48:11 -070081 std::vector<const native_handle_t*> bufferHandles;
82 bufferHandles.reserve(count);
83 mAllocator->allocate(
Chia-I Wu5255c352017-12-15 11:33:25 -080084 descriptor, count,
85 [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) {
Chia-I Wu79d13ff2017-03-31 12:48:11 -070086 ASSERT_EQ(Error::NONE, tmpError) << "failed to allocate buffers";
87 ASSERT_EQ(count, tmpBuffers.size()) << "invalid buffer array";
Chia-I Wu89d09dd2017-02-24 10:41:35 -080088
Chia-I Wu79d13ff2017-03-31 12:48:11 -070089 for (uint32_t i = 0; i < count; i++) {
90 if (import) {
Chia-I Wu5255c352017-12-15 11:33:25 -080091 ASSERT_NO_FATAL_FAILURE(bufferHandles.push_back(importBuffer(tmpBuffers[i])));
Chia-I Wu79d13ff2017-03-31 12:48:11 -070092 } else {
Chia-I Wu5255c352017-12-15 11:33:25 -080093 ASSERT_NO_FATAL_FAILURE(bufferHandles.push_back(cloneBuffer(tmpBuffers[i])));
Chia-I Wu79d13ff2017-03-31 12:48:11 -070094 }
95 }
96
97 if (outStride) {
98 *outStride = tmpStride;
99 }
100 });
101
102 if (::testing::Test::HasFatalFailure()) {
103 bufferHandles.clear();
104 }
105
106 return bufferHandles;
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800107}
108
Chia-I Wu5255c352017-12-15 11:33:25 -0800109const native_handle_t* Gralloc::allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
110 bool import, uint32_t* outStride) {
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700111 BufferDescriptor descriptor = createDescriptor(descriptorInfo);
112 if (::testing::Test::HasFatalFailure()) {
113 return nullptr;
114 }
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800115
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700116 auto buffers = allocate(descriptor, 1, import, outStride);
117 if (::testing::Test::HasFatalFailure()) {
118 return nullptr;
119 }
120
121 return buffers[0];
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800122}
123
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700124sp<IMapper> Gralloc::getMapper() const {
125 return mMapper;
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800126}
127
Chia-I Wu5255c352017-12-15 11:33:25 -0800128BufferDescriptor Gralloc::createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo) {
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700129 BufferDescriptor descriptor;
Chia-I Wu5255c352017-12-15 11:33:25 -0800130 mMapper->createDescriptor(descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) {
131 ASSERT_EQ(Error::NONE, tmpError) << "failed to create descriptor";
132 descriptor = tmpDescriptor;
133 });
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800134
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700135 return descriptor;
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800136}
137
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700138const native_handle_t* Gralloc::importBuffer(const hidl_handle& rawHandle) {
139 const native_handle_t* bufferHandle = nullptr;
Chia-I Wu5255c352017-12-15 11:33:25 -0800140 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 });
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800145
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700146 if (bufferHandle) {
147 mImportedBuffers.insert(bufferHandle);
148 }
149
150 return bufferHandle;
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800151}
152
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700153void Gralloc::freeBuffer(const native_handle_t* bufferHandle) {
154 auto buffer = const_cast<native_handle_t*>(bufferHandle);
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800155
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700156 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 }
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800164}
165
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700166void* Gralloc::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
167 const IMapper::Rect& accessRegion, int acquireFence) {
168 auto buffer = const_cast<native_handle_t*>(bufferHandle);
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800169
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700170 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
171 hidl_handle acquireFenceHandle;
172 if (acquireFence >= 0) {
173 auto h = native_handle_init(acquireFenceStorage, 1, 0);
174 h->data[0] = acquireFence;
175 acquireFenceHandle = h;
176 }
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800177
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700178 void* data = nullptr;
179 mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
180 [&](const auto& tmpError, const auto& tmpData) {
Chia-I Wu5255c352017-12-15 11:33:25 -0800181 ASSERT_EQ(Error::NONE, tmpError) << "failed to lock buffer " << buffer;
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700182 data = tmpData;
183 });
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800184
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700185 if (acquireFence >= 0) {
186 close(acquireFence);
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800187 }
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800188
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700189 return data;
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800190}
191
Chia-I Wu5255c352017-12-15 11:33:25 -0800192YCbCrLayout Gralloc::lockYCbCr(const native_handle_t* bufferHandle, uint64_t cpuUsage,
193 const IMapper::Rect& accessRegion, int acquireFence) {
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700194 auto buffer = const_cast<native_handle_t*>(bufferHandle);
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800195
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700196 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
197 hidl_handle acquireFenceHandle;
198 if (acquireFence >= 0) {
199 auto h = native_handle_init(acquireFenceStorage, 1, 0);
200 h->data[0] = acquireFence;
201 acquireFenceHandle = h;
202 }
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800203
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700204 YCbCrLayout layout = {};
205 mMapper->lockYCbCr(buffer, cpuUsage, accessRegion, acquireFenceHandle,
206 [&](const auto& tmpError, const auto& tmpLayout) {
207 ASSERT_EQ(Error::NONE, tmpError)
208 << "failed to lockYCbCr buffer " << buffer;
209 layout = tmpLayout;
210 });
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800211
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700212 if (acquireFence >= 0) {
213 close(acquireFence);
214 }
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800215
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700216 return layout;
217}
218
219int Gralloc::unlock(const native_handle_t* bufferHandle) {
220 auto buffer = const_cast<native_handle_t*>(bufferHandle);
221
222 int releaseFence = -1;
Chia-I Wu5255c352017-12-15 11:33:25 -0800223 mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
224 ASSERT_EQ(Error::NONE, tmpError) << "failed to unlock buffer " << buffer;
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700225
Chia-I Wu5255c352017-12-15 11:33:25 -0800226 auto fenceHandle = tmpReleaseFence.getNativeHandle();
227 if (fenceHandle) {
228 ASSERT_EQ(0, fenceHandle->numInts) << "invalid fence handle " << fenceHandle;
229 if (fenceHandle->numFds == 1) {
230 releaseFence = dup(fenceHandle->data[0]);
231 ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
232 } else {
233 ASSERT_EQ(0, fenceHandle->numFds) << " invalid fence handle " << fenceHandle;
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700234 }
Chia-I Wu5255c352017-12-15 11:33:25 -0800235 }
236 });
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700237
238 return releaseFence;
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800239}
240
Chia-I Wu98923fc2018-01-14 21:45:18 -0800241} // namespace vts
Chia-I Wu89d09dd2017-02-24 10:41:35 -0800242} // namespace V2_0
243} // namespace mapper
244} // namespace graphics
245} // namespace hardware
246} // namespace android