blob: 1f746a2ed161488a190749e927157f97127ba62e [file] [log] [blame]
Chia-I Wu5bac7f32017-04-06 12:34:32 -07001/*
2 * Copyright 2016 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#define LOG_TAG "Gralloc2"
18
Jesse Hall5dac7812017-07-06 14:02:29 -070019#include <hidl/ServiceManagement.h>
Chia-I Wud8091b92017-05-16 14:30:34 -070020#include <hwbinder/IPCThreadState.h>
Chia-I Wu5bac7f32017-04-06 12:34:32 -070021#include <ui/Gralloc2.h>
22
23#include <log/log.h>
24#pragma clang diagnostic push
25#pragma clang diagnostic ignored "-Wzero-length-array"
26#include <sync/sync.h>
27#pragma clang diagnostic pop
28
29namespace android {
30
31namespace Gralloc2 {
32
33static constexpr Error kTransactionError = Error::NO_RESOURCES;
34
Jesse Hall5dac7812017-07-06 14:02:29 -070035void Mapper::preload() {
36 android::hardware::preloadPassthroughService<hardware::graphics::mapper::V2_0::IMapper>();
37}
38
Chia-I Wu5bac7f32017-04-06 12:34:32 -070039Mapper::Mapper()
40{
41 mMapper = IMapper::getService();
Chia-I Wudbbe33b2017-09-27 15:22:21 -070042 if (mMapper == nullptr) {
43 LOG_ALWAYS_FATAL("gralloc-mapper is missing");
44 }
45 if (mMapper->isRemote()) {
Chia-I Wu5bac7f32017-04-06 12:34:32 -070046 LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
47 }
Chia-I Wudbbe33b2017-09-27 15:22:21 -070048
49 // IMapper 2.1 is optional
50 mMapperV2_1 = hardware::graphics::mapper::V2_1::IMapper::castFrom(mMapper);
Chia-I Wu5bac7f32017-04-06 12:34:32 -070051}
52
53Error Mapper::createDescriptor(
54 const IMapper::BufferDescriptorInfo& descriptorInfo,
55 BufferDescriptor* outDescriptor) const
56{
57 Error error;
58 auto ret = mMapper->createDescriptor(descriptorInfo,
59 [&](const auto& tmpError, const auto& tmpDescriptor)
60 {
61 error = tmpError;
62 if (error != Error::NONE) {
63 return;
64 }
65
66 *outDescriptor = tmpDescriptor;
67 });
68
69 return (ret.isOk()) ? error : kTransactionError;
70}
71
72Error Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
73 buffer_handle_t* outBufferHandle) const
74{
75 Error error;
76 auto ret = mMapper->importBuffer(rawHandle,
77 [&](const auto& tmpError, const auto& tmpBuffer)
78 {
79 error = tmpError;
80 if (error != Error::NONE) {
81 return;
82 }
83
84 *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
85 });
86
87 return (ret.isOk()) ? error : kTransactionError;
88}
89
90void Mapper::freeBuffer(buffer_handle_t bufferHandle) const
91{
92 auto buffer = const_cast<native_handle_t*>(bufferHandle);
93 auto ret = mMapper->freeBuffer(buffer);
94
95 auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
96 ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d",
97 buffer, error);
98}
99
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700100Error Mapper::validateBufferSize(buffer_handle_t bufferHandle,
101 const IMapper::BufferDescriptorInfo& descriptorInfo,
102 uint32_t stride) const
103{
104 if (mMapperV2_1 == nullptr) {
105 return Error::NONE;
106 }
107
108 auto buffer = const_cast<native_handle_t*>(bufferHandle);
109 auto ret = mMapperV2_1->validateBufferSize(buffer, descriptorInfo, stride);
110
111 return (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
112}
113
114void Mapper::getTransportSize(buffer_handle_t bufferHandle,
115 uint32_t* outNumFds, uint32_t* outNumInts) const
116{
117 *outNumFds = uint32_t(bufferHandle->numFds);
118 *outNumInts = uint32_t(bufferHandle->numInts);
119
120 if (mMapperV2_1 == nullptr) {
121 return;
122 }
123
124 Error error;
125 auto buffer = const_cast<native_handle_t*>(bufferHandle);
126 auto ret = mMapperV2_1->getTransportSize(buffer,
127 [&](const auto& tmpError, const auto& tmpNumFds, const auto& tmpNumInts) {
128 error = tmpError;
129 if (error != Error::NONE) {
130 return;
131 }
132
133 *outNumFds = tmpNumFds;
134 *outNumInts = tmpNumInts;
135 });
136
137 if (!ret.isOk()) {
138 error = kTransactionError;
139 }
140 ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d",
141 buffer, error);
142}
143
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700144Error Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage,
145 const IMapper::Rect& accessRegion,
146 int acquireFence, void** outData) const
147{
148 auto buffer = const_cast<native_handle_t*>(bufferHandle);
149
150 // put acquireFence in a hidl_handle
151 hardware::hidl_handle acquireFenceHandle;
152 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
153 if (acquireFence >= 0) {
154 auto h = native_handle_init(acquireFenceStorage, 1, 0);
155 h->data[0] = acquireFence;
156 acquireFenceHandle = h;
157 }
158
159 Error error;
160 auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
161 [&](const auto& tmpError, const auto& tmpData)
162 {
163 error = tmpError;
164 if (error != Error::NONE) {
165 return;
166 }
167
168 *outData = tmpData;
169 });
170
171 // we own acquireFence even on errors
172 if (acquireFence >= 0) {
173 close(acquireFence);
174 }
175
176 return (ret.isOk()) ? error : kTransactionError;
177}
178
179Error Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage,
180 const IMapper::Rect& accessRegion,
181 int acquireFence, YCbCrLayout* outLayout) const
182{
183 auto buffer = const_cast<native_handle_t*>(bufferHandle);
184
185 // put acquireFence in a hidl_handle
186 hardware::hidl_handle acquireFenceHandle;
187 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
188 if (acquireFence >= 0) {
189 auto h = native_handle_init(acquireFenceStorage, 1, 0);
190 h->data[0] = acquireFence;
191 acquireFenceHandle = h;
192 }
193
194 Error error;
195 auto ret = mMapper->lockYCbCr(buffer, usage, accessRegion,
196 acquireFenceHandle,
197 [&](const auto& tmpError, const auto& tmpLayout)
198 {
199 error = tmpError;
200 if (error != Error::NONE) {
201 return;
202 }
203
204 *outLayout = tmpLayout;
205 });
206
207 // we own acquireFence even on errors
208 if (acquireFence >= 0) {
209 close(acquireFence);
210 }
211
212 return (ret.isOk()) ? error : kTransactionError;
213}
214
215int Mapper::unlock(buffer_handle_t bufferHandle) const
216{
217 auto buffer = const_cast<native_handle_t*>(bufferHandle);
218
219 int releaseFence = -1;
220 Error error;
221 auto ret = mMapper->unlock(buffer,
222 [&](const auto& tmpError, const auto& tmpReleaseFence)
223 {
224 error = tmpError;
225 if (error != Error::NONE) {
226 return;
227 }
228
229 auto fenceHandle = tmpReleaseFence.getNativeHandle();
230 if (fenceHandle && fenceHandle->numFds == 1) {
231 int fd = dup(fenceHandle->data[0]);
232 if (fd >= 0) {
233 releaseFence = fd;
234 } else {
235 ALOGD("failed to dup unlock release fence");
236 sync_wait(fenceHandle->data[0], -1);
237 }
238 }
239 });
240
241 if (!ret.isOk()) {
242 error = kTransactionError;
243 }
244
245 if (error != Error::NONE) {
246 ALOGE("unlock(%p) failed with %d", buffer, error);
247 }
248
249 return releaseFence;
250}
251
252Allocator::Allocator(const Mapper& mapper)
253 : mMapper(mapper)
254{
Chia-I Wucb8405e2017-04-17 15:20:19 -0700255 mAllocator = IAllocator::getService();
256 if (mAllocator == nullptr) {
257 LOG_ALWAYS_FATAL("gralloc-alloc is missing");
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700258 }
259}
260
261std::string Allocator::dumpDebugInfo() const
262{
263 std::string debugInfo;
264
265 mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) {
266 debugInfo = tmpDebugInfo.c_str();
267 });
268
269 return debugInfo;
270}
271
272Error Allocator::allocate(BufferDescriptor descriptor, uint32_t count,
273 uint32_t* outStride, buffer_handle_t* outBufferHandles) const
274{
275 Error error;
276 auto ret = mAllocator->allocate(descriptor, count,
277 [&](const auto& tmpError, const auto& tmpStride,
278 const auto& tmpBuffers) {
279 error = tmpError;
280 if (tmpError != Error::NONE) {
281 return;
282 }
283
284 // import buffers
285 for (uint32_t i = 0; i < count; i++) {
286 error = mMapper.importBuffer(tmpBuffers[i],
287 &outBufferHandles[i]);
288 if (error != Error::NONE) {
289 for (uint32_t j = 0; j < i; j++) {
290 mMapper.freeBuffer(outBufferHandles[j]);
291 outBufferHandles[j] = nullptr;
292 }
293 return;
294 }
295 }
296
297 *outStride = tmpStride;
298 });
299
Chia-I Wud8091b92017-05-16 14:30:34 -0700300 // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
301 hardware::IPCThreadState::self()->flushCommands();
302
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700303 return (ret.isOk()) ? error : kTransactionError;
304}
305
306} // namespace Gralloc2
307
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700308} // namespace android