blob: f8d9401a0ef4e009d2e25fc53803e64fb5dfa2da [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
19#include <ui/Gralloc2.h>
20
21#include <log/log.h>
22#pragma clang diagnostic push
23#pragma clang diagnostic ignored "-Wzero-length-array"
24#include <sync/sync.h>
25#pragma clang diagnostic pop
26
27namespace android {
28
29namespace Gralloc2 {
30
31static constexpr Error kTransactionError = Error::NO_RESOURCES;
32
33Mapper::Mapper()
34{
35 mMapper = IMapper::getService();
Chia-I Wucb8405e2017-04-17 15:20:19 -070036 if (mMapper == nullptr || mMapper->isRemote()) {
Chia-I Wu5bac7f32017-04-06 12:34:32 -070037 LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
38 }
39}
40
41Error Mapper::createDescriptor(
42 const IMapper::BufferDescriptorInfo& descriptorInfo,
43 BufferDescriptor* outDescriptor) const
44{
45 Error error;
46 auto ret = mMapper->createDescriptor(descriptorInfo,
47 [&](const auto& tmpError, const auto& tmpDescriptor)
48 {
49 error = tmpError;
50 if (error != Error::NONE) {
51 return;
52 }
53
54 *outDescriptor = tmpDescriptor;
55 });
56
57 return (ret.isOk()) ? error : kTransactionError;
58}
59
60Error Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
61 buffer_handle_t* outBufferHandle) const
62{
63 Error error;
64 auto ret = mMapper->importBuffer(rawHandle,
65 [&](const auto& tmpError, const auto& tmpBuffer)
66 {
67 error = tmpError;
68 if (error != Error::NONE) {
69 return;
70 }
71
72 *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
73 });
74
75 return (ret.isOk()) ? error : kTransactionError;
76}
77
78void Mapper::freeBuffer(buffer_handle_t bufferHandle) const
79{
80 auto buffer = const_cast<native_handle_t*>(bufferHandle);
81 auto ret = mMapper->freeBuffer(buffer);
82
83 auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
84 ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d",
85 buffer, error);
86}
87
88Error Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage,
89 const IMapper::Rect& accessRegion,
90 int acquireFence, void** outData) const
91{
92 auto buffer = const_cast<native_handle_t*>(bufferHandle);
93
94 // put acquireFence in a hidl_handle
95 hardware::hidl_handle acquireFenceHandle;
96 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
97 if (acquireFence >= 0) {
98 auto h = native_handle_init(acquireFenceStorage, 1, 0);
99 h->data[0] = acquireFence;
100 acquireFenceHandle = h;
101 }
102
103 Error error;
104 auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
105 [&](const auto& tmpError, const auto& tmpData)
106 {
107 error = tmpError;
108 if (error != Error::NONE) {
109 return;
110 }
111
112 *outData = tmpData;
113 });
114
115 // we own acquireFence even on errors
116 if (acquireFence >= 0) {
117 close(acquireFence);
118 }
119
120 return (ret.isOk()) ? error : kTransactionError;
121}
122
123Error Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage,
124 const IMapper::Rect& accessRegion,
125 int acquireFence, YCbCrLayout* outLayout) const
126{
127 auto buffer = const_cast<native_handle_t*>(bufferHandle);
128
129 // put acquireFence in a hidl_handle
130 hardware::hidl_handle acquireFenceHandle;
131 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
132 if (acquireFence >= 0) {
133 auto h = native_handle_init(acquireFenceStorage, 1, 0);
134 h->data[0] = acquireFence;
135 acquireFenceHandle = h;
136 }
137
138 Error error;
139 auto ret = mMapper->lockYCbCr(buffer, usage, accessRegion,
140 acquireFenceHandle,
141 [&](const auto& tmpError, const auto& tmpLayout)
142 {
143 error = tmpError;
144 if (error != Error::NONE) {
145 return;
146 }
147
148 *outLayout = tmpLayout;
149 });
150
151 // we own acquireFence even on errors
152 if (acquireFence >= 0) {
153 close(acquireFence);
154 }
155
156 return (ret.isOk()) ? error : kTransactionError;
157}
158
159int Mapper::unlock(buffer_handle_t bufferHandle) const
160{
161 auto buffer = const_cast<native_handle_t*>(bufferHandle);
162
163 int releaseFence = -1;
164 Error error;
165 auto ret = mMapper->unlock(buffer,
166 [&](const auto& tmpError, const auto& tmpReleaseFence)
167 {
168 error = tmpError;
169 if (error != Error::NONE) {
170 return;
171 }
172
173 auto fenceHandle = tmpReleaseFence.getNativeHandle();
174 if (fenceHandle && fenceHandle->numFds == 1) {
175 int fd = dup(fenceHandle->data[0]);
176 if (fd >= 0) {
177 releaseFence = fd;
178 } else {
179 ALOGD("failed to dup unlock release fence");
180 sync_wait(fenceHandle->data[0], -1);
181 }
182 }
183 });
184
185 if (!ret.isOk()) {
186 error = kTransactionError;
187 }
188
189 if (error != Error::NONE) {
190 ALOGE("unlock(%p) failed with %d", buffer, error);
191 }
192
193 return releaseFence;
194}
195
196Allocator::Allocator(const Mapper& mapper)
197 : mMapper(mapper)
198{
Chia-I Wucb8405e2017-04-17 15:20:19 -0700199 mAllocator = IAllocator::getService();
200 if (mAllocator == nullptr) {
201 LOG_ALWAYS_FATAL("gralloc-alloc is missing");
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700202 }
203}
204
205std::string Allocator::dumpDebugInfo() const
206{
207 std::string debugInfo;
208
209 mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) {
210 debugInfo = tmpDebugInfo.c_str();
211 });
212
213 return debugInfo;
214}
215
216Error Allocator::allocate(BufferDescriptor descriptor, uint32_t count,
217 uint32_t* outStride, buffer_handle_t* outBufferHandles) const
218{
219 Error error;
220 auto ret = mAllocator->allocate(descriptor, count,
221 [&](const auto& tmpError, const auto& tmpStride,
222 const auto& tmpBuffers) {
223 error = tmpError;
224 if (tmpError != Error::NONE) {
225 return;
226 }
227
228 // import buffers
229 for (uint32_t i = 0; i < count; i++) {
230 error = mMapper.importBuffer(tmpBuffers[i],
231 &outBufferHandles[i]);
232 if (error != Error::NONE) {
233 for (uint32_t j = 0; j < i; j++) {
234 mMapper.freeBuffer(outBufferHandles[j]);
235 outBufferHandles[j] = nullptr;
236 }
237 return;
238 }
239 }
240
241 *outStride = tmpStride;
242 });
243
244 return (ret.isOk()) ? error : kTransactionError;
245}
246
247} // namespace Gralloc2
248
249} // namespace android