blob: 4f950b8c4af4c03922a44a1c955afbc487030bd5 [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>
Alec Mouri9c604e32022-03-18 22:47:44 +000025#include <gralloctypes/Gralloc4.h>
Marissa Wall87c8ba72019-06-20 14:20:52 -070026#include <hidl/ServiceManagement.h>
27#include <hwbinder/IPCThreadState.h>
28#include <ui/Gralloc4.h>
29
30#include <inttypes.h>
31#include <log/log.h>
32#pragma clang diagnostic push
33#pragma clang diagnostic ignored "-Wzero-length-array"
34#include <sync/sync.h>
35#pragma clang diagnostic pop
36
John Reck614326b2022-01-11 15:49:54 -050037using aidl::android::hardware::graphics::allocator::AllocationError;
38using aidl::android::hardware::graphics::allocator::AllocationResult;
Marissa Wall22b2de12019-12-02 18:11:43 -080039using aidl::android::hardware::graphics::common::ExtendableType;
40using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
41using aidl::android::hardware::graphics::common::StandardMetadataType;
42using android::hardware::hidl_vec;
Marissa Wall87c8ba72019-06-20 14:20:52 -070043using android::hardware::graphics::allocator::V4_0::IAllocator;
44using android::hardware::graphics::common::V1_2::BufferUsage;
Chris Forbes6c09ee72022-01-26 18:48:55 +130045using android::hardware::graphics::common::V1_2::PixelFormat;
Marissa Wall87c8ba72019-06-20 14:20:52 -070046using android::hardware::graphics::mapper::V4_0::BufferDescriptor;
47using android::hardware::graphics::mapper::V4_0::Error;
48using android::hardware::graphics::mapper::V4_0::IMapper;
John Reck614326b2022-01-11 15:49:54 -050049using AidlIAllocator = ::aidl::android::hardware::graphics::allocator::IAllocator;
50using AidlBufferUsage = ::aidl::android::hardware::graphics::common::BufferUsage;
Yichi Chenba40db52021-04-30 00:18:32 +080051using AidlDataspace = ::aidl::android::hardware::graphics::common::Dataspace;
John Reck614326b2022-01-11 15:49:54 -050052using AidlNativeHandle = ::aidl::android::hardware::common::NativeHandle;
Marissa Wall22b2de12019-12-02 18:11:43 -080053using BufferDump = android::hardware::graphics::mapper::V4_0::IMapper::BufferDump;
54using MetadataDump = android::hardware::graphics::mapper::V4_0::IMapper::MetadataDump;
55using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
56using MetadataTypeDescription =
57 android::hardware::graphics::mapper::V4_0::IMapper::MetadataTypeDescription;
Marissa Wall87c8ba72019-06-20 14:20:52 -070058
59namespace android {
60
61namespace {
62
63static constexpr Error kTransactionError = Error::NO_RESOURCES;
John Reck614326b2022-01-11 15:49:54 -050064static const auto kAidlAllocatorServiceName = AidlIAllocator::descriptor + std::string("/default");
Marissa Wall87c8ba72019-06-20 14:20:52 -070065
Robin Lee38b59412022-02-02 22:53:15 +010066// TODO(b/72323293, b/72703005): Remove these invalid bits from callers
67static constexpr uint64_t kRemovedUsageBits = static_cast<uint64_t>((1 << 10) | (1 << 13));
68
Marissa Wall87c8ba72019-06-20 14:20:52 -070069uint64_t getValidUsageBits() {
70 static const uint64_t validUsageBits = []() -> uint64_t {
71 uint64_t bits = 0;
72 for (const auto bit :
73 hardware::hidl_enum_range<hardware::graphics::common::V1_2::BufferUsage>()) {
74 bits = bits | bit;
75 }
76 return bits;
77 }();
Robin Lee38b59412022-02-02 22:53:15 +010078 return validUsageBits | kRemovedUsageBits;
Marissa Wall87c8ba72019-06-20 14:20:52 -070079}
80
John Reck614326b2022-01-11 15:49:54 -050081uint64_t getValidUsageBits41() {
82 static const uint64_t validUsageBits = []() -> uint64_t {
83 uint64_t bits = 0;
84 for (const auto bit : ndk::enum_range<AidlBufferUsage>{}) {
85 bits |= static_cast<int64_t>(bit);
86 }
87 return bits;
88 }();
89 return validUsageBits;
90}
91
Marissa Wall87c8ba72019-06-20 14:20:52 -070092static inline IMapper::Rect sGralloc4Rect(const Rect& rect) {
93 IMapper::Rect outRect{};
94 outRect.left = rect.left;
95 outRect.top = rect.top;
96 outRect.width = rect.width();
97 outRect.height = rect.height();
98 return outRect;
99}
Marissa Wall87c8ba72019-06-20 14:20:52 -0700100
John Reck614326b2022-01-11 15:49:54 -0500101// See if gralloc "4.1" is available.
102static bool hasIAllocatorAidl() {
103 // Avoid re-querying repeatedly for this information;
104 static bool sHasIAllocatorAidl = []() -> bool {
John Reck614326b2022-01-11 15:49:54 -0500105 if (__builtin_available(android 31, *)) {
106 return AServiceManager_isDeclared(kAidlAllocatorServiceName.c_str());
107 }
108 return false;
109 }();
110 return sHasIAllocatorAidl;
111}
112
John Recke0711382022-01-26 12:10:59 -0500113// Determines whether the passed info is compatible with the mapper.
114static status_t validateBufferDescriptorInfo(IMapper::BufferDescriptorInfo* descriptorInfo) {
115 uint64_t validUsageBits = getValidUsageBits();
116 if (hasIAllocatorAidl()) {
117 validUsageBits |= getValidUsageBits41();
118 }
119
120 if (descriptorInfo->usage & ~validUsageBits) {
121 ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64,
122 descriptorInfo->usage & ~validUsageBits);
123 return BAD_VALUE;
124 }
Chris Forbes6c09ee72022-01-26 18:48:55 +1300125
126 // Combinations that are only allowed with gralloc 4.1.
127 // Previous grallocs must be protected from this.
128 if (!hasIAllocatorAidl() &&
129 descriptorInfo->format != hardware::graphics::common::V1_2::PixelFormat::BLOB &&
130 descriptorInfo->usage & BufferUsage::GPU_DATA_BUFFER) {
131 ALOGE("non-BLOB pixel format with GPU_DATA_BUFFER usage is not supported prior to gralloc 4.1");
132 return BAD_VALUE;
133 }
134
John Recke0711382022-01-26 12:10:59 -0500135 return NO_ERROR;
136}
137
138static inline status_t sBufferDescriptorInfo(std::string name, uint32_t width, uint32_t height,
139 PixelFormat format, uint32_t layerCount,
140 uint64_t usage,
141 IMapper::BufferDescriptorInfo* outDescriptorInfo) {
142 outDescriptorInfo->name = name;
143 outDescriptorInfo->width = width;
144 outDescriptorInfo->height = height;
145 outDescriptorInfo->layerCount = layerCount;
146 outDescriptorInfo->format = static_cast<hardware::graphics::common::V1_2::PixelFormat>(format);
147 outDescriptorInfo->usage = usage;
148 outDescriptorInfo->reservedSize = 0;
149
150 return validateBufferDescriptorInfo(outDescriptorInfo);
151}
152
Marissa Wall87c8ba72019-06-20 14:20:52 -0700153} // anonymous namespace
154
155void Gralloc4Mapper::preload() {
156 android::hardware::preloadPassthroughService<IMapper>();
157}
158
159Gralloc4Mapper::Gralloc4Mapper() {
160 mMapper = IMapper::getService();
161 if (mMapper == nullptr) {
162 ALOGI("mapper 4.x is not supported");
163 return;
164 }
165 if (mMapper->isRemote()) {
166 LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
167 }
168}
169
170bool Gralloc4Mapper::isLoaded() const {
171 return mMapper != nullptr;
172}
173
Marissa Wall87c8ba72019-06-20 14:20:52 -0700174status_t Gralloc4Mapper::createDescriptor(void* bufferDescriptorInfo,
175 void* outBufferDescriptor) const {
176 IMapper::BufferDescriptorInfo* descriptorInfo =
177 static_cast<IMapper::BufferDescriptorInfo*>(bufferDescriptorInfo);
178 BufferDescriptor* outDescriptor = static_cast<BufferDescriptor*>(outBufferDescriptor);
179
180 status_t status = validateBufferDescriptorInfo(descriptorInfo);
181 if (status != NO_ERROR) {
182 return status;
183 }
184
185 Error error;
186 auto hidl_cb = [&](const auto& tmpError, const auto& tmpDescriptor) {
187 error = tmpError;
188 if (error != Error::NONE) {
189 return;
190 }
191 *outDescriptor = tmpDescriptor;
192 };
193
194 hardware::Return<void> ret = mMapper->createDescriptor(*descriptorInfo, hidl_cb);
195
196 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
197}
198
199status_t Gralloc4Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
200 buffer_handle_t* outBufferHandle) const {
201 Error error;
202 auto ret = mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
203 error = tmpError;
204 if (error != Error::NONE) {
205 return;
206 }
207 *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
208 });
209
210 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
211}
212
213void Gralloc4Mapper::freeBuffer(buffer_handle_t bufferHandle) const {
214 auto buffer = const_cast<native_handle_t*>(bufferHandle);
215 auto ret = mMapper->freeBuffer(buffer);
216
217 auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
218 ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d", buffer, error);
219}
220
221status_t Gralloc4Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
Marissa Wall22b2de12019-12-02 18:11:43 -0800222 uint32_t height, PixelFormat format,
Marissa Wall87c8ba72019-06-20 14:20:52 -0700223 uint32_t layerCount, uint64_t usage,
224 uint32_t stride) const {
225 IMapper::BufferDescriptorInfo descriptorInfo;
John Recke0711382022-01-26 12:10:59 -0500226 if (auto error = sBufferDescriptorInfo("validateBufferSize", width, height, format, layerCount,
227 usage, &descriptorInfo) != OK) {
228 return error;
229 }
Marissa Wall87c8ba72019-06-20 14:20:52 -0700230
231 auto buffer = const_cast<native_handle_t*>(bufferHandle);
232 auto ret = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
233
234 return static_cast<status_t>((ret.isOk()) ? static_cast<Error>(ret) : kTransactionError);
235}
236
237void Gralloc4Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t* outNumFds,
238 uint32_t* outNumInts) const {
239 *outNumFds = uint32_t(bufferHandle->numFds);
240 *outNumInts = uint32_t(bufferHandle->numInts);
241
242 Error error;
243 auto buffer = const_cast<native_handle_t*>(bufferHandle);
244 auto ret = mMapper->getTransportSize(buffer,
245 [&](const auto& tmpError, const auto& tmpNumFds,
246 const auto& tmpNumInts) {
247 error = tmpError;
248 if (error != Error::NONE) {
249 return;
250 }
251 *outNumFds = tmpNumFds;
252 *outNumInts = tmpNumInts;
253 });
254
255 error = (ret.isOk()) ? error : kTransactionError;
256
257 ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d", buffer, error);
258}
259
260status_t Gralloc4Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
261 int acquireFence, void** outData, int32_t* outBytesPerPixel,
262 int32_t* outBytesPerStride) const {
Marissa Wall22b2de12019-12-02 18:11:43 -0800263 std::vector<ui::PlaneLayout> planeLayouts;
264 status_t err = getPlaneLayouts(bufferHandle, &planeLayouts);
265
Valerie Hau3bb97912020-04-09 10:40:10 -0700266 if (err == NO_ERROR && !planeLayouts.empty()) {
Marissa Wall22b2de12019-12-02 18:11:43 -0800267 if (outBytesPerPixel) {
268 int32_t bitsPerPixel = planeLayouts.front().sampleIncrementInBits;
269 for (const auto& planeLayout : planeLayouts) {
270 if (bitsPerPixel != planeLayout.sampleIncrementInBits) {
271 bitsPerPixel = -1;
272 }
273 }
274 if (bitsPerPixel >= 0 && bitsPerPixel % 8 == 0) {
275 *outBytesPerPixel = bitsPerPixel / 8;
276 } else {
277 *outBytesPerPixel = -1;
278 }
279 }
280 if (outBytesPerStride) {
281 int32_t bytesPerStride = planeLayouts.front().strideInBytes;
282 for (const auto& planeLayout : planeLayouts) {
283 if (bytesPerStride != planeLayout.strideInBytes) {
284 bytesPerStride = -1;
285 }
286 }
287 if (bytesPerStride >= 0) {
288 *outBytesPerStride = bytesPerStride;
289 } else {
290 *outBytesPerStride = -1;
291 }
292 }
Marissa Wall20611c62019-11-05 15:06:24 -0800293 }
294
Marissa Wall87c8ba72019-06-20 14:20:52 -0700295 auto buffer = const_cast<native_handle_t*>(bufferHandle);
296
297 IMapper::Rect accessRegion = sGralloc4Rect(bounds);
298
299 // put acquireFence in a hidl_handle
300 hardware::hidl_handle acquireFenceHandle;
301 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
302 if (acquireFence >= 0) {
303 auto h = native_handle_init(acquireFenceStorage, 1, 0);
304 h->data[0] = acquireFence;
305 acquireFenceHandle = h;
306 }
307
308 Error error;
309 auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
Marissa Wall20611c62019-11-05 15:06:24 -0800310 [&](const auto& tmpError, const auto& tmpData) {
Marissa Wall87c8ba72019-06-20 14:20:52 -0700311 error = tmpError;
312 if (error != Error::NONE) {
313 return;
314 }
315 *outData = tmpData;
Marissa Wall87c8ba72019-06-20 14:20:52 -0700316 });
317
318 // we own acquireFence even on errors
319 if (acquireFence >= 0) {
320 close(acquireFence);
321 }
322
323 error = (ret.isOk()) ? error : kTransactionError;
324
325 ALOGW_IF(error != Error::NONE, "lock(%p, ...) failed: %d", bufferHandle, error);
326
327 return static_cast<status_t>(error);
328}
329
Marissa Wall22b2de12019-12-02 18:11:43 -0800330status_t Gralloc4Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
331 int acquireFence, android_ycbcr* outYcbcr) const {
332 if (!outYcbcr) {
333 return BAD_VALUE;
334 }
335
336 std::vector<ui::PlaneLayout> planeLayouts;
337 status_t error = getPlaneLayouts(bufferHandle, &planeLayouts);
338 if (error != NO_ERROR) {
339 return error;
340 }
341
342 void* data = nullptr;
343 error = lock(bufferHandle, usage, bounds, acquireFence, &data, nullptr, nullptr);
344 if (error != NO_ERROR) {
345 return error;
346 }
347
348 android_ycbcr ycbcr;
349
350 ycbcr.y = nullptr;
351 ycbcr.cb = nullptr;
352 ycbcr.cr = nullptr;
353 ycbcr.ystride = 0;
354 ycbcr.cstride = 0;
355 ycbcr.chroma_step = 0;
356
357 for (const auto& planeLayout : planeLayouts) {
358 for (const auto& planeLayoutComponent : planeLayout.components) {
359 if (!gralloc4::isStandardPlaneLayoutComponentType(planeLayoutComponent.type)) {
360 continue;
361 }
Marissa Wall22b2de12019-12-02 18:11:43 -0800362
Jason Macnak41209912022-02-16 14:44:44 -0800363 uint8_t* tmpData = static_cast<uint8_t*>(data) + planeLayout.offsetInBytes;
364
365 // Note that `offsetInBits` may not be a multiple of 8 for packed formats (e.g. P010)
366 // but we still want to point to the start of the first byte.
367 tmpData += (planeLayoutComponent.offsetInBits / 8);
368
Marissa Wall22b2de12019-12-02 18:11:43 -0800369 uint64_t sampleIncrementInBytes;
370
371 auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
372 switch (type) {
373 case PlaneLayoutComponentType::Y:
Jason Macnak41209912022-02-16 14:44:44 -0800374 if ((ycbcr.y != nullptr) || (planeLayout.sampleIncrementInBits % 8 != 0)) {
Marissa Wall22b2de12019-12-02 18:11:43 -0800375 unlock(bufferHandle);
376 return BAD_VALUE;
377 }
378 ycbcr.y = tmpData;
379 ycbcr.ystride = planeLayout.strideInBytes;
380 break;
381
382 case PlaneLayoutComponentType::CB:
383 case PlaneLayoutComponentType::CR:
384 if (planeLayout.sampleIncrementInBits % 8 != 0) {
385 unlock(bufferHandle);
386 return BAD_VALUE;
387 }
388
389 sampleIncrementInBytes = planeLayout.sampleIncrementInBits / 8;
Jason Macnak41209912022-02-16 14:44:44 -0800390 if ((sampleIncrementInBytes != 1) && (sampleIncrementInBytes != 2) &&
391 (sampleIncrementInBytes != 4)) {
Marissa Wall22b2de12019-12-02 18:11:43 -0800392 unlock(bufferHandle);
393 return BAD_VALUE;
394 }
395
396 if (ycbcr.cstride == 0 && ycbcr.chroma_step == 0) {
397 ycbcr.cstride = planeLayout.strideInBytes;
398 ycbcr.chroma_step = sampleIncrementInBytes;
399 } else {
400 if ((static_cast<int64_t>(ycbcr.cstride) != planeLayout.strideInBytes) ||
401 (ycbcr.chroma_step != sampleIncrementInBytes)) {
402 unlock(bufferHandle);
403 return BAD_VALUE;
404 }
405 }
406
407 if (type == PlaneLayoutComponentType::CB) {
408 if (ycbcr.cb != nullptr) {
409 unlock(bufferHandle);
410 return BAD_VALUE;
411 }
412 ycbcr.cb = tmpData;
413 } else {
414 if (ycbcr.cr != nullptr) {
415 unlock(bufferHandle);
416 return BAD_VALUE;
417 }
418 ycbcr.cr = tmpData;
419 }
420 break;
421 default:
422 break;
423 };
424 }
425 }
426
427 *outYcbcr = ycbcr;
Marissa Wall90df5852020-02-27 10:17:02 -0800428 return static_cast<status_t>(Error::NONE);
Marissa Wall87c8ba72019-06-20 14:20:52 -0700429}
430
431int Gralloc4Mapper::unlock(buffer_handle_t bufferHandle) const {
432 auto buffer = const_cast<native_handle_t*>(bufferHandle);
433
434 int releaseFence = -1;
435 Error error;
436 auto ret = mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
437 error = tmpError;
438 if (error != Error::NONE) {
439 return;
440 }
441
442 auto fenceHandle = tmpReleaseFence.getNativeHandle();
443 if (fenceHandle && fenceHandle->numFds == 1) {
444 int fd = dup(fenceHandle->data[0]);
445 if (fd >= 0) {
446 releaseFence = fd;
447 } else {
John Recke0711382022-01-26 12:10:59 -0500448 ALOGW("failed to dup unlock release fence");
Marissa Wall87c8ba72019-06-20 14:20:52 -0700449 sync_wait(fenceHandle->data[0], -1);
450 }
451 }
452 });
453
454 if (!ret.isOk()) {
455 error = kTransactionError;
456 }
457
458 if (error != Error::NONE) {
459 ALOGE("unlock(%p) failed with %d", buffer, error);
460 }
461
462 return releaseFence;
463}
464
Marissa Wall22b2de12019-12-02 18:11:43 -0800465status_t Gralloc4Mapper::isSupported(uint32_t width, uint32_t height, PixelFormat format,
Marissa Wall87c8ba72019-06-20 14:20:52 -0700466 uint32_t layerCount, uint64_t usage,
467 bool* outSupported) const {
468 IMapper::BufferDescriptorInfo descriptorInfo;
John Recke0711382022-01-26 12:10:59 -0500469 if (auto error = sBufferDescriptorInfo("isSupported", width, height, format, layerCount, usage,
470 &descriptorInfo) != OK) {
471 // Usage isn't known to the HAL or otherwise failed validation.
472 *outSupported = false;
473 return OK;
474 }
Marissa Wall87c8ba72019-06-20 14:20:52 -0700475
476 Error error;
477 auto ret = mMapper->isSupported(descriptorInfo,
478 [&](const auto& tmpError, const auto& tmpSupported) {
479 error = tmpError;
480 if (error != Error::NONE) {
481 return;
482 }
483 if (outSupported) {
484 *outSupported = tmpSupported;
485 }
486 });
487
488 if (!ret.isOk()) {
489 error = kTransactionError;
490 }
491
492 if (error != Error::NONE) {
493 ALOGE("isSupported(%u, %u, %d, %u, ...) failed with %d", width, height, format, layerCount,
494 error);
495 }
496
497 return static_cast<status_t>(error);
498}
499
Marissa Wall22b2de12019-12-02 18:11:43 -0800500template <class T>
501status_t Gralloc4Mapper::get(buffer_handle_t bufferHandle, const MetadataType& metadataType,
502 DecodeFunction<T> decodeFunction, T* outMetadata) const {
503 if (!outMetadata) {
504 return BAD_VALUE;
505 }
506
507 hidl_vec<uint8_t> vec;
508 Error error;
509 auto ret = mMapper->get(const_cast<native_handle_t*>(bufferHandle), metadataType,
510 [&](const auto& tmpError, const hidl_vec<uint8_t>& tmpVec) {
511 error = tmpError;
512 vec = tmpVec;
513 });
514
515 if (!ret.isOk()) {
516 error = kTransactionError;
517 }
518
519 if (error != Error::NONE) {
520 ALOGE("get(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
521 metadataType.value, error);
522 return static_cast<status_t>(error);
523 }
524
525 return decodeFunction(vec, outMetadata);
526}
527
Alec Mouri9c604e32022-03-18 22:47:44 +0000528template <class T>
529status_t Gralloc4Mapper::set(buffer_handle_t bufferHandle, const MetadataType& metadataType,
530 const T& metadata, EncodeFunction<T> encodeFunction) const {
531 hidl_vec<uint8_t> encodedMetadata;
532 if (const status_t status = encodeFunction(metadata, &encodedMetadata); status != OK) {
533 ALOGE("Encoding metadata(%s) failed with %d", metadataType.name.c_str(), status);
534 return status;
535 }
536 hidl_vec<uint8_t> vec;
537 auto ret =
538 mMapper->set(const_cast<native_handle_t*>(bufferHandle), metadataType, encodedMetadata);
539
540 const Error error = ret.withDefault(kTransactionError);
541 switch (error) {
542 case Error::BAD_DESCRIPTOR:
543 case Error::BAD_BUFFER:
544 case Error::BAD_VALUE:
545 case Error::NO_RESOURCES:
546 ALOGE("set(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
547 metadataType.value, error);
548 break;
549 // It is not an error to attempt to set metadata that a particular gralloc implementation
550 // happens to not support.
551 case Error::UNSUPPORTED:
552 case Error::NONE:
553 break;
554 }
555
556 return static_cast<status_t>(error);
557}
558
Marissa Wall22b2de12019-12-02 18:11:43 -0800559status_t Gralloc4Mapper::getBufferId(buffer_handle_t bufferHandle, uint64_t* outBufferId) const {
560 return get(bufferHandle, gralloc4::MetadataType_BufferId, gralloc4::decodeBufferId,
561 outBufferId);
562}
563
564status_t Gralloc4Mapper::getName(buffer_handle_t bufferHandle, std::string* outName) const {
565 return get(bufferHandle, gralloc4::MetadataType_Name, gralloc4::decodeName, outName);
566}
567
568status_t Gralloc4Mapper::getWidth(buffer_handle_t bufferHandle, uint64_t* outWidth) const {
569 return get(bufferHandle, gralloc4::MetadataType_Width, gralloc4::decodeWidth, outWidth);
570}
571
572status_t Gralloc4Mapper::getHeight(buffer_handle_t bufferHandle, uint64_t* outHeight) const {
573 return get(bufferHandle, gralloc4::MetadataType_Height, gralloc4::decodeHeight, outHeight);
574}
575
576status_t Gralloc4Mapper::getLayerCount(buffer_handle_t bufferHandle,
577 uint64_t* outLayerCount) const {
578 return get(bufferHandle, gralloc4::MetadataType_LayerCount, gralloc4::decodeLayerCount,
579 outLayerCount);
580}
581
582status_t Gralloc4Mapper::getPixelFormatRequested(buffer_handle_t bufferHandle,
583 ui::PixelFormat* outPixelFormatRequested) const {
584 return get(bufferHandle, gralloc4::MetadataType_PixelFormatRequested,
585 gralloc4::decodePixelFormatRequested, outPixelFormatRequested);
586}
587
588status_t Gralloc4Mapper::getPixelFormatFourCC(buffer_handle_t bufferHandle,
589 uint32_t* outPixelFormatFourCC) const {
590 return get(bufferHandle, gralloc4::MetadataType_PixelFormatFourCC,
591 gralloc4::decodePixelFormatFourCC, outPixelFormatFourCC);
592}
593
594status_t Gralloc4Mapper::getPixelFormatModifier(buffer_handle_t bufferHandle,
595 uint64_t* outPixelFormatModifier) const {
596 return get(bufferHandle, gralloc4::MetadataType_PixelFormatModifier,
597 gralloc4::decodePixelFormatModifier, outPixelFormatModifier);
598}
599
600status_t Gralloc4Mapper::getUsage(buffer_handle_t bufferHandle, uint64_t* outUsage) const {
601 return get(bufferHandle, gralloc4::MetadataType_Usage, gralloc4::decodeUsage, outUsage);
602}
603
604status_t Gralloc4Mapper::getAllocationSize(buffer_handle_t bufferHandle,
605 uint64_t* outAllocationSize) const {
606 return get(bufferHandle, gralloc4::MetadataType_AllocationSize, gralloc4::decodeAllocationSize,
607 outAllocationSize);
608}
609
610status_t Gralloc4Mapper::getProtectedContent(buffer_handle_t bufferHandle,
611 uint64_t* outProtectedContent) const {
612 return get(bufferHandle, gralloc4::MetadataType_ProtectedContent,
613 gralloc4::decodeProtectedContent, outProtectedContent);
614}
615
616status_t Gralloc4Mapper::getCompression(buffer_handle_t bufferHandle,
617 ExtendableType* outCompression) const {
618 return get(bufferHandle, gralloc4::MetadataType_Compression, gralloc4::decodeCompression,
619 outCompression);
620}
621
622status_t Gralloc4Mapper::getCompression(buffer_handle_t bufferHandle,
623 ui::Compression* outCompression) const {
624 if (!outCompression) {
625 return BAD_VALUE;
626 }
627 ExtendableType compression;
628 status_t error = getCompression(bufferHandle, &compression);
629 if (error) {
630 return error;
631 }
632 if (!gralloc4::isStandardCompression(compression)) {
633 return BAD_TYPE;
634 }
635 *outCompression = gralloc4::getStandardCompressionValue(compression);
636 return NO_ERROR;
637}
638
639status_t Gralloc4Mapper::getInterlaced(buffer_handle_t bufferHandle,
640 ExtendableType* outInterlaced) const {
641 return get(bufferHandle, gralloc4::MetadataType_Interlaced, gralloc4::decodeInterlaced,
642 outInterlaced);
643}
644
645status_t Gralloc4Mapper::getInterlaced(buffer_handle_t bufferHandle,
646 ui::Interlaced* outInterlaced) const {
647 if (!outInterlaced) {
648 return BAD_VALUE;
649 }
650 ExtendableType interlaced;
651 status_t error = getInterlaced(bufferHandle, &interlaced);
652 if (error) {
653 return error;
654 }
655 if (!gralloc4::isStandardInterlaced(interlaced)) {
656 return BAD_TYPE;
657 }
658 *outInterlaced = gralloc4::getStandardInterlacedValue(interlaced);
659 return NO_ERROR;
660}
661
662status_t Gralloc4Mapper::getChromaSiting(buffer_handle_t bufferHandle,
663 ExtendableType* outChromaSiting) const {
664 return get(bufferHandle, gralloc4::MetadataType_ChromaSiting, gralloc4::decodeChromaSiting,
665 outChromaSiting);
666}
667
668status_t Gralloc4Mapper::getChromaSiting(buffer_handle_t bufferHandle,
669 ui::ChromaSiting* outChromaSiting) const {
670 if (!outChromaSiting) {
671 return BAD_VALUE;
672 }
673 ExtendableType chromaSiting;
674 status_t error = getChromaSiting(bufferHandle, &chromaSiting);
675 if (error) {
676 return error;
677 }
678 if (!gralloc4::isStandardChromaSiting(chromaSiting)) {
679 return BAD_TYPE;
680 }
681 *outChromaSiting = gralloc4::getStandardChromaSitingValue(chromaSiting);
682 return NO_ERROR;
683}
684
685status_t Gralloc4Mapper::getPlaneLayouts(buffer_handle_t bufferHandle,
686 std::vector<ui::PlaneLayout>* outPlaneLayouts) const {
687 return get(bufferHandle, gralloc4::MetadataType_PlaneLayouts, gralloc4::decodePlaneLayouts,
688 outPlaneLayouts);
689}
690
691status_t Gralloc4Mapper::getDataspace(buffer_handle_t bufferHandle,
692 ui::Dataspace* outDataspace) const {
693 if (!outDataspace) {
694 return BAD_VALUE;
695 }
Yichi Chenba40db52021-04-30 00:18:32 +0800696 AidlDataspace dataspace;
Marissa Wall22b2de12019-12-02 18:11:43 -0800697 status_t error = get(bufferHandle, gralloc4::MetadataType_Dataspace, gralloc4::decodeDataspace,
698 &dataspace);
699 if (error) {
700 return error;
701 }
702
703 // Gralloc4 uses stable AIDL dataspace but the rest of the system still uses HIDL dataspace
704 *outDataspace = static_cast<ui::Dataspace>(dataspace);
705 return NO_ERROR;
706}
707
Alec Mouri9c604e32022-03-18 22:47:44 +0000708status_t Gralloc4Mapper::setDataspace(buffer_handle_t bufferHandle, ui::Dataspace dataspace) const {
709 return set(bufferHandle, gralloc4::MetadataType_Dataspace,
710 static_cast<aidl::android::hardware::graphics::common::Dataspace>(dataspace),
711 gralloc4::encodeDataspace);
712}
713
Marissa Wall22b2de12019-12-02 18:11:43 -0800714status_t Gralloc4Mapper::getBlendMode(buffer_handle_t bufferHandle,
715 ui::BlendMode* outBlendMode) const {
716 return get(bufferHandle, gralloc4::MetadataType_BlendMode, gralloc4::decodeBlendMode,
717 outBlendMode);
718}
719
Marissa Wallef785e12019-12-12 14:26:59 -0800720status_t Gralloc4Mapper::getSmpte2086(buffer_handle_t bufferHandle,
721 std::optional<ui::Smpte2086>* outSmpte2086) const {
722 return get(bufferHandle, gralloc4::MetadataType_Smpte2086, gralloc4::decodeSmpte2086,
723 outSmpte2086);
724}
725
Alec Mouri9c604e32022-03-18 22:47:44 +0000726status_t Gralloc4Mapper::setSmpte2086(buffer_handle_t bufferHandle,
727 std::optional<ui::Smpte2086> smpte2086) const {
728 return set(bufferHandle, gralloc4::MetadataType_Smpte2086, smpte2086,
729 gralloc4::encodeSmpte2086);
730}
731
Marissa Wallef785e12019-12-12 14:26:59 -0800732status_t Gralloc4Mapper::getCta861_3(buffer_handle_t bufferHandle,
733 std::optional<ui::Cta861_3>* outCta861_3) const {
734 return get(bufferHandle, gralloc4::MetadataType_Cta861_3, gralloc4::decodeCta861_3,
735 outCta861_3);
736}
737
Alec Mouri9c604e32022-03-18 22:47:44 +0000738status_t Gralloc4Mapper::setCta861_3(buffer_handle_t bufferHandle,
739 std::optional<ui::Cta861_3> cta861_3) const {
740 return set(bufferHandle, gralloc4::MetadataType_Cta861_3, cta861_3, gralloc4::encodeCta861_3);
741}
742
Marissa Wallef785e12019-12-12 14:26:59 -0800743status_t Gralloc4Mapper::getSmpte2094_40(
744 buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>>* outSmpte2094_40) const {
745 return get(bufferHandle, gralloc4::MetadataType_Smpte2094_40, gralloc4::decodeSmpte2094_40,
746 outSmpte2094_40);
747}
748
Alec Mouri9c604e32022-03-18 22:47:44 +0000749status_t Gralloc4Mapper::setSmpte2094_40(buffer_handle_t bufferHandle,
750 std::optional<std::vector<uint8_t>> smpte2094_40) const {
751 return set(bufferHandle, gralloc4::MetadataType_Smpte2094_40, smpte2094_40,
752 gralloc4::encodeSmpte2094_40);
753}
754
Alec Mouri332765e2021-10-06 16:38:12 -0700755status_t Gralloc4Mapper::getSmpte2094_10(
756 buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>>* outSmpte2094_10) const {
757 return get(bufferHandle, gralloc4::MetadataType_Smpte2094_10, gralloc4::decodeSmpte2094_10,
758 outSmpte2094_10);
759}
760
Alec Mouri9c604e32022-03-18 22:47:44 +0000761status_t Gralloc4Mapper::setSmpte2094_10(buffer_handle_t bufferHandle,
762 std::optional<std::vector<uint8_t>> smpte2094_10) const {
763 return set(bufferHandle, gralloc4::MetadataType_Smpte2094_10, smpte2094_10,
764 gralloc4::encodeSmpte2094_10);
765}
766
Marissa Wall22b2de12019-12-02 18:11:43 -0800767template <class T>
768status_t Gralloc4Mapper::getDefault(uint32_t width, uint32_t height, PixelFormat format,
769 uint32_t layerCount, uint64_t usage,
770 const MetadataType& metadataType,
771 DecodeFunction<T> decodeFunction, T* outMetadata) const {
772 if (!outMetadata) {
773 return BAD_VALUE;
774 }
775
776 IMapper::BufferDescriptorInfo descriptorInfo;
John Recke0711382022-01-26 12:10:59 -0500777 if (auto error = sBufferDescriptorInfo("getDefault", width, height, format, layerCount, usage,
778 &descriptorInfo) != OK) {
779 return error;
780 }
Marissa Wall22b2de12019-12-02 18:11:43 -0800781
782 hidl_vec<uint8_t> vec;
783 Error error;
784 auto ret = mMapper->getFromBufferDescriptorInfo(descriptorInfo, metadataType,
785 [&](const auto& tmpError,
786 const hidl_vec<uint8_t>& tmpVec) {
787 error = tmpError;
788 vec = tmpVec;
789 });
790
791 if (!ret.isOk()) {
792 error = kTransactionError;
793 }
794
795 if (error != Error::NONE) {
796 ALOGE("getDefault(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
797 metadataType.value, error);
798 return static_cast<status_t>(error);
799 }
800
801 return decodeFunction(vec, outMetadata);
802}
803
804status_t Gralloc4Mapper::getDefaultPixelFormatFourCC(uint32_t width, uint32_t height,
805 PixelFormat format, uint32_t layerCount,
806 uint64_t usage,
807 uint32_t* outPixelFormatFourCC) const {
808 return getDefault(width, height, format, layerCount, usage,
809 gralloc4::MetadataType_PixelFormatFourCC, gralloc4::decodePixelFormatFourCC,
810 outPixelFormatFourCC);
811}
812
813status_t Gralloc4Mapper::getDefaultPixelFormatModifier(uint32_t width, uint32_t height,
814 PixelFormat format, uint32_t layerCount,
815 uint64_t usage,
816 uint64_t* outPixelFormatModifier) const {
817 return getDefault(width, height, format, layerCount, usage,
818 gralloc4::MetadataType_PixelFormatModifier,
819 gralloc4::decodePixelFormatModifier, outPixelFormatModifier);
820}
821
822status_t Gralloc4Mapper::getDefaultAllocationSize(uint32_t width, uint32_t height,
823 PixelFormat format, uint32_t layerCount,
824 uint64_t usage,
825 uint64_t* outAllocationSize) const {
826 return getDefault(width, height, format, layerCount, usage,
827 gralloc4::MetadataType_AllocationSize, gralloc4::decodeAllocationSize,
828 outAllocationSize);
829}
830
831status_t Gralloc4Mapper::getDefaultProtectedContent(uint32_t width, uint32_t height,
832 PixelFormat format, uint32_t layerCount,
833 uint64_t usage,
834 uint64_t* outProtectedContent) const {
835 return getDefault(width, height, format, layerCount, usage,
836 gralloc4::MetadataType_ProtectedContent, gralloc4::decodeProtectedContent,
837 outProtectedContent);
838}
839
840status_t Gralloc4Mapper::getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
841 uint32_t layerCount, uint64_t usage,
842 ExtendableType* outCompression) const {
843 return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_Compression,
844 gralloc4::decodeCompression, outCompression);
845}
846
847status_t Gralloc4Mapper::getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
848 uint32_t layerCount, uint64_t usage,
849 ui::Compression* outCompression) const {
850 if (!outCompression) {
851 return BAD_VALUE;
852 }
853 ExtendableType compression;
854 status_t error = getDefaultCompression(width, height, format, layerCount, usage, &compression);
855 if (error) {
856 return error;
857 }
858 if (!gralloc4::isStandardCompression(compression)) {
859 return BAD_TYPE;
860 }
861 *outCompression = gralloc4::getStandardCompressionValue(compression);
862 return NO_ERROR;
863}
864
865status_t Gralloc4Mapper::getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
866 uint32_t layerCount, uint64_t usage,
867 ExtendableType* outInterlaced) const {
868 return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_Interlaced,
869 gralloc4::decodeInterlaced, outInterlaced);
870}
871
872status_t Gralloc4Mapper::getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
873 uint32_t layerCount, uint64_t usage,
874 ui::Interlaced* outInterlaced) const {
875 if (!outInterlaced) {
876 return BAD_VALUE;
877 }
878 ExtendableType interlaced;
879 status_t error = getDefaultInterlaced(width, height, format, layerCount, usage, &interlaced);
880 if (error) {
881 return error;
882 }
883 if (!gralloc4::isStandardInterlaced(interlaced)) {
884 return BAD_TYPE;
885 }
886 *outInterlaced = gralloc4::getStandardInterlacedValue(interlaced);
887 return NO_ERROR;
888}
889
890status_t Gralloc4Mapper::getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
891 uint32_t layerCount, uint64_t usage,
892 ExtendableType* outChromaSiting) const {
893 return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_ChromaSiting,
894 gralloc4::decodeChromaSiting, outChromaSiting);
895}
896
897status_t Gralloc4Mapper::getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
898 uint32_t layerCount, uint64_t usage,
899 ui::ChromaSiting* outChromaSiting) const {
900 if (!outChromaSiting) {
901 return BAD_VALUE;
902 }
903 ExtendableType chromaSiting;
904 status_t error =
905 getDefaultChromaSiting(width, height, format, layerCount, usage, &chromaSiting);
906 if (error) {
907 return error;
908 }
909 if (!gralloc4::isStandardChromaSiting(chromaSiting)) {
910 return BAD_TYPE;
911 }
912 *outChromaSiting = gralloc4::getStandardChromaSitingValue(chromaSiting);
913 return NO_ERROR;
914}
915
916status_t Gralloc4Mapper::getDefaultPlaneLayouts(
917 uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage,
918 std::vector<ui::PlaneLayout>* outPlaneLayouts) const {
919 return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_PlaneLayouts,
920 gralloc4::decodePlaneLayouts, outPlaneLayouts);
921}
922
923std::vector<MetadataTypeDescription> Gralloc4Mapper::listSupportedMetadataTypes() const {
924 hidl_vec<MetadataTypeDescription> descriptions;
925 Error error;
926 auto ret = mMapper->listSupportedMetadataTypes(
927 [&](const auto& tmpError, const auto& tmpDescriptions) {
928 error = tmpError;
929 descriptions = tmpDescriptions;
930 });
931
932 if (!ret.isOk()) {
933 error = kTransactionError;
934 }
935
936 if (error != Error::NONE) {
937 ALOGE("listSupportedMetadataType() failed with %d", error);
938 return {};
939 }
940
941 return static_cast<std::vector<MetadataTypeDescription>>(descriptions);
942}
943
944template <class T>
945status_t Gralloc4Mapper::metadataDumpHelper(const BufferDump& bufferDump,
946 StandardMetadataType metadataType,
947 DecodeFunction<T> decodeFunction, T* outT) const {
948 const auto& metadataDump = bufferDump.metadataDump;
949
950 auto itr =
951 std::find_if(metadataDump.begin(), metadataDump.end(),
952 [&](const MetadataDump& tmpMetadataDump) {
953 if (!gralloc4::isStandardMetadataType(tmpMetadataDump.metadataType)) {
954 return false;
955 }
956 return metadataType ==
957 gralloc4::getStandardMetadataTypeValue(
958 tmpMetadataDump.metadataType);
959 });
960 if (itr == metadataDump.end()) {
961 return BAD_VALUE;
962 }
963
964 return decodeFunction(itr->metadata, outT);
965}
966
967status_t Gralloc4Mapper::bufferDumpHelper(const BufferDump& bufferDump, std::ostringstream* outDump,
968 uint64_t* outAllocationSize, bool less) const {
969 uint64_t bufferId;
970 std::string name;
971 uint64_t width;
972 uint64_t height;
973 uint64_t layerCount;
974 ui::PixelFormat pixelFormatRequested;
975 uint32_t pixelFormatFourCC;
976 uint64_t pixelFormatModifier;
977 uint64_t usage;
Yichi Chenba40db52021-04-30 00:18:32 +0800978 AidlDataspace dataspace;
Marissa Wall22b2de12019-12-02 18:11:43 -0800979 uint64_t allocationSize;
980 uint64_t protectedContent;
981 ExtendableType compression;
982 ExtendableType interlaced;
983 ExtendableType chromaSiting;
984 std::vector<ui::PlaneLayout> planeLayouts;
985
986 status_t error = metadataDumpHelper(bufferDump, StandardMetadataType::BUFFER_ID,
987 gralloc4::decodeBufferId, &bufferId);
988 if (error != NO_ERROR) {
989 return error;
990 }
991 error = metadataDumpHelper(bufferDump, StandardMetadataType::NAME, gralloc4::decodeName, &name);
992 if (error != NO_ERROR) {
993 return error;
994 }
995 error = metadataDumpHelper(bufferDump, StandardMetadataType::WIDTH, gralloc4::decodeWidth,
996 &width);
997 if (error != NO_ERROR) {
998 return error;
999 }
1000 error = metadataDumpHelper(bufferDump, StandardMetadataType::HEIGHT, gralloc4::decodeHeight,
1001 &height);
1002 if (error != NO_ERROR) {
1003 return error;
1004 }
1005 error = metadataDumpHelper(bufferDump, StandardMetadataType::LAYER_COUNT,
1006 gralloc4::decodeLayerCount, &layerCount);
1007 if (error != NO_ERROR) {
1008 return error;
1009 }
1010 error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_REQUESTED,
1011 gralloc4::decodePixelFormatRequested, &pixelFormatRequested);
1012 if (error != NO_ERROR) {
1013 return error;
1014 }
1015 error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_FOURCC,
1016 gralloc4::decodePixelFormatFourCC, &pixelFormatFourCC);
1017 if (error != NO_ERROR) {
1018 return error;
1019 }
1020 error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_MODIFIER,
1021 gralloc4::decodePixelFormatModifier, &pixelFormatModifier);
1022 if (error != NO_ERROR) {
1023 return error;
1024 }
1025 error = metadataDumpHelper(bufferDump, StandardMetadataType::USAGE, gralloc4::decodeUsage,
1026 &usage);
1027 if (error != NO_ERROR) {
1028 return error;
1029 }
Yichi Chenba40db52021-04-30 00:18:32 +08001030 error = metadataDumpHelper(bufferDump, StandardMetadataType::DATASPACE,
1031 gralloc4::decodeDataspace, &dataspace);
1032 if (error != NO_ERROR) {
1033 return error;
1034 }
Marissa Wall22b2de12019-12-02 18:11:43 -08001035 error = metadataDumpHelper(bufferDump, StandardMetadataType::ALLOCATION_SIZE,
1036 gralloc4::decodeAllocationSize, &allocationSize);
1037 if (error != NO_ERROR) {
1038 return error;
1039 }
1040 error = metadataDumpHelper(bufferDump, StandardMetadataType::PROTECTED_CONTENT,
1041 gralloc4::decodeProtectedContent, &protectedContent);
1042 if (error != NO_ERROR) {
1043 return error;
1044 }
1045 error = metadataDumpHelper(bufferDump, StandardMetadataType::COMPRESSION,
1046 gralloc4::decodeCompression, &compression);
1047 if (error != NO_ERROR) {
1048 return error;
1049 }
1050 error = metadataDumpHelper(bufferDump, StandardMetadataType::INTERLACED,
1051 gralloc4::decodeInterlaced, &interlaced);
1052 if (error != NO_ERROR) {
1053 return error;
1054 }
1055 error = metadataDumpHelper(bufferDump, StandardMetadataType::CHROMA_SITING,
1056 gralloc4::decodeChromaSiting, &chromaSiting);
1057 if (error != NO_ERROR) {
1058 return error;
1059 }
1060 error = metadataDumpHelper(bufferDump, StandardMetadataType::PLANE_LAYOUTS,
1061 gralloc4::decodePlaneLayouts, &planeLayouts);
1062 if (error != NO_ERROR) {
1063 return error;
1064 }
1065
1066 if (outAllocationSize) {
1067 *outAllocationSize = allocationSize;
1068 }
1069 double allocationSizeKiB = static_cast<double>(allocationSize) / 1024;
1070
Alec Mouri04511ef2022-01-06 12:57:12 -08001071 *outDump << "+ name:" << name << ", id:" << bufferId << ", size:" << std::fixed
1072 << allocationSizeKiB << "KiB, w/h:" << width << "x" << height << ", usage: 0x"
1073 << std::hex << usage << std::dec
1074 << ", req fmt:" << static_cast<int32_t>(pixelFormatRequested)
Marissa Wall22b2de12019-12-02 18:11:43 -08001075 << ", fourcc/mod:" << pixelFormatFourCC << "/" << pixelFormatModifier
Yichi Chen6de5b582021-09-13 20:00:52 +08001076 << ", dataspace: 0x" << std::hex << static_cast<uint32_t>(dataspace) << std::dec
Marissa Wall22b2de12019-12-02 18:11:43 -08001077 << ", compressed: ";
1078
1079 if (less) {
1080 bool isCompressed = !gralloc4::isStandardCompression(compression) ||
1081 (gralloc4::getStandardCompressionValue(compression) != ui::Compression::NONE);
1082 *outDump << std::boolalpha << isCompressed << "\n";
1083 } else {
1084 *outDump << gralloc4::getCompressionName(compression) << "\n";
1085 }
1086
1087 bool firstPlane = true;
1088 for (const auto& planeLayout : planeLayouts) {
1089 if (firstPlane) {
1090 firstPlane = false;
1091 *outDump << "\tplanes: ";
1092 } else {
1093 *outDump << "\t ";
1094 }
1095
1096 for (size_t i = 0; i < planeLayout.components.size(); i++) {
1097 const auto& planeLayoutComponent = planeLayout.components[i];
1098 *outDump << gralloc4::getPlaneLayoutComponentTypeName(planeLayoutComponent.type);
1099 if (i < planeLayout.components.size() - 1) {
1100 *outDump << "/";
1101 } else {
1102 *outDump << ":\t";
1103 }
1104 }
1105 *outDump << " w/h:" << planeLayout.widthInSamples << "x" << planeLayout.heightInSamples
1106 << ", stride:" << planeLayout.strideInBytes
1107 << " bytes, size:" << planeLayout.totalSizeInBytes;
1108 if (!less) {
1109 *outDump << ", inc:" << planeLayout.sampleIncrementInBits
1110 << " bits, subsampling w/h:" << planeLayout.horizontalSubsampling << "x"
1111 << planeLayout.verticalSubsampling;
1112 }
1113 *outDump << "\n";
1114 }
1115
1116 if (!less) {
1117 *outDump << "\tlayer cnt: " << layerCount << ", protected content: " << protectedContent
1118 << ", interlaced: " << gralloc4::getInterlacedName(interlaced)
1119 << ", chroma siting:" << gralloc4::getChromaSitingName(chromaSiting) << "\n";
1120 }
1121
1122 return NO_ERROR;
1123}
1124
1125std::string Gralloc4Mapper::dumpBuffer(buffer_handle_t bufferHandle, bool less) const {
1126 auto buffer = const_cast<native_handle_t*>(bufferHandle);
1127
1128 BufferDump bufferDump;
1129 Error error;
1130 auto ret = mMapper->dumpBuffer(buffer, [&](const auto& tmpError, const auto& tmpBufferDump) {
1131 error = tmpError;
1132 bufferDump = tmpBufferDump;
1133 });
1134
1135 if (!ret.isOk()) {
1136 error = kTransactionError;
1137 }
1138
1139 if (error != Error::NONE) {
1140 ALOGE("dumpBuffer() failed with %d", error);
1141 return "";
1142 }
1143
1144 std::ostringstream stream;
1145 stream.precision(2);
1146
1147 status_t err = bufferDumpHelper(bufferDump, &stream, nullptr, less);
1148 if (err != NO_ERROR) {
1149 ALOGE("bufferDumpHelper() failed with %d", err);
1150 return "";
1151 }
1152
1153 return stream.str();
1154}
1155
1156std::string Gralloc4Mapper::dumpBuffers(bool less) const {
1157 hidl_vec<BufferDump> bufferDumps;
1158 Error error;
1159 auto ret = mMapper->dumpBuffers([&](const auto& tmpError, const auto& tmpBufferDump) {
1160 error = tmpError;
1161 bufferDumps = tmpBufferDump;
1162 });
1163
1164 if (!ret.isOk()) {
1165 error = kTransactionError;
1166 }
1167
1168 if (error != Error::NONE) {
1169 ALOGE("dumpBuffer() failed with %d", error);
1170 return "";
1171 }
1172
1173 uint64_t totalAllocationSize = 0;
1174 std::ostringstream stream;
1175 stream.precision(2);
1176
1177 stream << "Imported gralloc buffers:\n";
1178
1179 for (const auto& bufferDump : bufferDumps) {
1180 uint64_t allocationSize = 0;
1181 status_t err = bufferDumpHelper(bufferDump, &stream, &allocationSize, less);
1182 if (err != NO_ERROR) {
1183 ALOGE("bufferDumpHelper() failed with %d", err);
1184 return "";
1185 }
1186 totalAllocationSize += allocationSize;
1187 }
1188
1189 double totalAllocationSizeKiB = static_cast<double>(totalAllocationSize) / 1024;
1190 stream << "Total imported by gralloc: " << totalAllocationSizeKiB << "KiB\n";
1191 return stream.str();
1192}
1193
Marissa Wall87c8ba72019-06-20 14:20:52 -07001194Gralloc4Allocator::Gralloc4Allocator(const Gralloc4Mapper& mapper) : mMapper(mapper) {
1195 mAllocator = IAllocator::getService();
John Reck614326b2022-01-11 15:49:54 -05001196 if (__builtin_available(android 31, *)) {
1197 if (hasIAllocatorAidl()) {
1198 mAidlAllocator = AidlIAllocator::fromBinder(ndk::SpAIBinder(
1199 AServiceManager_waitForService(kAidlAllocatorServiceName.c_str())));
1200 ALOGE_IF(!mAidlAllocator, "AIDL IAllocator declared but failed to get service");
1201 }
1202 }
Devin Mooree401e882022-04-11 22:41:58 +00001203 if (mAllocator == nullptr && mAidlAllocator == nullptr) {
1204 ALOGW("allocator 4.x is not supported");
1205 return;
1206 }
Marissa Wall87c8ba72019-06-20 14:20:52 -07001207}
1208
1209bool Gralloc4Allocator::isLoaded() const {
Devin Mooree401e882022-04-11 22:41:58 +00001210 return mAllocator != nullptr || mAidlAllocator != nullptr;
Marissa Wall87c8ba72019-06-20 14:20:52 -07001211}
1212
Marissa Wall22b2de12019-12-02 18:11:43 -08001213std::string Gralloc4Allocator::dumpDebugInfo(bool less) const {
1214 return mMapper.dumpBuffers(less);
Marissa Wall87c8ba72019-06-20 14:20:52 -07001215}
1216
Marissa Wall22b2de12019-12-02 18:11:43 -08001217status_t Gralloc4Allocator::allocate(std::string requestorName, uint32_t width, uint32_t height,
1218 android::PixelFormat format, uint32_t layerCount,
1219 uint64_t usage, uint32_t bufferCount, uint32_t* outStride,
1220 buffer_handle_t* outBufferHandles, bool importBuffers) const {
Marissa Wall87c8ba72019-06-20 14:20:52 -07001221 IMapper::BufferDescriptorInfo descriptorInfo;
John Recke0711382022-01-26 12:10:59 -05001222 if (auto error = sBufferDescriptorInfo(requestorName, width, height, format, layerCount, usage,
1223 &descriptorInfo) != OK) {
1224 return error;
1225 }
Marissa Wall87c8ba72019-06-20 14:20:52 -07001226
1227 BufferDescriptor descriptor;
1228 status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),
1229 static_cast<void*>(&descriptor));
1230 if (error != NO_ERROR) {
1231 return error;
1232 }
1233
John Reck614326b2022-01-11 15:49:54 -05001234 if (mAidlAllocator) {
1235 AllocationResult result;
1236 auto status = mAidlAllocator->allocate(descriptor, bufferCount, &result);
1237 if (!status.isOk()) {
1238 error = status.getExceptionCode();
1239 if (error == EX_SERVICE_SPECIFIC) {
1240 error = status.getServiceSpecificError();
1241 }
1242 if (error == OK) {
1243 error = UNKNOWN_ERROR;
1244 }
1245 } else {
1246 if (importBuffers) {
1247 for (uint32_t i = 0; i < bufferCount; i++) {
1248 error = mMapper.importBuffer(makeFromAidl(result.buffers[i]),
1249 &outBufferHandles[i]);
1250 if (error != NO_ERROR) {
1251 for (uint32_t j = 0; j < i; j++) {
1252 mMapper.freeBuffer(outBufferHandles[j]);
1253 outBufferHandles[j] = nullptr;
1254 }
1255 break;
1256 }
1257 }
1258 } else {
1259 for (uint32_t i = 0; i < bufferCount; i++) {
1260 outBufferHandles[i] = dupFromAidl(result.buffers[i]);
1261 if (!outBufferHandles[i]) {
1262 for (uint32_t j = 0; j < i; j++) {
1263 auto buffer = const_cast<native_handle_t*>(outBufferHandles[j]);
1264 native_handle_close(buffer);
1265 native_handle_delete(buffer);
1266 outBufferHandles[j] = nullptr;
1267 }
1268 }
1269 }
1270 }
1271 }
1272 *outStride = result.stride;
1273 // Release all the resources held by AllocationResult (specifically any remaining FDs)
1274 result = {};
1275 // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
1276 hardware::IPCThreadState::self()->flushCommands();
1277 return error;
1278 }
1279
Marissa Wall87c8ba72019-06-20 14:20:52 -07001280 auto ret = mAllocator->allocate(descriptor, bufferCount,
1281 [&](const auto& tmpError, const auto& tmpStride,
1282 const auto& tmpBuffers) {
1283 error = static_cast<status_t>(tmpError);
1284 if (tmpError != Error::NONE) {
1285 return;
1286 }
1287
Marissa Wallbfcf81f2019-11-27 10:36:29 -08001288 if (importBuffers) {
1289 for (uint32_t i = 0; i < bufferCount; i++) {
1290 error = mMapper.importBuffer(tmpBuffers[i],
1291 &outBufferHandles[i]);
1292 if (error != NO_ERROR) {
1293 for (uint32_t j = 0; j < i; j++) {
1294 mMapper.freeBuffer(outBufferHandles[j]);
1295 outBufferHandles[j] = nullptr;
1296 }
1297 return;
Marissa Wall87c8ba72019-06-20 14:20:52 -07001298 }
Marissa Wallbfcf81f2019-11-27 10:36:29 -08001299 }
1300 } else {
1301 for (uint32_t i = 0; i < bufferCount; i++) {
1302 outBufferHandles[i] = native_handle_clone(
1303 tmpBuffers[i].getNativeHandle());
1304 if (!outBufferHandles[i]) {
1305 for (uint32_t j = 0; j < i; j++) {
1306 auto buffer = const_cast<native_handle_t*>(
1307 outBufferHandles[j]);
1308 native_handle_close(buffer);
1309 native_handle_delete(buffer);
1310 outBufferHandles[j] = nullptr;
1311 }
1312 }
Marissa Wall87c8ba72019-06-20 14:20:52 -07001313 }
1314 }
1315 *outStride = tmpStride;
1316 });
1317
1318 // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
1319 hardware::IPCThreadState::self()->flushCommands();
1320
1321 return (ret.isOk()) ? error : static_cast<status_t>(kTransactionError);
1322}
1323
1324} // namespace android