blob: 7289ab56cc904d59018c4ff6fa97987f709db1a5 [file] [log] [blame]
Marissa Wall87c8ba72019-06-20 14:20:52 -07001/*
2 * Copyright 2019 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 "Gralloc4"
18
John Reck614326b2022-01-11 15:49:54 -050019#include <aidl/android/hardware/graphics/allocator/AllocationError.h>
20#include <aidl/android/hardware/graphics/allocator/AllocationResult.h>
21#include <aidl/android/hardware/graphics/common/BufferUsage.h>
22#include <aidlcommonsupport/NativeHandle.h>
23#include <android/binder_enums.h>
24#include <android/binder_manager.h>
Charles Chen788b58b2023-02-13 18:02:10 +000025#include <cutils/android_filesystem_config.h>
26#include <cutils/multiuser.h>
Alec Mouri9c604e32022-03-18 22:47:44 +000027#include <gralloctypes/Gralloc4.h>
Marissa Wall87c8ba72019-06-20 14:20:52 -070028#include <hidl/ServiceManagement.h>
29#include <hwbinder/IPCThreadState.h>
30#include <ui/Gralloc4.h>
31
32#include <inttypes.h>
33#include <log/log.h>
34#pragma clang diagnostic push
35#pragma clang diagnostic ignored "-Wzero-length-array"
36#include <sync/sync.h>
37#pragma clang diagnostic pop
38
John Reck614326b2022-01-11 15:49:54 -050039using aidl::android::hardware::graphics::allocator::AllocationError;
40using aidl::android::hardware::graphics::allocator::AllocationResult;
Marissa Wall22b2de12019-12-02 18:11:43 -080041using aidl::android::hardware::graphics::common::ExtendableType;
42using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
43using aidl::android::hardware::graphics::common::StandardMetadataType;
44using android::hardware::hidl_vec;
Marissa Wall87c8ba72019-06-20 14:20:52 -070045using android::hardware::graphics::allocator::V4_0::IAllocator;
46using android::hardware::graphics::common::V1_2::BufferUsage;
Chris Forbes6c09ee72022-01-26 18:48:55 +130047using android::hardware::graphics::common::V1_2::PixelFormat;
Marissa Wall87c8ba72019-06-20 14:20:52 -070048using android::hardware::graphics::mapper::V4_0::BufferDescriptor;
49using android::hardware::graphics::mapper::V4_0::Error;
50using android::hardware::graphics::mapper::V4_0::IMapper;
John Reck614326b2022-01-11 15:49:54 -050051using AidlIAllocator = ::aidl::android::hardware::graphics::allocator::IAllocator;
52using AidlBufferUsage = ::aidl::android::hardware::graphics::common::BufferUsage;
Yichi Chenba40db52021-04-30 00:18:32 +080053using AidlDataspace = ::aidl::android::hardware::graphics::common::Dataspace;
John Reck614326b2022-01-11 15:49:54 -050054using AidlNativeHandle = ::aidl::android::hardware::common::NativeHandle;
Marissa Wall22b2de12019-12-02 18:11:43 -080055using BufferDump = android::hardware::graphics::mapper::V4_0::IMapper::BufferDump;
56using MetadataDump = android::hardware::graphics::mapper::V4_0::IMapper::MetadataDump;
57using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
58using MetadataTypeDescription =
59 android::hardware::graphics::mapper::V4_0::IMapper::MetadataTypeDescription;
Marissa Wall87c8ba72019-06-20 14:20:52 -070060
61namespace android {
62
63namespace {
64
65static constexpr Error kTransactionError = Error::NO_RESOURCES;
John Reck614326b2022-01-11 15:49:54 -050066static const auto kAidlAllocatorServiceName = AidlIAllocator::descriptor + std::string("/default");
Marissa Wall87c8ba72019-06-20 14:20:52 -070067
Robin Lee38b59412022-02-02 22:53:15 +010068// TODO(b/72323293, b/72703005): Remove these invalid bits from callers
69static constexpr uint64_t kRemovedUsageBits = static_cast<uint64_t>((1 << 10) | (1 << 13));
70
Marissa Wall87c8ba72019-06-20 14:20:52 -070071uint64_t getValidUsageBits() {
72 static const uint64_t validUsageBits = []() -> uint64_t {
73 uint64_t bits = 0;
74 for (const auto bit :
75 hardware::hidl_enum_range<hardware::graphics::common::V1_2::BufferUsage>()) {
76 bits = bits | bit;
77 }
Kevin F. Haggerty9ca88af2021-10-27 23:02:31 +010078
79#ifdef ADDNL_GRALLOC_10_USAGE_BITS
80 uint64_t addnl_bits = static_cast<uint64_t>(ADDNL_GRALLOC_10_USAGE_BITS);
81 ALOGI("Adding additional valid usage bits: 0x%" PRIx64, addnl_bits);
82 bits = bits | addnl_bits;
83#endif
84
Marissa Wall87c8ba72019-06-20 14:20:52 -070085 return bits;
86 }();
Robin Lee38b59412022-02-02 22:53:15 +010087 return validUsageBits | kRemovedUsageBits;
Marissa Wall87c8ba72019-06-20 14:20:52 -070088}
89
John Reck614326b2022-01-11 15:49:54 -050090uint64_t getValidUsageBits41() {
91 static const uint64_t validUsageBits = []() -> uint64_t {
92 uint64_t bits = 0;
93 for (const auto bit : ndk::enum_range<AidlBufferUsage>{}) {
94 bits |= static_cast<int64_t>(bit);
95 }
96 return bits;
97 }();
98 return validUsageBits;
99}
100
Marissa Wall87c8ba72019-06-20 14:20:52 -0700101static inline IMapper::Rect sGralloc4Rect(const Rect& rect) {
102 IMapper::Rect outRect{};
103 outRect.left = rect.left;
104 outRect.top = rect.top;
105 outRect.width = rect.width();
106 outRect.height = rect.height();
107 return outRect;
108}
Marissa Wall87c8ba72019-06-20 14:20:52 -0700109
John Reck614326b2022-01-11 15:49:54 -0500110// See if gralloc "4.1" is available.
111static bool hasIAllocatorAidl() {
112 // Avoid re-querying repeatedly for this information;
113 static bool sHasIAllocatorAidl = []() -> bool {
John Reck614326b2022-01-11 15:49:54 -0500114 if (__builtin_available(android 31, *)) {
115 return AServiceManager_isDeclared(kAidlAllocatorServiceName.c_str());
116 }
117 return false;
118 }();
119 return sHasIAllocatorAidl;
120}
121
John Recke0711382022-01-26 12:10:59 -0500122// Determines whether the passed info is compatible with the mapper.
123static status_t validateBufferDescriptorInfo(IMapper::BufferDescriptorInfo* descriptorInfo) {
124 uint64_t validUsageBits = getValidUsageBits();
125 if (hasIAllocatorAidl()) {
126 validUsageBits |= getValidUsageBits41();
127 }
128
129 if (descriptorInfo->usage & ~validUsageBits) {
130 ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64,
131 descriptorInfo->usage & ~validUsageBits);
132 return BAD_VALUE;
133 }
Chris Forbes6c09ee72022-01-26 18:48:55 +1300134
135 // Combinations that are only allowed with gralloc 4.1.
136 // Previous grallocs must be protected from this.
137 if (!hasIAllocatorAidl() &&
138 descriptorInfo->format != hardware::graphics::common::V1_2::PixelFormat::BLOB &&
139 descriptorInfo->usage & BufferUsage::GPU_DATA_BUFFER) {
140 ALOGE("non-BLOB pixel format with GPU_DATA_BUFFER usage is not supported prior to gralloc 4.1");
141 return BAD_VALUE;
142 }
143
John Recke0711382022-01-26 12:10:59 -0500144 return NO_ERROR;
145}
146
147static inline status_t sBufferDescriptorInfo(std::string name, uint32_t width, uint32_t height,
148 PixelFormat format, uint32_t layerCount,
149 uint64_t usage,
150 IMapper::BufferDescriptorInfo* outDescriptorInfo) {
151 outDescriptorInfo->name = name;
152 outDescriptorInfo->width = width;
153 outDescriptorInfo->height = height;
154 outDescriptorInfo->layerCount = layerCount;
155 outDescriptorInfo->format = static_cast<hardware::graphics::common::V1_2::PixelFormat>(format);
156 outDescriptorInfo->usage = usage;
157 outDescriptorInfo->reservedSize = 0;
158
159 return validateBufferDescriptorInfo(outDescriptorInfo);
160}
161
Marissa Wall87c8ba72019-06-20 14:20:52 -0700162} // anonymous namespace
163
164void Gralloc4Mapper::preload() {
165 android::hardware::preloadPassthroughService<IMapper>();
166}
167
168Gralloc4Mapper::Gralloc4Mapper() {
169 mMapper = IMapper::getService();
170 if (mMapper == nullptr) {
171 ALOGI("mapper 4.x is not supported");
172 return;
173 }
174 if (mMapper->isRemote()) {
175 LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
176 }
177}
178
179bool Gralloc4Mapper::isLoaded() const {
180 return mMapper != nullptr;
181}
182
Marissa Wall87c8ba72019-06-20 14:20:52 -0700183status_t Gralloc4Mapper::createDescriptor(void* bufferDescriptorInfo,
184 void* outBufferDescriptor) const {
185 IMapper::BufferDescriptorInfo* descriptorInfo =
186 static_cast<IMapper::BufferDescriptorInfo*>(bufferDescriptorInfo);
187 BufferDescriptor* outDescriptor = static_cast<BufferDescriptor*>(outBufferDescriptor);
188
189 status_t status = validateBufferDescriptorInfo(descriptorInfo);
190 if (status != NO_ERROR) {
191 return status;
192 }
193
194 Error error;
195 auto hidl_cb = [&](const auto& tmpError, const auto& tmpDescriptor) {
196 error = tmpError;
197 if (error != Error::NONE) {
198 return;
199 }
200 *outDescriptor = tmpDescriptor;
201 };
202
203 hardware::Return<void> ret = mMapper->createDescriptor(*descriptorInfo, hidl_cb);
204
205 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
206}
207
John Reck0ff95c92022-12-08 11:45:29 -0500208status_t Gralloc4Mapper::importBuffer(const native_handle_t* rawHandle,
Marissa Wall87c8ba72019-06-20 14:20:52 -0700209 buffer_handle_t* outBufferHandle) const {
210 Error error;
211 auto ret = mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
212 error = tmpError;
213 if (error != Error::NONE) {
214 return;
215 }
216 *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
217 });
218
219 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
220}
221
222void Gralloc4Mapper::freeBuffer(buffer_handle_t bufferHandle) const {
223 auto buffer = const_cast<native_handle_t*>(bufferHandle);
224 auto ret = mMapper->freeBuffer(buffer);
225
226 auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
227 ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d", buffer, error);
228}
229
230status_t Gralloc4Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
Marissa Wall22b2de12019-12-02 18:11:43 -0800231 uint32_t height, PixelFormat format,
Marissa Wall87c8ba72019-06-20 14:20:52 -0700232 uint32_t layerCount, uint64_t usage,
233 uint32_t stride) const {
234 IMapper::BufferDescriptorInfo descriptorInfo;
John Recke0711382022-01-26 12:10:59 -0500235 if (auto error = sBufferDescriptorInfo("validateBufferSize", width, height, format, layerCount,
236 usage, &descriptorInfo) != OK) {
237 return error;
238 }
Marissa Wall87c8ba72019-06-20 14:20:52 -0700239
240 auto buffer = const_cast<native_handle_t*>(bufferHandle);
241 auto ret = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
242
243 return static_cast<status_t>((ret.isOk()) ? static_cast<Error>(ret) : kTransactionError);
244}
245
246void Gralloc4Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t* outNumFds,
247 uint32_t* outNumInts) const {
248 *outNumFds = uint32_t(bufferHandle->numFds);
249 *outNumInts = uint32_t(bufferHandle->numInts);
250
251 Error error;
252 auto buffer = const_cast<native_handle_t*>(bufferHandle);
253 auto ret = mMapper->getTransportSize(buffer,
254 [&](const auto& tmpError, const auto& tmpNumFds,
255 const auto& tmpNumInts) {
256 error = tmpError;
257 if (error != Error::NONE) {
258 return;
259 }
260 *outNumFds = tmpNumFds;
261 *outNumInts = tmpNumInts;
262 });
263
264 error = (ret.isOk()) ? error : kTransactionError;
265
266 ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d", buffer, error);
267}
268
269status_t Gralloc4Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
270 int acquireFence, void** outData, int32_t* outBytesPerPixel,
271 int32_t* outBytesPerStride) const {
John Reck434bc982023-12-19 17:04:07 -0500272 if (outBytesPerPixel) *outBytesPerPixel = -1;
273 if (outBytesPerStride) *outBytesPerStride = -1;
Marissa Wall20611c62019-11-05 15:06:24 -0800274
Marissa Wall87c8ba72019-06-20 14:20:52 -0700275 auto buffer = const_cast<native_handle_t*>(bufferHandle);
276
277 IMapper::Rect accessRegion = sGralloc4Rect(bounds);
278
279 // put acquireFence in a hidl_handle
280 hardware::hidl_handle acquireFenceHandle;
281 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
282 if (acquireFence >= 0) {
283 auto h = native_handle_init(acquireFenceStorage, 1, 0);
284 h->data[0] = acquireFence;
285 acquireFenceHandle = h;
286 }
287
288 Error error;
289 auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
Marissa Wall20611c62019-11-05 15:06:24 -0800290 [&](const auto& tmpError, const auto& tmpData) {
Marissa Wall87c8ba72019-06-20 14:20:52 -0700291 error = tmpError;
292 if (error != Error::NONE) {
293 return;
294 }
295 *outData = tmpData;
Marissa Wall87c8ba72019-06-20 14:20:52 -0700296 });
297
298 // we own acquireFence even on errors
299 if (acquireFence >= 0) {
300 close(acquireFence);
301 }
302
303 error = (ret.isOk()) ? error : kTransactionError;
304
305 ALOGW_IF(error != Error::NONE, "lock(%p, ...) failed: %d", bufferHandle, error);
306
307 return static_cast<status_t>(error);
308}
309
Marissa Wall22b2de12019-12-02 18:11:43 -0800310status_t Gralloc4Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
311 int acquireFence, android_ycbcr* outYcbcr) const {
312 if (!outYcbcr) {
313 return BAD_VALUE;
314 }
315
316 std::vector<ui::PlaneLayout> planeLayouts;
317 status_t error = getPlaneLayouts(bufferHandle, &planeLayouts);
318 if (error != NO_ERROR) {
319 return error;
320 }
321
322 void* data = nullptr;
323 error = lock(bufferHandle, usage, bounds, acquireFence, &data, nullptr, nullptr);
324 if (error != NO_ERROR) {
325 return error;
326 }
327
328 android_ycbcr ycbcr;
329
330 ycbcr.y = nullptr;
331 ycbcr.cb = nullptr;
332 ycbcr.cr = nullptr;
333 ycbcr.ystride = 0;
334 ycbcr.cstride = 0;
335 ycbcr.chroma_step = 0;
336
337 for (const auto& planeLayout : planeLayouts) {
338 for (const auto& planeLayoutComponent : planeLayout.components) {
339 if (!gralloc4::isStandardPlaneLayoutComponentType(planeLayoutComponent.type)) {
340 continue;
341 }
Marissa Wall22b2de12019-12-02 18:11:43 -0800342
Jason Macnak41209912022-02-16 14:44:44 -0800343 uint8_t* tmpData = static_cast<uint8_t*>(data) + planeLayout.offsetInBytes;
344
345 // Note that `offsetInBits` may not be a multiple of 8 for packed formats (e.g. P010)
346 // but we still want to point to the start of the first byte.
347 tmpData += (planeLayoutComponent.offsetInBits / 8);
348
Marissa Wall22b2de12019-12-02 18:11:43 -0800349 uint64_t sampleIncrementInBytes;
350
351 auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
352 switch (type) {
353 case PlaneLayoutComponentType::Y:
Jason Macnak41209912022-02-16 14:44:44 -0800354 if ((ycbcr.y != nullptr) || (planeLayout.sampleIncrementInBits % 8 != 0)) {
Marissa Wall22b2de12019-12-02 18:11:43 -0800355 unlock(bufferHandle);
356 return BAD_VALUE;
357 }
358 ycbcr.y = tmpData;
359 ycbcr.ystride = planeLayout.strideInBytes;
360 break;
361
362 case PlaneLayoutComponentType::CB:
363 case PlaneLayoutComponentType::CR:
364 if (planeLayout.sampleIncrementInBits % 8 != 0) {
365 unlock(bufferHandle);
366 return BAD_VALUE;
367 }
368
369 sampleIncrementInBytes = planeLayout.sampleIncrementInBits / 8;
Jason Macnak41209912022-02-16 14:44:44 -0800370 if ((sampleIncrementInBytes != 1) && (sampleIncrementInBytes != 2) &&
371 (sampleIncrementInBytes != 4)) {
Marissa Wall22b2de12019-12-02 18:11:43 -0800372 unlock(bufferHandle);
373 return BAD_VALUE;
374 }
375
376 if (ycbcr.cstride == 0 && ycbcr.chroma_step == 0) {
377 ycbcr.cstride = planeLayout.strideInBytes;
378 ycbcr.chroma_step = sampleIncrementInBytes;
379 } else {
380 if ((static_cast<int64_t>(ycbcr.cstride) != planeLayout.strideInBytes) ||
381 (ycbcr.chroma_step != sampleIncrementInBytes)) {
382 unlock(bufferHandle);
383 return BAD_VALUE;
384 }
385 }
386
387 if (type == PlaneLayoutComponentType::CB) {
388 if (ycbcr.cb != nullptr) {
389 unlock(bufferHandle);
390 return BAD_VALUE;
391 }
392 ycbcr.cb = tmpData;
393 } else {
394 if (ycbcr.cr != nullptr) {
395 unlock(bufferHandle);
396 return BAD_VALUE;
397 }
398 ycbcr.cr = tmpData;
399 }
400 break;
401 default:
402 break;
403 };
404 }
405 }
406
407 *outYcbcr = ycbcr;
Marissa Wall90df5852020-02-27 10:17:02 -0800408 return static_cast<status_t>(Error::NONE);
Marissa Wall87c8ba72019-06-20 14:20:52 -0700409}
410
411int Gralloc4Mapper::unlock(buffer_handle_t bufferHandle) const {
412 auto buffer = const_cast<native_handle_t*>(bufferHandle);
413
414 int releaseFence = -1;
415 Error error;
416 auto ret = mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
417 error = tmpError;
418 if (error != Error::NONE) {
419 return;
420 }
421
422 auto fenceHandle = tmpReleaseFence.getNativeHandle();
423 if (fenceHandle && fenceHandle->numFds == 1) {
424 int fd = dup(fenceHandle->data[0]);
425 if (fd >= 0) {
426 releaseFence = fd;
427 } else {
John Recke0711382022-01-26 12:10:59 -0500428 ALOGW("failed to dup unlock release fence");
Marissa Wall87c8ba72019-06-20 14:20:52 -0700429 sync_wait(fenceHandle->data[0], -1);
430 }
431 }
432 });
433
434 if (!ret.isOk()) {
435 error = kTransactionError;
436 }
437
438 if (error != Error::NONE) {
439 ALOGE("unlock(%p) failed with %d", buffer, error);
440 }
441
442 return releaseFence;
443}
444
Marissa Wall22b2de12019-12-02 18:11:43 -0800445status_t Gralloc4Mapper::isSupported(uint32_t width, uint32_t height, PixelFormat format,
Marissa Wall87c8ba72019-06-20 14:20:52 -0700446 uint32_t layerCount, uint64_t usage,
447 bool* outSupported) const {
448 IMapper::BufferDescriptorInfo descriptorInfo;
Yi Kong6fcddef2023-12-05 17:48:24 +0900449 if (sBufferDescriptorInfo("isSupported", width, height, format, layerCount, usage,
450 &descriptorInfo) != OK) {
John Recke0711382022-01-26 12:10:59 -0500451 // Usage isn't known to the HAL or otherwise failed validation.
452 *outSupported = false;
453 return OK;
454 }
Marissa Wall87c8ba72019-06-20 14:20:52 -0700455
456 Error error;
457 auto ret = mMapper->isSupported(descriptorInfo,
458 [&](const auto& tmpError, const auto& tmpSupported) {
459 error = tmpError;
460 if (error != Error::NONE) {
461 return;
462 }
463 if (outSupported) {
464 *outSupported = tmpSupported;
465 }
466 });
467
468 if (!ret.isOk()) {
469 error = kTransactionError;
470 }
471
472 if (error != Error::NONE) {
473 ALOGE("isSupported(%u, %u, %d, %u, ...) failed with %d", width, height, format, layerCount,
474 error);
475 }
476
477 return static_cast<status_t>(error);
478}
479
Marissa Wall22b2de12019-12-02 18:11:43 -0800480template <class T>
481status_t Gralloc4Mapper::get(buffer_handle_t bufferHandle, const MetadataType& metadataType,
482 DecodeFunction<T> decodeFunction, T* outMetadata) const {
483 if (!outMetadata) {
484 return BAD_VALUE;
485 }
486
487 hidl_vec<uint8_t> vec;
488 Error error;
489 auto ret = mMapper->get(const_cast<native_handle_t*>(bufferHandle), metadataType,
490 [&](const auto& tmpError, const hidl_vec<uint8_t>& tmpVec) {
491 error = tmpError;
492 vec = tmpVec;
493 });
494
495 if (!ret.isOk()) {
496 error = kTransactionError;
497 }
498
499 if (error != Error::NONE) {
500 ALOGE("get(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
501 metadataType.value, error);
502 return static_cast<status_t>(error);
503 }
504
505 return decodeFunction(vec, outMetadata);
506}
507
Alec Mouri9c604e32022-03-18 22:47:44 +0000508template <class T>
509status_t Gralloc4Mapper::set(buffer_handle_t bufferHandle, const MetadataType& metadataType,
510 const T& metadata, EncodeFunction<T> encodeFunction) const {
511 hidl_vec<uint8_t> encodedMetadata;
512 if (const status_t status = encodeFunction(metadata, &encodedMetadata); status != OK) {
513 ALOGE("Encoding metadata(%s) failed with %d", metadataType.name.c_str(), status);
514 return status;
515 }
516 hidl_vec<uint8_t> vec;
517 auto ret =
518 mMapper->set(const_cast<native_handle_t*>(bufferHandle), metadataType, encodedMetadata);
519
520 const Error error = ret.withDefault(kTransactionError);
521 switch (error) {
522 case Error::BAD_DESCRIPTOR:
523 case Error::BAD_BUFFER:
524 case Error::BAD_VALUE:
525 case Error::NO_RESOURCES:
526 ALOGE("set(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
527 metadataType.value, error);
528 break;
529 // It is not an error to attempt to set metadata that a particular gralloc implementation
530 // happens to not support.
531 case Error::UNSUPPORTED:
532 case Error::NONE:
533 break;
534 }
535
536 return static_cast<status_t>(error);
537}
538
Marissa Wall22b2de12019-12-02 18:11:43 -0800539status_t Gralloc4Mapper::getBufferId(buffer_handle_t bufferHandle, uint64_t* outBufferId) const {
540 return get(bufferHandle, gralloc4::MetadataType_BufferId, gralloc4::decodeBufferId,
541 outBufferId);
542}
543
544status_t Gralloc4Mapper::getName(buffer_handle_t bufferHandle, std::string* outName) const {
545 return get(bufferHandle, gralloc4::MetadataType_Name, gralloc4::decodeName, outName);
546}
547
548status_t Gralloc4Mapper::getWidth(buffer_handle_t bufferHandle, uint64_t* outWidth) const {
549 return get(bufferHandle, gralloc4::MetadataType_Width, gralloc4::decodeWidth, outWidth);
550}
551
552status_t Gralloc4Mapper::getHeight(buffer_handle_t bufferHandle, uint64_t* outHeight) const {
553 return get(bufferHandle, gralloc4::MetadataType_Height, gralloc4::decodeHeight, outHeight);
554}
555
556status_t Gralloc4Mapper::getLayerCount(buffer_handle_t bufferHandle,
557 uint64_t* outLayerCount) const {
558 return get(bufferHandle, gralloc4::MetadataType_LayerCount, gralloc4::decodeLayerCount,
559 outLayerCount);
560}
561
562status_t Gralloc4Mapper::getPixelFormatRequested(buffer_handle_t bufferHandle,
563 ui::PixelFormat* outPixelFormatRequested) const {
564 return get(bufferHandle, gralloc4::MetadataType_PixelFormatRequested,
565 gralloc4::decodePixelFormatRequested, outPixelFormatRequested);
566}
567
568status_t Gralloc4Mapper::getPixelFormatFourCC(buffer_handle_t bufferHandle,
569 uint32_t* outPixelFormatFourCC) const {
570 return get(bufferHandle, gralloc4::MetadataType_PixelFormatFourCC,
571 gralloc4::decodePixelFormatFourCC, outPixelFormatFourCC);
572}
573
574status_t Gralloc4Mapper::getPixelFormatModifier(buffer_handle_t bufferHandle,
575 uint64_t* outPixelFormatModifier) const {
576 return get(bufferHandle, gralloc4::MetadataType_PixelFormatModifier,
577 gralloc4::decodePixelFormatModifier, outPixelFormatModifier);
578}
579
580status_t Gralloc4Mapper::getUsage(buffer_handle_t bufferHandle, uint64_t* outUsage) const {
581 return get(bufferHandle, gralloc4::MetadataType_Usage, gralloc4::decodeUsage, outUsage);
582}
583
584status_t Gralloc4Mapper::getAllocationSize(buffer_handle_t bufferHandle,
585 uint64_t* outAllocationSize) const {
586 return get(bufferHandle, gralloc4::MetadataType_AllocationSize, gralloc4::decodeAllocationSize,
587 outAllocationSize);
588}
589
590status_t Gralloc4Mapper::getProtectedContent(buffer_handle_t bufferHandle,
591 uint64_t* outProtectedContent) const {
592 return get(bufferHandle, gralloc4::MetadataType_ProtectedContent,
593 gralloc4::decodeProtectedContent, outProtectedContent);
594}
595
596status_t Gralloc4Mapper::getCompression(buffer_handle_t bufferHandle,
597 ExtendableType* outCompression) const {
598 return get(bufferHandle, gralloc4::MetadataType_Compression, gralloc4::decodeCompression,
599 outCompression);
600}
601
602status_t Gralloc4Mapper::getCompression(buffer_handle_t bufferHandle,
603 ui::Compression* outCompression) const {
604 if (!outCompression) {
605 return BAD_VALUE;
606 }
607 ExtendableType compression;
608 status_t error = getCompression(bufferHandle, &compression);
609 if (error) {
610 return error;
611 }
612 if (!gralloc4::isStandardCompression(compression)) {
613 return BAD_TYPE;
614 }
615 *outCompression = gralloc4::getStandardCompressionValue(compression);
616 return NO_ERROR;
617}
618
619status_t Gralloc4Mapper::getInterlaced(buffer_handle_t bufferHandle,
620 ExtendableType* outInterlaced) const {
621 return get(bufferHandle, gralloc4::MetadataType_Interlaced, gralloc4::decodeInterlaced,
622 outInterlaced);
623}
624
625status_t Gralloc4Mapper::getInterlaced(buffer_handle_t bufferHandle,
626 ui::Interlaced* outInterlaced) const {
627 if (!outInterlaced) {
628 return BAD_VALUE;
629 }
630 ExtendableType interlaced;
631 status_t error = getInterlaced(bufferHandle, &interlaced);
632 if (error) {
633 return error;
634 }
635 if (!gralloc4::isStandardInterlaced(interlaced)) {
636 return BAD_TYPE;
637 }
638 *outInterlaced = gralloc4::getStandardInterlacedValue(interlaced);
639 return NO_ERROR;
640}
641
642status_t Gralloc4Mapper::getChromaSiting(buffer_handle_t bufferHandle,
643 ExtendableType* outChromaSiting) const {
644 return get(bufferHandle, gralloc4::MetadataType_ChromaSiting, gralloc4::decodeChromaSiting,
645 outChromaSiting);
646}
647
648status_t Gralloc4Mapper::getChromaSiting(buffer_handle_t bufferHandle,
649 ui::ChromaSiting* outChromaSiting) const {
650 if (!outChromaSiting) {
651 return BAD_VALUE;
652 }
653 ExtendableType chromaSiting;
654 status_t error = getChromaSiting(bufferHandle, &chromaSiting);
655 if (error) {
656 return error;
657 }
658 if (!gralloc4::isStandardChromaSiting(chromaSiting)) {
659 return BAD_TYPE;
660 }
661 *outChromaSiting = gralloc4::getStandardChromaSitingValue(chromaSiting);
662 return NO_ERROR;
663}
664
665status_t Gralloc4Mapper::getPlaneLayouts(buffer_handle_t bufferHandle,
666 std::vector<ui::PlaneLayout>* outPlaneLayouts) const {
667 return get(bufferHandle, gralloc4::MetadataType_PlaneLayouts, gralloc4::decodePlaneLayouts,
668 outPlaneLayouts);
669}
670
671status_t Gralloc4Mapper::getDataspace(buffer_handle_t bufferHandle,
672 ui::Dataspace* outDataspace) const {
673 if (!outDataspace) {
674 return BAD_VALUE;
675 }
Yichi Chenba40db52021-04-30 00:18:32 +0800676 AidlDataspace dataspace;
Marissa Wall22b2de12019-12-02 18:11:43 -0800677 status_t error = get(bufferHandle, gralloc4::MetadataType_Dataspace, gralloc4::decodeDataspace,
678 &dataspace);
679 if (error) {
680 return error;
681 }
682
683 // Gralloc4 uses stable AIDL dataspace but the rest of the system still uses HIDL dataspace
684 *outDataspace = static_cast<ui::Dataspace>(dataspace);
685 return NO_ERROR;
686}
687
Alec Mouri9c604e32022-03-18 22:47:44 +0000688status_t Gralloc4Mapper::setDataspace(buffer_handle_t bufferHandle, ui::Dataspace dataspace) const {
689 return set(bufferHandle, gralloc4::MetadataType_Dataspace,
690 static_cast<aidl::android::hardware::graphics::common::Dataspace>(dataspace),
691 gralloc4::encodeDataspace);
692}
693
Marissa Wall22b2de12019-12-02 18:11:43 -0800694status_t Gralloc4Mapper::getBlendMode(buffer_handle_t bufferHandle,
695 ui::BlendMode* outBlendMode) const {
696 return get(bufferHandle, gralloc4::MetadataType_BlendMode, gralloc4::decodeBlendMode,
697 outBlendMode);
698}
699
Marissa Wallef785e12019-12-12 14:26:59 -0800700status_t Gralloc4Mapper::getSmpte2086(buffer_handle_t bufferHandle,
701 std::optional<ui::Smpte2086>* outSmpte2086) const {
702 return get(bufferHandle, gralloc4::MetadataType_Smpte2086, gralloc4::decodeSmpte2086,
703 outSmpte2086);
704}
705
Alec Mouri9c604e32022-03-18 22:47:44 +0000706status_t Gralloc4Mapper::setSmpte2086(buffer_handle_t bufferHandle,
707 std::optional<ui::Smpte2086> smpte2086) const {
708 return set(bufferHandle, gralloc4::MetadataType_Smpte2086, smpte2086,
709 gralloc4::encodeSmpte2086);
710}
711
Marissa Wallef785e12019-12-12 14:26:59 -0800712status_t Gralloc4Mapper::getCta861_3(buffer_handle_t bufferHandle,
713 std::optional<ui::Cta861_3>* outCta861_3) const {
714 return get(bufferHandle, gralloc4::MetadataType_Cta861_3, gralloc4::decodeCta861_3,
715 outCta861_3);
716}
717
Alec Mouri9c604e32022-03-18 22:47:44 +0000718status_t Gralloc4Mapper::setCta861_3(buffer_handle_t bufferHandle,
719 std::optional<ui::Cta861_3> cta861_3) const {
720 return set(bufferHandle, gralloc4::MetadataType_Cta861_3, cta861_3, gralloc4::encodeCta861_3);
721}
722
Marissa Wallef785e12019-12-12 14:26:59 -0800723status_t Gralloc4Mapper::getSmpte2094_40(
724 buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>>* outSmpte2094_40) const {
725 return get(bufferHandle, gralloc4::MetadataType_Smpte2094_40, gralloc4::decodeSmpte2094_40,
726 outSmpte2094_40);
727}
728
Alec Mouri9c604e32022-03-18 22:47:44 +0000729status_t Gralloc4Mapper::setSmpte2094_40(buffer_handle_t bufferHandle,
730 std::optional<std::vector<uint8_t>> smpte2094_40) const {
731 return set(bufferHandle, gralloc4::MetadataType_Smpte2094_40, smpte2094_40,
732 gralloc4::encodeSmpte2094_40);
733}
734
Alec Mouri332765e2021-10-06 16:38:12 -0700735status_t Gralloc4Mapper::getSmpte2094_10(
736 buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>>* outSmpte2094_10) const {
737 return get(bufferHandle, gralloc4::MetadataType_Smpte2094_10, gralloc4::decodeSmpte2094_10,
738 outSmpte2094_10);
739}
740
Alec Mouri9c604e32022-03-18 22:47:44 +0000741status_t Gralloc4Mapper::setSmpte2094_10(buffer_handle_t bufferHandle,
742 std::optional<std::vector<uint8_t>> smpte2094_10) const {
743 return set(bufferHandle, gralloc4::MetadataType_Smpte2094_10, smpte2094_10,
744 gralloc4::encodeSmpte2094_10);
745}
746
Marissa Wall22b2de12019-12-02 18:11:43 -0800747std::vector<MetadataTypeDescription> Gralloc4Mapper::listSupportedMetadataTypes() const {
748 hidl_vec<MetadataTypeDescription> descriptions;
749 Error error;
750 auto ret = mMapper->listSupportedMetadataTypes(
751 [&](const auto& tmpError, const auto& tmpDescriptions) {
752 error = tmpError;
753 descriptions = tmpDescriptions;
754 });
755
756 if (!ret.isOk()) {
757 error = kTransactionError;
758 }
759
760 if (error != Error::NONE) {
761 ALOGE("listSupportedMetadataType() failed with %d", error);
762 return {};
763 }
764
765 return static_cast<std::vector<MetadataTypeDescription>>(descriptions);
766}
767
768template <class T>
769status_t Gralloc4Mapper::metadataDumpHelper(const BufferDump& bufferDump,
770 StandardMetadataType metadataType,
771 DecodeFunction<T> decodeFunction, T* outT) const {
772 const auto& metadataDump = bufferDump.metadataDump;
773
774 auto itr =
775 std::find_if(metadataDump.begin(), metadataDump.end(),
776 [&](const MetadataDump& tmpMetadataDump) {
777 if (!gralloc4::isStandardMetadataType(tmpMetadataDump.metadataType)) {
778 return false;
779 }
780 return metadataType ==
781 gralloc4::getStandardMetadataTypeValue(
782 tmpMetadataDump.metadataType);
783 });
784 if (itr == metadataDump.end()) {
785 return BAD_VALUE;
786 }
787
788 return decodeFunction(itr->metadata, outT);
789}
790
791status_t Gralloc4Mapper::bufferDumpHelper(const BufferDump& bufferDump, std::ostringstream* outDump,
792 uint64_t* outAllocationSize, bool less) const {
793 uint64_t bufferId;
794 std::string name;
795 uint64_t width;
796 uint64_t height;
797 uint64_t layerCount;
798 ui::PixelFormat pixelFormatRequested;
799 uint32_t pixelFormatFourCC;
800 uint64_t pixelFormatModifier;
801 uint64_t usage;
Yichi Chenba40db52021-04-30 00:18:32 +0800802 AidlDataspace dataspace;
Marissa Wall22b2de12019-12-02 18:11:43 -0800803 uint64_t allocationSize;
804 uint64_t protectedContent;
805 ExtendableType compression;
806 ExtendableType interlaced;
807 ExtendableType chromaSiting;
808 std::vector<ui::PlaneLayout> planeLayouts;
809
810 status_t error = metadataDumpHelper(bufferDump, StandardMetadataType::BUFFER_ID,
811 gralloc4::decodeBufferId, &bufferId);
812 if (error != NO_ERROR) {
813 return error;
814 }
815 error = metadataDumpHelper(bufferDump, StandardMetadataType::NAME, gralloc4::decodeName, &name);
816 if (error != NO_ERROR) {
817 return error;
818 }
819 error = metadataDumpHelper(bufferDump, StandardMetadataType::WIDTH, gralloc4::decodeWidth,
820 &width);
821 if (error != NO_ERROR) {
822 return error;
823 }
824 error = metadataDumpHelper(bufferDump, StandardMetadataType::HEIGHT, gralloc4::decodeHeight,
825 &height);
826 if (error != NO_ERROR) {
827 return error;
828 }
829 error = metadataDumpHelper(bufferDump, StandardMetadataType::LAYER_COUNT,
830 gralloc4::decodeLayerCount, &layerCount);
831 if (error != NO_ERROR) {
832 return error;
833 }
834 error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_REQUESTED,
835 gralloc4::decodePixelFormatRequested, &pixelFormatRequested);
836 if (error != NO_ERROR) {
837 return error;
838 }
839 error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_FOURCC,
840 gralloc4::decodePixelFormatFourCC, &pixelFormatFourCC);
841 if (error != NO_ERROR) {
842 return error;
843 }
844 error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_MODIFIER,
845 gralloc4::decodePixelFormatModifier, &pixelFormatModifier);
846 if (error != NO_ERROR) {
847 return error;
848 }
849 error = metadataDumpHelper(bufferDump, StandardMetadataType::USAGE, gralloc4::decodeUsage,
850 &usage);
851 if (error != NO_ERROR) {
852 return error;
853 }
Yichi Chenba40db52021-04-30 00:18:32 +0800854 error = metadataDumpHelper(bufferDump, StandardMetadataType::DATASPACE,
855 gralloc4::decodeDataspace, &dataspace);
856 if (error != NO_ERROR) {
857 return error;
858 }
Marissa Wall22b2de12019-12-02 18:11:43 -0800859 error = metadataDumpHelper(bufferDump, StandardMetadataType::ALLOCATION_SIZE,
860 gralloc4::decodeAllocationSize, &allocationSize);
861 if (error != NO_ERROR) {
862 return error;
863 }
864 error = metadataDumpHelper(bufferDump, StandardMetadataType::PROTECTED_CONTENT,
865 gralloc4::decodeProtectedContent, &protectedContent);
866 if (error != NO_ERROR) {
867 return error;
868 }
869 error = metadataDumpHelper(bufferDump, StandardMetadataType::COMPRESSION,
870 gralloc4::decodeCompression, &compression);
871 if (error != NO_ERROR) {
872 return error;
873 }
874 error = metadataDumpHelper(bufferDump, StandardMetadataType::INTERLACED,
875 gralloc4::decodeInterlaced, &interlaced);
876 if (error != NO_ERROR) {
877 return error;
878 }
879 error = metadataDumpHelper(bufferDump, StandardMetadataType::CHROMA_SITING,
880 gralloc4::decodeChromaSiting, &chromaSiting);
881 if (error != NO_ERROR) {
882 return error;
883 }
884 error = metadataDumpHelper(bufferDump, StandardMetadataType::PLANE_LAYOUTS,
885 gralloc4::decodePlaneLayouts, &planeLayouts);
886 if (error != NO_ERROR) {
887 return error;
888 }
889
890 if (outAllocationSize) {
891 *outAllocationSize = allocationSize;
892 }
893 double allocationSizeKiB = static_cast<double>(allocationSize) / 1024;
894
Alec Mouri04511ef2022-01-06 12:57:12 -0800895 *outDump << "+ name:" << name << ", id:" << bufferId << ", size:" << std::fixed
896 << allocationSizeKiB << "KiB, w/h:" << width << "x" << height << ", usage: 0x"
897 << std::hex << usage << std::dec
898 << ", req fmt:" << static_cast<int32_t>(pixelFormatRequested)
Marissa Wall22b2de12019-12-02 18:11:43 -0800899 << ", fourcc/mod:" << pixelFormatFourCC << "/" << pixelFormatModifier
Yichi Chen6de5b582021-09-13 20:00:52 +0800900 << ", dataspace: 0x" << std::hex << static_cast<uint32_t>(dataspace) << std::dec
Marissa Wall22b2de12019-12-02 18:11:43 -0800901 << ", compressed: ";
902
903 if (less) {
904 bool isCompressed = !gralloc4::isStandardCompression(compression) ||
905 (gralloc4::getStandardCompressionValue(compression) != ui::Compression::NONE);
906 *outDump << std::boolalpha << isCompressed << "\n";
907 } else {
908 *outDump << gralloc4::getCompressionName(compression) << "\n";
909 }
910
911 bool firstPlane = true;
912 for (const auto& planeLayout : planeLayouts) {
913 if (firstPlane) {
914 firstPlane = false;
915 *outDump << "\tplanes: ";
916 } else {
917 *outDump << "\t ";
918 }
919
920 for (size_t i = 0; i < planeLayout.components.size(); i++) {
921 const auto& planeLayoutComponent = planeLayout.components[i];
922 *outDump << gralloc4::getPlaneLayoutComponentTypeName(planeLayoutComponent.type);
923 if (i < planeLayout.components.size() - 1) {
924 *outDump << "/";
925 } else {
926 *outDump << ":\t";
927 }
928 }
929 *outDump << " w/h:" << planeLayout.widthInSamples << "x" << planeLayout.heightInSamples
930 << ", stride:" << planeLayout.strideInBytes
931 << " bytes, size:" << planeLayout.totalSizeInBytes;
932 if (!less) {
933 *outDump << ", inc:" << planeLayout.sampleIncrementInBits
934 << " bits, subsampling w/h:" << planeLayout.horizontalSubsampling << "x"
935 << planeLayout.verticalSubsampling;
936 }
937 *outDump << "\n";
938 }
939
940 if (!less) {
941 *outDump << "\tlayer cnt: " << layerCount << ", protected content: " << protectedContent
942 << ", interlaced: " << gralloc4::getInterlacedName(interlaced)
943 << ", chroma siting:" << gralloc4::getChromaSitingName(chromaSiting) << "\n";
944 }
945
946 return NO_ERROR;
947}
948
949std::string Gralloc4Mapper::dumpBuffer(buffer_handle_t bufferHandle, bool less) const {
950 auto buffer = const_cast<native_handle_t*>(bufferHandle);
951
952 BufferDump bufferDump;
953 Error error;
954 auto ret = mMapper->dumpBuffer(buffer, [&](const auto& tmpError, const auto& tmpBufferDump) {
955 error = tmpError;
956 bufferDump = tmpBufferDump;
957 });
958
959 if (!ret.isOk()) {
960 error = kTransactionError;
961 }
962
963 if (error != Error::NONE) {
964 ALOGE("dumpBuffer() failed with %d", error);
965 return "";
966 }
967
968 std::ostringstream stream;
969 stream.precision(2);
970
971 status_t err = bufferDumpHelper(bufferDump, &stream, nullptr, less);
972 if (err != NO_ERROR) {
973 ALOGE("bufferDumpHelper() failed with %d", err);
974 return "";
975 }
976
977 return stream.str();
978}
979
980std::string Gralloc4Mapper::dumpBuffers(bool less) const {
981 hidl_vec<BufferDump> bufferDumps;
982 Error error;
983 auto ret = mMapper->dumpBuffers([&](const auto& tmpError, const auto& tmpBufferDump) {
984 error = tmpError;
985 bufferDumps = tmpBufferDump;
986 });
987
988 if (!ret.isOk()) {
989 error = kTransactionError;
990 }
991
992 if (error != Error::NONE) {
993 ALOGE("dumpBuffer() failed with %d", error);
994 return "";
995 }
996
997 uint64_t totalAllocationSize = 0;
998 std::ostringstream stream;
999 stream.precision(2);
1000
1001 stream << "Imported gralloc buffers:\n";
1002
1003 for (const auto& bufferDump : bufferDumps) {
1004 uint64_t allocationSize = 0;
1005 status_t err = bufferDumpHelper(bufferDump, &stream, &allocationSize, less);
1006 if (err != NO_ERROR) {
1007 ALOGE("bufferDumpHelper() failed with %d", err);
1008 return "";
1009 }
1010 totalAllocationSize += allocationSize;
1011 }
1012
1013 double totalAllocationSizeKiB = static_cast<double>(totalAllocationSize) / 1024;
1014 stream << "Total imported by gralloc: " << totalAllocationSizeKiB << "KiB\n";
1015 return stream.str();
1016}
1017
Marissa Wall87c8ba72019-06-20 14:20:52 -07001018Gralloc4Allocator::Gralloc4Allocator(const Gralloc4Mapper& mapper) : mMapper(mapper) {
1019 mAllocator = IAllocator::getService();
John Reck614326b2022-01-11 15:49:54 -05001020 if (__builtin_available(android 31, *)) {
1021 if (hasIAllocatorAidl()) {
Charles Chen788b58b2023-02-13 18:02:10 +00001022 // TODO(b/269517338): Perform the isolated checking for this in service manager instead.
1023 uid_t aid = multiuser_get_app_id(getuid());
1024 if (aid >= AID_ISOLATED_START && aid <= AID_ISOLATED_END) {
1025 mAidlAllocator = AidlIAllocator::fromBinder(ndk::SpAIBinder(
1026 AServiceManager_getService(kAidlAllocatorServiceName.c_str())));
1027 } else {
1028 mAidlAllocator = AidlIAllocator::fromBinder(ndk::SpAIBinder(
1029 AServiceManager_waitForService(kAidlAllocatorServiceName.c_str())));
1030 }
John Reck614326b2022-01-11 15:49:54 -05001031 ALOGE_IF(!mAidlAllocator, "AIDL IAllocator declared but failed to get service");
1032 }
1033 }
Devin Mooree401e882022-04-11 22:41:58 +00001034 if (mAllocator == nullptr && mAidlAllocator == nullptr) {
1035 ALOGW("allocator 4.x is not supported");
1036 return;
1037 }
Marissa Wall87c8ba72019-06-20 14:20:52 -07001038}
1039
1040bool Gralloc4Allocator::isLoaded() const {
Devin Mooree401e882022-04-11 22:41:58 +00001041 return mAllocator != nullptr || mAidlAllocator != nullptr;
Marissa Wall87c8ba72019-06-20 14:20:52 -07001042}
1043
Marissa Wall22b2de12019-12-02 18:11:43 -08001044std::string Gralloc4Allocator::dumpDebugInfo(bool less) const {
1045 return mMapper.dumpBuffers(less);
Marissa Wall87c8ba72019-06-20 14:20:52 -07001046}
1047
Marissa Wall22b2de12019-12-02 18:11:43 -08001048status_t Gralloc4Allocator::allocate(std::string requestorName, uint32_t width, uint32_t height,
1049 android::PixelFormat format, uint32_t layerCount,
John Reckd727e9c2023-12-08 11:30:37 -05001050 uint64_t usage, uint32_t* outStride,
Marissa Wall22b2de12019-12-02 18:11:43 -08001051 buffer_handle_t* outBufferHandles, bool importBuffers) const {
Marissa Wall87c8ba72019-06-20 14:20:52 -07001052 IMapper::BufferDescriptorInfo descriptorInfo;
John Recke0711382022-01-26 12:10:59 -05001053 if (auto error = sBufferDescriptorInfo(requestorName, width, height, format, layerCount, usage,
1054 &descriptorInfo) != OK) {
1055 return error;
1056 }
Marissa Wall87c8ba72019-06-20 14:20:52 -07001057
1058 BufferDescriptor descriptor;
1059 status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),
1060 static_cast<void*>(&descriptor));
1061 if (error != NO_ERROR) {
1062 return error;
1063 }
1064
John Reckd727e9c2023-12-08 11:30:37 -05001065 constexpr auto bufferCount = 1;
1066
John Reck614326b2022-01-11 15:49:54 -05001067 if (mAidlAllocator) {
1068 AllocationResult result;
John Reck0ff95c92022-12-08 11:45:29 -05001069#pragma clang diagnostic push
1070#pragma clang diagnostic ignored "-Wdeprecated-declarations"
John Reck614326b2022-01-11 15:49:54 -05001071 auto status = mAidlAllocator->allocate(descriptor, bufferCount, &result);
John Reck0ff95c92022-12-08 11:45:29 -05001072#pragma clang diagnostic pop // deprecation
John Reck614326b2022-01-11 15:49:54 -05001073 if (!status.isOk()) {
1074 error = status.getExceptionCode();
1075 if (error == EX_SERVICE_SPECIFIC) {
1076 error = status.getServiceSpecificError();
1077 }
1078 if (error == OK) {
1079 error = UNKNOWN_ERROR;
1080 }
1081 } else {
1082 if (importBuffers) {
1083 for (uint32_t i = 0; i < bufferCount; i++) {
Christopher Ferris14ec0802022-04-22 13:23:43 -07001084 auto handle = makeFromAidl(result.buffers[i]);
1085 error = mMapper.importBuffer(handle, &outBufferHandles[i]);
1086 native_handle_delete(handle);
John Reck614326b2022-01-11 15:49:54 -05001087 if (error != NO_ERROR) {
1088 for (uint32_t j = 0; j < i; j++) {
1089 mMapper.freeBuffer(outBufferHandles[j]);
1090 outBufferHandles[j] = nullptr;
1091 }
1092 break;
1093 }
1094 }
1095 } else {
1096 for (uint32_t i = 0; i < bufferCount; i++) {
1097 outBufferHandles[i] = dupFromAidl(result.buffers[i]);
1098 if (!outBufferHandles[i]) {
1099 for (uint32_t j = 0; j < i; j++) {
1100 auto buffer = const_cast<native_handle_t*>(outBufferHandles[j]);
1101 native_handle_close(buffer);
1102 native_handle_delete(buffer);
1103 outBufferHandles[j] = nullptr;
1104 }
1105 }
1106 }
1107 }
1108 }
1109 *outStride = result.stride;
1110 // Release all the resources held by AllocationResult (specifically any remaining FDs)
1111 result = {};
1112 // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
1113 hardware::IPCThreadState::self()->flushCommands();
1114 return error;
1115 }
1116
Marissa Wall87c8ba72019-06-20 14:20:52 -07001117 auto ret = mAllocator->allocate(descriptor, bufferCount,
1118 [&](const auto& tmpError, const auto& tmpStride,
1119 const auto& tmpBuffers) {
1120 error = static_cast<status_t>(tmpError);
1121 if (tmpError != Error::NONE) {
1122 return;
1123 }
1124
Marissa Wallbfcf81f2019-11-27 10:36:29 -08001125 if (importBuffers) {
1126 for (uint32_t i = 0; i < bufferCount; i++) {
1127 error = mMapper.importBuffer(tmpBuffers[i],
1128 &outBufferHandles[i]);
1129 if (error != NO_ERROR) {
1130 for (uint32_t j = 0; j < i; j++) {
1131 mMapper.freeBuffer(outBufferHandles[j]);
1132 outBufferHandles[j] = nullptr;
1133 }
1134 return;
Marissa Wall87c8ba72019-06-20 14:20:52 -07001135 }
Marissa Wallbfcf81f2019-11-27 10:36:29 -08001136 }
1137 } else {
1138 for (uint32_t i = 0; i < bufferCount; i++) {
1139 outBufferHandles[i] = native_handle_clone(
1140 tmpBuffers[i].getNativeHandle());
1141 if (!outBufferHandles[i]) {
1142 for (uint32_t j = 0; j < i; j++) {
1143 auto buffer = const_cast<native_handle_t*>(
1144 outBufferHandles[j]);
1145 native_handle_close(buffer);
1146 native_handle_delete(buffer);
1147 outBufferHandles[j] = nullptr;
1148 }
1149 }
Marissa Wall87c8ba72019-06-20 14:20:52 -07001150 }
1151 }
1152 *outStride = tmpStride;
1153 });
1154
1155 // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
1156 hardware::IPCThreadState::self()->flushCommands();
1157
1158 return (ret.isOk()) ? error : static_cast<status_t>(kTransactionError);
1159}
1160
1161} // namespace android