blob: 882674f4791df808931fa22b6bf1689e4de06eed [file] [log] [blame]
Marissa Wall925bf7f2018-12-29 14:27:11 -08001/*
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 "Gralloc3"
18
19#include <hidl/ServiceManagement.h>
20#include <hwbinder/IPCThreadState.h>
21#include <ui/Gralloc3.h>
22
23#include <inttypes.h>
24#include <log/log.h>
25#pragma clang diagnostic push
26#pragma clang diagnostic ignored "-Wzero-length-array"
27#include <sync/sync.h>
28#pragma clang diagnostic pop
29
30using android::hardware::graphics::allocator::V3_0::IAllocator;
Marissa Wall63429912019-04-09 14:05:06 -070031using android::hardware::graphics::common::V1_2::BufferUsage;
Marissa Wall925bf7f2018-12-29 14:27:11 -080032using android::hardware::graphics::mapper::V3_0::BufferDescriptor;
33using android::hardware::graphics::mapper::V3_0::Error;
34using android::hardware::graphics::mapper::V3_0::IMapper;
35using android::hardware::graphics::mapper::V3_0::YCbCrLayout;
36
37namespace android {
38
39namespace {
40
41static constexpr Error kTransactionError = Error::NO_RESOURCES;
42
43uint64_t getValidUsageBits() {
44 static const uint64_t validUsageBits = []() -> uint64_t {
45 uint64_t bits = 0;
46 for (const auto bit :
Marissa Wall63429912019-04-09 14:05:06 -070047 hardware::hidl_enum_range<hardware::graphics::common::V1_2::BufferUsage>()) {
Marissa Wall925bf7f2018-12-29 14:27:11 -080048 bits = bits | bit;
49 }
50 return bits;
51 }();
52 return validUsageBits;
53}
54
55static inline IMapper::Rect sGralloc3Rect(const Rect& rect) {
56 IMapper::Rect outRect{};
57 outRect.left = rect.left;
58 outRect.top = rect.top;
59 outRect.width = rect.width();
60 outRect.height = rect.height();
61 return outRect;
62}
63static inline void sBufferDescriptorInfo(uint32_t width, uint32_t height,
64 android::PixelFormat format, uint32_t layerCount,
65 uint64_t usage,
66 IMapper::BufferDescriptorInfo* outDescriptorInfo) {
67 outDescriptorInfo->width = width;
68 outDescriptorInfo->height = height;
69 outDescriptorInfo->layerCount = layerCount;
Marissa Wall63429912019-04-09 14:05:06 -070070 outDescriptorInfo->format = static_cast<hardware::graphics::common::V1_2::PixelFormat>(format);
Marissa Wall925bf7f2018-12-29 14:27:11 -080071 outDescriptorInfo->usage = usage;
72}
73
74} // anonymous namespace
75
76void Gralloc3Mapper::preload() {
77 android::hardware::preloadPassthroughService<IMapper>();
78}
79
80Gralloc3Mapper::Gralloc3Mapper() {
81 mMapper = IMapper::getService();
82 if (mMapper == nullptr) {
83 ALOGW("mapper 3.x is not supported");
84 return;
85 }
86 if (mMapper->isRemote()) {
87 LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
88 }
89}
90
Valerie Hau250c6542019-01-31 14:23:43 -080091bool Gralloc3Mapper::isLoaded() const {
Marissa Wall925bf7f2018-12-29 14:27:11 -080092 return mMapper != nullptr;
93}
94
95status_t Gralloc3Mapper::validateBufferDescriptorInfo(
96 IMapper::BufferDescriptorInfo* descriptorInfo) const {
97 uint64_t validUsageBits = getValidUsageBits();
98
99 if (descriptorInfo->usage & ~validUsageBits) {
100 ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64,
101 descriptorInfo->usage & ~validUsageBits);
102 return BAD_VALUE;
103 }
104 return NO_ERROR;
105}
106
107status_t Gralloc3Mapper::createDescriptor(void* bufferDescriptorInfo,
108 void* outBufferDescriptor) const {
109 IMapper::BufferDescriptorInfo* descriptorInfo =
110 static_cast<IMapper::BufferDescriptorInfo*>(bufferDescriptorInfo);
111 BufferDescriptor* outDescriptor = static_cast<BufferDescriptor*>(outBufferDescriptor);
112
113 status_t status = validateBufferDescriptorInfo(descriptorInfo);
114 if (status != NO_ERROR) {
115 return status;
116 }
117
118 Error error;
119 auto hidl_cb = [&](const auto& tmpError, const auto& tmpDescriptor) {
120 error = tmpError;
121 if (error != Error::NONE) {
122 return;
123 }
124 *outDescriptor = tmpDescriptor;
125 };
126
127 hardware::Return<void> ret = mMapper->createDescriptor(*descriptorInfo, hidl_cb);
128
129 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
130}
131
132status_t Gralloc3Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
133 buffer_handle_t* outBufferHandle) const {
134 Error error;
135 auto ret = mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
136 error = tmpError;
137 if (error != Error::NONE) {
138 return;
139 }
140 *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
141 });
142
143 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
144}
145
146void Gralloc3Mapper::freeBuffer(buffer_handle_t bufferHandle) const {
147 auto buffer = const_cast<native_handle_t*>(bufferHandle);
148 auto ret = mMapper->freeBuffer(buffer);
149
150 auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
151 ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d", buffer, error);
152}
153
154status_t Gralloc3Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
155 uint32_t height, android::PixelFormat format,
156 uint32_t layerCount, uint64_t usage,
157 uint32_t stride) const {
158 IMapper::BufferDescriptorInfo descriptorInfo;
159 sBufferDescriptorInfo(width, height, format, layerCount, usage, &descriptorInfo);
160
161 auto buffer = const_cast<native_handle_t*>(bufferHandle);
162 auto ret = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
163
164 return static_cast<status_t>((ret.isOk()) ? static_cast<Error>(ret) : kTransactionError);
165}
166
167void Gralloc3Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t* outNumFds,
168 uint32_t* outNumInts) const {
169 *outNumFds = uint32_t(bufferHandle->numFds);
170 *outNumInts = uint32_t(bufferHandle->numInts);
171
172 Error error;
173 auto buffer = const_cast<native_handle_t*>(bufferHandle);
174 auto ret = mMapper->getTransportSize(buffer,
175 [&](const auto& tmpError, const auto& tmpNumFds,
176 const auto& tmpNumInts) {
177 error = tmpError;
178 if (error != Error::NONE) {
179 return;
180 }
181 *outNumFds = tmpNumFds;
182 *outNumInts = tmpNumInts;
183 });
184
185 error = (ret.isOk()) ? error : kTransactionError;
186
187 ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d", buffer, error);
188}
189
190status_t Gralloc3Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
Valerie Hau0c9fc362019-01-22 09:17:19 -0800191 int acquireFence, void** outData, int32_t* outBytesPerPixel,
192 int32_t* outBytesPerStride) const {
Marissa Wall925bf7f2018-12-29 14:27:11 -0800193 auto buffer = const_cast<native_handle_t*>(bufferHandle);
194
195 IMapper::Rect accessRegion = sGralloc3Rect(bounds);
196
197 // put acquireFence in a hidl_handle
198 hardware::hidl_handle acquireFenceHandle;
199 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
200 if (acquireFence >= 0) {
201 auto h = native_handle_init(acquireFenceStorage, 1, 0);
202 h->data[0] = acquireFence;
203 acquireFenceHandle = h;
204 }
205
206 Error error;
207 auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
Valerie Hau0c9fc362019-01-22 09:17:19 -0800208 [&](const auto& tmpError, const auto& tmpData,
209 const auto& tmpBytesPerPixel, const auto& tmpBytesPerStride) {
Marissa Wall925bf7f2018-12-29 14:27:11 -0800210 error = tmpError;
211 if (error != Error::NONE) {
212 return;
213 }
214 *outData = tmpData;
Valerie Hau0c9fc362019-01-22 09:17:19 -0800215 if (outBytesPerPixel) {
216 *outBytesPerPixel = tmpBytesPerPixel;
217 }
218 if (outBytesPerStride) {
219 *outBytesPerStride = tmpBytesPerStride;
220 }
Marissa Wall925bf7f2018-12-29 14:27:11 -0800221 });
222
223 // we own acquireFence even on errors
224 if (acquireFence >= 0) {
225 close(acquireFence);
226 }
227
228 error = (ret.isOk()) ? error : kTransactionError;
229
230 ALOGW_IF(error != Error::NONE, "lock(%p, ...) failed: %d", bufferHandle, error);
231
232 return static_cast<status_t>(error);
233}
234
235status_t Gralloc3Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
236 int acquireFence, android_ycbcr* ycbcr) const {
237 auto buffer = const_cast<native_handle_t*>(bufferHandle);
238
239 IMapper::Rect accessRegion = sGralloc3Rect(bounds);
240
241 // put acquireFence in a hidl_handle
242 hardware::hidl_handle acquireFenceHandle;
243 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
244 if (acquireFence >= 0) {
245 auto h = native_handle_init(acquireFenceStorage, 1, 0);
246 h->data[0] = acquireFence;
247 acquireFenceHandle = h;
248 }
249
250 YCbCrLayout layout;
251 Error error;
252 auto ret = mMapper->lockYCbCr(buffer, usage, accessRegion, acquireFenceHandle,
253 [&](const auto& tmpError, const auto& tmpLayout) {
254 error = tmpError;
255 if (error != Error::NONE) {
256 return;
257 }
258
259 layout = tmpLayout;
260 });
261
262 if (error == Error::NONE) {
263 ycbcr->y = layout.y;
264 ycbcr->cb = layout.cb;
265 ycbcr->cr = layout.cr;
266 ycbcr->ystride = static_cast<size_t>(layout.yStride);
267 ycbcr->cstride = static_cast<size_t>(layout.cStride);
268 ycbcr->chroma_step = static_cast<size_t>(layout.chromaStep);
269 }
270
271 // we own acquireFence even on errors
272 if (acquireFence >= 0) {
273 close(acquireFence);
274 }
275
276 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
277}
278
279int Gralloc3Mapper::unlock(buffer_handle_t bufferHandle) const {
280 auto buffer = const_cast<native_handle_t*>(bufferHandle);
281
282 int releaseFence = -1;
283 Error error;
284 auto ret = mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
285 error = tmpError;
286 if (error != Error::NONE) {
287 return;
288 }
289
290 auto fenceHandle = tmpReleaseFence.getNativeHandle();
291 if (fenceHandle && fenceHandle->numFds == 1) {
292 int fd = dup(fenceHandle->data[0]);
293 if (fd >= 0) {
294 releaseFence = fd;
295 } else {
296 ALOGD("failed to dup unlock release fence");
297 sync_wait(fenceHandle->data[0], -1);
298 }
299 }
300 });
301
302 if (!ret.isOk()) {
303 error = kTransactionError;
304 }
305
306 if (error != Error::NONE) {
307 ALOGE("unlock(%p) failed with %d", buffer, error);
308 }
309
310 return releaseFence;
311}
312
Valerie Hauddbfaeb2019-02-01 09:54:20 -0800313status_t Gralloc3Mapper::isSupported(uint32_t width, uint32_t height, android::PixelFormat format,
314 uint32_t layerCount, uint64_t usage,
315 bool* outSupported) const {
316 IMapper::BufferDescriptorInfo descriptorInfo;
317 sBufferDescriptorInfo(width, height, format, layerCount, usage, &descriptorInfo);
318
319 Error error;
320 auto ret = mMapper->isSupported(descriptorInfo,
321 [&](const auto& tmpError, const auto& tmpSupported) {
322 error = tmpError;
323 if (error != Error::NONE) {
324 return;
325 }
326 if (outSupported) {
327 *outSupported = tmpSupported;
328 }
329 });
330
331 if (!ret.isOk()) {
332 error = kTransactionError;
333 }
334
335 if (error != Error::NONE) {
336 ALOGE("isSupported(%u, %u, %d, %u, ...) failed with %d", width, height, format, layerCount,
337 error);
338 }
339
340 return static_cast<status_t>(error);
341}
342
Marissa Wall925bf7f2018-12-29 14:27:11 -0800343Gralloc3Allocator::Gralloc3Allocator(const Gralloc3Mapper& mapper) : mMapper(mapper) {
344 mAllocator = IAllocator::getService();
345 if (mAllocator == nullptr) {
346 ALOGW("allocator 3.x is not supported");
347 return;
348 }
349}
350
Valerie Hau250c6542019-01-31 14:23:43 -0800351bool Gralloc3Allocator::isLoaded() const {
Marissa Wall925bf7f2018-12-29 14:27:11 -0800352 return mAllocator != nullptr;
353}
354
Marissa Wall22b2de12019-12-02 18:11:43 -0800355std::string Gralloc3Allocator::dumpDebugInfo(bool /*less*/) const {
Marissa Wall925bf7f2018-12-29 14:27:11 -0800356 std::string debugInfo;
357
358 mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
359
360 return debugInfo;
361}
362
Marissa Wall22b2de12019-12-02 18:11:43 -0800363status_t Gralloc3Allocator::allocate(std::string /*requestorName*/, uint32_t width, uint32_t height,
364 android::PixelFormat format, uint32_t layerCount,
365 uint64_t usage, uint32_t bufferCount, uint32_t* outStride,
366 buffer_handle_t* outBufferHandles, bool importBuffers) const {
Marissa Wall925bf7f2018-12-29 14:27:11 -0800367 IMapper::BufferDescriptorInfo descriptorInfo;
368 sBufferDescriptorInfo(width, height, format, layerCount, usage, &descriptorInfo);
369
370 BufferDescriptor descriptor;
371 status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),
372 static_cast<void*>(&descriptor));
373 if (error != NO_ERROR) {
374 return error;
375 }
376
377 auto ret = mAllocator->allocate(descriptor, bufferCount,
378 [&](const auto& tmpError, const auto& tmpStride,
379 const auto& tmpBuffers) {
380 error = static_cast<status_t>(tmpError);
381 if (tmpError != Error::NONE) {
382 return;
383 }
384
Marissa Wallbfcf81f2019-11-27 10:36:29 -0800385 if (importBuffers) {
386 for (uint32_t i = 0; i < bufferCount; i++) {
387 error = mMapper.importBuffer(tmpBuffers[i],
388 &outBufferHandles[i]);
389 if (error != NO_ERROR) {
390 for (uint32_t j = 0; j < i; j++) {
391 mMapper.freeBuffer(outBufferHandles[j]);
392 outBufferHandles[j] = nullptr;
393 }
394 return;
Marissa Wall925bf7f2018-12-29 14:27:11 -0800395 }
Marissa Wallbfcf81f2019-11-27 10:36:29 -0800396 }
397 } else {
398 for (uint32_t i = 0; i < bufferCount; i++) {
399 outBufferHandles[i] = native_handle_clone(
400 tmpBuffers[i].getNativeHandle());
401 if (!outBufferHandles[i]) {
402 for (uint32_t j = 0; j < i; j++) {
403 auto buffer = const_cast<native_handle_t*>(
404 outBufferHandles[j]);
405 native_handle_close(buffer);
406 native_handle_delete(buffer);
407 outBufferHandles[j] = nullptr;
408 }
409 }
Marissa Wall925bf7f2018-12-29 14:27:11 -0800410 }
411 }
412 *outStride = tmpStride;
413 });
414
415 // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
416 hardware::IPCThreadState::self()->flushCommands();
417
418 return (ret.isOk()) ? error : static_cast<status_t>(kTransactionError);
419}
420
421} // namespace android