blob: 9922d6afafe3461a2ee5bf8384f439128825de1b [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>
Marissa Wall87c8ba72019-06-20 14:20:52 -070025#include <hidl/ServiceManagement.h>
26#include <hwbinder/IPCThreadState.h>
27#include <ui/Gralloc4.h>
28
29#include <inttypes.h>
30#include <log/log.h>
31#pragma clang diagnostic push
32#pragma clang diagnostic ignored "-Wzero-length-array"
33#include <sync/sync.h>
34#pragma clang diagnostic pop
35
John Reck614326b2022-01-11 15:49:54 -050036using aidl::android::hardware::graphics::allocator::AllocationError;
37using aidl::android::hardware::graphics::allocator::AllocationResult;
Marissa Wall22b2de12019-12-02 18:11:43 -080038using aidl::android::hardware::graphics::common::ExtendableType;
39using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
40using aidl::android::hardware::graphics::common::StandardMetadataType;
41using android::hardware::hidl_vec;
Marissa Wall87c8ba72019-06-20 14:20:52 -070042using android::hardware::graphics::allocator::V4_0::IAllocator;
43using android::hardware::graphics::common::V1_2::BufferUsage;
Chris Forbes6c09ee72022-01-26 18:48:55 +130044using android::hardware::graphics::common::V1_2::PixelFormat;
Marissa Wall87c8ba72019-06-20 14:20:52 -070045using android::hardware::graphics::mapper::V4_0::BufferDescriptor;
46using android::hardware::graphics::mapper::V4_0::Error;
47using android::hardware::graphics::mapper::V4_0::IMapper;
John Reck614326b2022-01-11 15:49:54 -050048using AidlIAllocator = ::aidl::android::hardware::graphics::allocator::IAllocator;
49using AidlBufferUsage = ::aidl::android::hardware::graphics::common::BufferUsage;
Yichi Chenba40db52021-04-30 00:18:32 +080050using AidlDataspace = ::aidl::android::hardware::graphics::common::Dataspace;
John Reck614326b2022-01-11 15:49:54 -050051using AidlNativeHandle = ::aidl::android::hardware::common::NativeHandle;
Marissa Wall22b2de12019-12-02 18:11:43 -080052using BufferDump = android::hardware::graphics::mapper::V4_0::IMapper::BufferDump;
53using MetadataDump = android::hardware::graphics::mapper::V4_0::IMapper::MetadataDump;
54using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
55using MetadataTypeDescription =
56 android::hardware::graphics::mapper::V4_0::IMapper::MetadataTypeDescription;
Marissa Wall87c8ba72019-06-20 14:20:52 -070057
58namespace android {
59
60namespace {
61
62static constexpr Error kTransactionError = Error::NO_RESOURCES;
John Reck614326b2022-01-11 15:49:54 -050063static const auto kAidlAllocatorServiceName = AidlIAllocator::descriptor + std::string("/default");
Marissa Wall87c8ba72019-06-20 14:20:52 -070064
65uint64_t getValidUsageBits() {
66 static const uint64_t validUsageBits = []() -> uint64_t {
67 uint64_t bits = 0;
68 for (const auto bit :
69 hardware::hidl_enum_range<hardware::graphics::common::V1_2::BufferUsage>()) {
70 bits = bits | bit;
71 }
72 return bits;
73 }();
74 return validUsageBits;
75}
76
John Reck614326b2022-01-11 15:49:54 -050077uint64_t getValidUsageBits41() {
78 static const uint64_t validUsageBits = []() -> uint64_t {
79 uint64_t bits = 0;
80 for (const auto bit : ndk::enum_range<AidlBufferUsage>{}) {
81 bits |= static_cast<int64_t>(bit);
82 }
83 return bits;
84 }();
85 return validUsageBits;
86}
87
Marissa Wall87c8ba72019-06-20 14:20:52 -070088static inline IMapper::Rect sGralloc4Rect(const Rect& rect) {
89 IMapper::Rect outRect{};
90 outRect.left = rect.left;
91 outRect.top = rect.top;
92 outRect.width = rect.width();
93 outRect.height = rect.height();
94 return outRect;
95}
Marissa Wall87c8ba72019-06-20 14:20:52 -070096
John Reck614326b2022-01-11 15:49:54 -050097// See if gralloc "4.1" is available.
98static bool hasIAllocatorAidl() {
99 // Avoid re-querying repeatedly for this information;
100 static bool sHasIAllocatorAidl = []() -> bool {
101 // TODO: Enable after landing sepolicy changes
102 if constexpr ((true)) return false;
103
104 if (__builtin_available(android 31, *)) {
105 return AServiceManager_isDeclared(kAidlAllocatorServiceName.c_str());
106 }
107 return false;
108 }();
109 return sHasIAllocatorAidl;
110}
111
John Recke0711382022-01-26 12:10:59 -0500112// Determines whether the passed info is compatible with the mapper.
113static status_t validateBufferDescriptorInfo(IMapper::BufferDescriptorInfo* descriptorInfo) {
114 uint64_t validUsageBits = getValidUsageBits();
115 if (hasIAllocatorAidl()) {
116 validUsageBits |= getValidUsageBits41();
117 }
118
119 if (descriptorInfo->usage & ~validUsageBits) {
120 ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64,
121 descriptorInfo->usage & ~validUsageBits);
122 return BAD_VALUE;
123 }
Chris Forbes6c09ee72022-01-26 18:48:55 +1300124
125 // Combinations that are only allowed with gralloc 4.1.
126 // Previous grallocs must be protected from this.
127 if (!hasIAllocatorAidl() &&
128 descriptorInfo->format != hardware::graphics::common::V1_2::PixelFormat::BLOB &&
129 descriptorInfo->usage & BufferUsage::GPU_DATA_BUFFER) {
130 ALOGE("non-BLOB pixel format with GPU_DATA_BUFFER usage is not supported prior to gralloc 4.1");
131 return BAD_VALUE;
132 }
133
John Recke0711382022-01-26 12:10:59 -0500134 return NO_ERROR;
135}
136
137static inline status_t sBufferDescriptorInfo(std::string name, uint32_t width, uint32_t height,
138 PixelFormat format, uint32_t layerCount,
139 uint64_t usage,
140 IMapper::BufferDescriptorInfo* outDescriptorInfo) {
141 outDescriptorInfo->name = name;
142 outDescriptorInfo->width = width;
143 outDescriptorInfo->height = height;
144 outDescriptorInfo->layerCount = layerCount;
145 outDescriptorInfo->format = static_cast<hardware::graphics::common::V1_2::PixelFormat>(format);
146 outDescriptorInfo->usage = usage;
147 outDescriptorInfo->reservedSize = 0;
148
149 return validateBufferDescriptorInfo(outDescriptorInfo);
150}
151
Marissa Wall87c8ba72019-06-20 14:20:52 -0700152} // anonymous namespace
153
154void Gralloc4Mapper::preload() {
155 android::hardware::preloadPassthroughService<IMapper>();
156}
157
158Gralloc4Mapper::Gralloc4Mapper() {
159 mMapper = IMapper::getService();
160 if (mMapper == nullptr) {
161 ALOGI("mapper 4.x is not supported");
162 return;
163 }
164 if (mMapper->isRemote()) {
165 LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
166 }
167}
168
169bool Gralloc4Mapper::isLoaded() const {
170 return mMapper != nullptr;
171}
172
Marissa Wall87c8ba72019-06-20 14:20:52 -0700173status_t Gralloc4Mapper::createDescriptor(void* bufferDescriptorInfo,
174 void* outBufferDescriptor) const {
175 IMapper::BufferDescriptorInfo* descriptorInfo =
176 static_cast<IMapper::BufferDescriptorInfo*>(bufferDescriptorInfo);
177 BufferDescriptor* outDescriptor = static_cast<BufferDescriptor*>(outBufferDescriptor);
178
179 status_t status = validateBufferDescriptorInfo(descriptorInfo);
180 if (status != NO_ERROR) {
181 return status;
182 }
183
184 Error error;
185 auto hidl_cb = [&](const auto& tmpError, const auto& tmpDescriptor) {
186 error = tmpError;
187 if (error != Error::NONE) {
188 return;
189 }
190 *outDescriptor = tmpDescriptor;
191 };
192
193 hardware::Return<void> ret = mMapper->createDescriptor(*descriptorInfo, hidl_cb);
194
195 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
196}
197
198status_t Gralloc4Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
199 buffer_handle_t* outBufferHandle) const {
200 Error error;
201 auto ret = mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
202 error = tmpError;
203 if (error != Error::NONE) {
204 return;
205 }
206 *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
207 });
208
209 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
210}
211
212void Gralloc4Mapper::freeBuffer(buffer_handle_t bufferHandle) const {
213 auto buffer = const_cast<native_handle_t*>(bufferHandle);
214 auto ret = mMapper->freeBuffer(buffer);
215
216 auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
217 ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d", buffer, error);
218}
219
220status_t Gralloc4Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
Marissa Wall22b2de12019-12-02 18:11:43 -0800221 uint32_t height, PixelFormat format,
Marissa Wall87c8ba72019-06-20 14:20:52 -0700222 uint32_t layerCount, uint64_t usage,
223 uint32_t stride) const {
224 IMapper::BufferDescriptorInfo descriptorInfo;
John Recke0711382022-01-26 12:10:59 -0500225 if (auto error = sBufferDescriptorInfo("validateBufferSize", width, height, format, layerCount,
226 usage, &descriptorInfo) != OK) {
227 return error;
228 }
Marissa Wall87c8ba72019-06-20 14:20:52 -0700229
230 auto buffer = const_cast<native_handle_t*>(bufferHandle);
231 auto ret = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
232
233 return static_cast<status_t>((ret.isOk()) ? static_cast<Error>(ret) : kTransactionError);
234}
235
236void Gralloc4Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t* outNumFds,
237 uint32_t* outNumInts) const {
238 *outNumFds = uint32_t(bufferHandle->numFds);
239 *outNumInts = uint32_t(bufferHandle->numInts);
240
241 Error error;
242 auto buffer = const_cast<native_handle_t*>(bufferHandle);
243 auto ret = mMapper->getTransportSize(buffer,
244 [&](const auto& tmpError, const auto& tmpNumFds,
245 const auto& tmpNumInts) {
246 error = tmpError;
247 if (error != Error::NONE) {
248 return;
249 }
250 *outNumFds = tmpNumFds;
251 *outNumInts = tmpNumInts;
252 });
253
254 error = (ret.isOk()) ? error : kTransactionError;
255
256 ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d", buffer, error);
257}
258
259status_t Gralloc4Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
260 int acquireFence, void** outData, int32_t* outBytesPerPixel,
261 int32_t* outBytesPerStride) const {
Marissa Wall22b2de12019-12-02 18:11:43 -0800262 std::vector<ui::PlaneLayout> planeLayouts;
263 status_t err = getPlaneLayouts(bufferHandle, &planeLayouts);
264
Valerie Hau3bb97912020-04-09 10:40:10 -0700265 if (err == NO_ERROR && !planeLayouts.empty()) {
Marissa Wall22b2de12019-12-02 18:11:43 -0800266 if (outBytesPerPixel) {
267 int32_t bitsPerPixel = planeLayouts.front().sampleIncrementInBits;
268 for (const auto& planeLayout : planeLayouts) {
269 if (bitsPerPixel != planeLayout.sampleIncrementInBits) {
270 bitsPerPixel = -1;
271 }
272 }
273 if (bitsPerPixel >= 0 && bitsPerPixel % 8 == 0) {
274 *outBytesPerPixel = bitsPerPixel / 8;
275 } else {
276 *outBytesPerPixel = -1;
277 }
278 }
279 if (outBytesPerStride) {
280 int32_t bytesPerStride = planeLayouts.front().strideInBytes;
281 for (const auto& planeLayout : planeLayouts) {
282 if (bytesPerStride != planeLayout.strideInBytes) {
283 bytesPerStride = -1;
284 }
285 }
286 if (bytesPerStride >= 0) {
287 *outBytesPerStride = bytesPerStride;
288 } else {
289 *outBytesPerStride = -1;
290 }
291 }
Marissa Wall20611c62019-11-05 15:06:24 -0800292 }
293
Marissa Wall87c8ba72019-06-20 14:20:52 -0700294 auto buffer = const_cast<native_handle_t*>(bufferHandle);
295
296 IMapper::Rect accessRegion = sGralloc4Rect(bounds);
297
298 // put acquireFence in a hidl_handle
299 hardware::hidl_handle acquireFenceHandle;
300 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
301 if (acquireFence >= 0) {
302 auto h = native_handle_init(acquireFenceStorage, 1, 0);
303 h->data[0] = acquireFence;
304 acquireFenceHandle = h;
305 }
306
307 Error error;
308 auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
Marissa Wall20611c62019-11-05 15:06:24 -0800309 [&](const auto& tmpError, const auto& tmpData) {
Marissa Wall87c8ba72019-06-20 14:20:52 -0700310 error = tmpError;
311 if (error != Error::NONE) {
312 return;
313 }
314 *outData = tmpData;
Marissa Wall87c8ba72019-06-20 14:20:52 -0700315 });
316
317 // we own acquireFence even on errors
318 if (acquireFence >= 0) {
319 close(acquireFence);
320 }
321
322 error = (ret.isOk()) ? error : kTransactionError;
323
324 ALOGW_IF(error != Error::NONE, "lock(%p, ...) failed: %d", bufferHandle, error);
325
326 return static_cast<status_t>(error);
327}
328
Marissa Wall22b2de12019-12-02 18:11:43 -0800329status_t Gralloc4Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
330 int acquireFence, android_ycbcr* outYcbcr) const {
331 if (!outYcbcr) {
332 return BAD_VALUE;
333 }
334
335 std::vector<ui::PlaneLayout> planeLayouts;
336 status_t error = getPlaneLayouts(bufferHandle, &planeLayouts);
337 if (error != NO_ERROR) {
338 return error;
339 }
340
341 void* data = nullptr;
342 error = lock(bufferHandle, usage, bounds, acquireFence, &data, nullptr, nullptr);
343 if (error != NO_ERROR) {
344 return error;
345 }
346
347 android_ycbcr ycbcr;
348
349 ycbcr.y = nullptr;
350 ycbcr.cb = nullptr;
351 ycbcr.cr = nullptr;
352 ycbcr.ystride = 0;
353 ycbcr.cstride = 0;
354 ycbcr.chroma_step = 0;
355
356 for (const auto& planeLayout : planeLayouts) {
357 for (const auto& planeLayoutComponent : planeLayout.components) {
358 if (!gralloc4::isStandardPlaneLayoutComponentType(planeLayoutComponent.type)) {
359 continue;
360 }
361 if (0 != planeLayoutComponent.offsetInBits % 8) {
362 unlock(bufferHandle);
363 return BAD_VALUE;
364 }
365
366 uint8_t* tmpData = static_cast<uint8_t*>(data) + planeLayout.offsetInBytes +
367 (planeLayoutComponent.offsetInBits / 8);
368 uint64_t sampleIncrementInBytes;
369
370 auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
371 switch (type) {
372 case PlaneLayoutComponentType::Y:
373 if ((ycbcr.y != nullptr) || (planeLayoutComponent.sizeInBits != 8) ||
374 (planeLayout.sampleIncrementInBits != 8)) {
375 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;
390 if ((sampleIncrementInBytes != 1) && (sampleIncrementInBytes != 2)) {
391 unlock(bufferHandle);
392 return BAD_VALUE;
393 }
394
395 if (ycbcr.cstride == 0 && ycbcr.chroma_step == 0) {
396 ycbcr.cstride = planeLayout.strideInBytes;
397 ycbcr.chroma_step = sampleIncrementInBytes;
398 } else {
399 if ((static_cast<int64_t>(ycbcr.cstride) != planeLayout.strideInBytes) ||
400 (ycbcr.chroma_step != sampleIncrementInBytes)) {
401 unlock(bufferHandle);
402 return BAD_VALUE;
403 }
404 }
405
406 if (type == PlaneLayoutComponentType::CB) {
407 if (ycbcr.cb != nullptr) {
408 unlock(bufferHandle);
409 return BAD_VALUE;
410 }
411 ycbcr.cb = tmpData;
412 } else {
413 if (ycbcr.cr != nullptr) {
414 unlock(bufferHandle);
415 return BAD_VALUE;
416 }
417 ycbcr.cr = tmpData;
418 }
419 break;
420 default:
421 break;
422 };
423 }
424 }
425
426 *outYcbcr = ycbcr;
Marissa Wall90df5852020-02-27 10:17:02 -0800427 return static_cast<status_t>(Error::NONE);
Marissa Wall87c8ba72019-06-20 14:20:52 -0700428}
429
430int Gralloc4Mapper::unlock(buffer_handle_t bufferHandle) const {
431 auto buffer = const_cast<native_handle_t*>(bufferHandle);
432
433 int releaseFence = -1;
434 Error error;
435 auto ret = mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
436 error = tmpError;
437 if (error != Error::NONE) {
438 return;
439 }
440
441 auto fenceHandle = tmpReleaseFence.getNativeHandle();
442 if (fenceHandle && fenceHandle->numFds == 1) {
443 int fd = dup(fenceHandle->data[0]);
444 if (fd >= 0) {
445 releaseFence = fd;
446 } else {
John Recke0711382022-01-26 12:10:59 -0500447 ALOGW("failed to dup unlock release fence");
Marissa Wall87c8ba72019-06-20 14:20:52 -0700448 sync_wait(fenceHandle->data[0], -1);
449 }
450 }
451 });
452
453 if (!ret.isOk()) {
454 error = kTransactionError;
455 }
456
457 if (error != Error::NONE) {
458 ALOGE("unlock(%p) failed with %d", buffer, error);
459 }
460
461 return releaseFence;
462}
463
Marissa Wall22b2de12019-12-02 18:11:43 -0800464status_t Gralloc4Mapper::isSupported(uint32_t width, uint32_t height, PixelFormat format,
Marissa Wall87c8ba72019-06-20 14:20:52 -0700465 uint32_t layerCount, uint64_t usage,
466 bool* outSupported) const {
467 IMapper::BufferDescriptorInfo descriptorInfo;
John Recke0711382022-01-26 12:10:59 -0500468 if (auto error = sBufferDescriptorInfo("isSupported", width, height, format, layerCount, usage,
469 &descriptorInfo) != OK) {
470 // Usage isn't known to the HAL or otherwise failed validation.
471 *outSupported = false;
472 return OK;
473 }
Marissa Wall87c8ba72019-06-20 14:20:52 -0700474
475 Error error;
476 auto ret = mMapper->isSupported(descriptorInfo,
477 [&](const auto& tmpError, const auto& tmpSupported) {
478 error = tmpError;
479 if (error != Error::NONE) {
480 return;
481 }
482 if (outSupported) {
483 *outSupported = tmpSupported;
484 }
485 });
486
487 if (!ret.isOk()) {
488 error = kTransactionError;
489 }
490
491 if (error != Error::NONE) {
492 ALOGE("isSupported(%u, %u, %d, %u, ...) failed with %d", width, height, format, layerCount,
493 error);
494 }
495
496 return static_cast<status_t>(error);
497}
498
Marissa Wall22b2de12019-12-02 18:11:43 -0800499template <class T>
500status_t Gralloc4Mapper::get(buffer_handle_t bufferHandle, const MetadataType& metadataType,
501 DecodeFunction<T> decodeFunction, T* outMetadata) const {
502 if (!outMetadata) {
503 return BAD_VALUE;
504 }
505
506 hidl_vec<uint8_t> vec;
507 Error error;
508 auto ret = mMapper->get(const_cast<native_handle_t*>(bufferHandle), metadataType,
509 [&](const auto& tmpError, const hidl_vec<uint8_t>& tmpVec) {
510 error = tmpError;
511 vec = tmpVec;
512 });
513
514 if (!ret.isOk()) {
515 error = kTransactionError;
516 }
517
518 if (error != Error::NONE) {
519 ALOGE("get(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
520 metadataType.value, error);
521 return static_cast<status_t>(error);
522 }
523
524 return decodeFunction(vec, outMetadata);
525}
526
527status_t Gralloc4Mapper::getBufferId(buffer_handle_t bufferHandle, uint64_t* outBufferId) const {
528 return get(bufferHandle, gralloc4::MetadataType_BufferId, gralloc4::decodeBufferId,
529 outBufferId);
530}
531
532status_t Gralloc4Mapper::getName(buffer_handle_t bufferHandle, std::string* outName) const {
533 return get(bufferHandle, gralloc4::MetadataType_Name, gralloc4::decodeName, outName);
534}
535
536status_t Gralloc4Mapper::getWidth(buffer_handle_t bufferHandle, uint64_t* outWidth) const {
537 return get(bufferHandle, gralloc4::MetadataType_Width, gralloc4::decodeWidth, outWidth);
538}
539
540status_t Gralloc4Mapper::getHeight(buffer_handle_t bufferHandle, uint64_t* outHeight) const {
541 return get(bufferHandle, gralloc4::MetadataType_Height, gralloc4::decodeHeight, outHeight);
542}
543
544status_t Gralloc4Mapper::getLayerCount(buffer_handle_t bufferHandle,
545 uint64_t* outLayerCount) const {
546 return get(bufferHandle, gralloc4::MetadataType_LayerCount, gralloc4::decodeLayerCount,
547 outLayerCount);
548}
549
550status_t Gralloc4Mapper::getPixelFormatRequested(buffer_handle_t bufferHandle,
551 ui::PixelFormat* outPixelFormatRequested) const {
552 return get(bufferHandle, gralloc4::MetadataType_PixelFormatRequested,
553 gralloc4::decodePixelFormatRequested, outPixelFormatRequested);
554}
555
556status_t Gralloc4Mapper::getPixelFormatFourCC(buffer_handle_t bufferHandle,
557 uint32_t* outPixelFormatFourCC) const {
558 return get(bufferHandle, gralloc4::MetadataType_PixelFormatFourCC,
559 gralloc4::decodePixelFormatFourCC, outPixelFormatFourCC);
560}
561
562status_t Gralloc4Mapper::getPixelFormatModifier(buffer_handle_t bufferHandle,
563 uint64_t* outPixelFormatModifier) const {
564 return get(bufferHandle, gralloc4::MetadataType_PixelFormatModifier,
565 gralloc4::decodePixelFormatModifier, outPixelFormatModifier);
566}
567
568status_t Gralloc4Mapper::getUsage(buffer_handle_t bufferHandle, uint64_t* outUsage) const {
569 return get(bufferHandle, gralloc4::MetadataType_Usage, gralloc4::decodeUsage, outUsage);
570}
571
572status_t Gralloc4Mapper::getAllocationSize(buffer_handle_t bufferHandle,
573 uint64_t* outAllocationSize) const {
574 return get(bufferHandle, gralloc4::MetadataType_AllocationSize, gralloc4::decodeAllocationSize,
575 outAllocationSize);
576}
577
578status_t Gralloc4Mapper::getProtectedContent(buffer_handle_t bufferHandle,
579 uint64_t* outProtectedContent) const {
580 return get(bufferHandle, gralloc4::MetadataType_ProtectedContent,
581 gralloc4::decodeProtectedContent, outProtectedContent);
582}
583
584status_t Gralloc4Mapper::getCompression(buffer_handle_t bufferHandle,
585 ExtendableType* outCompression) const {
586 return get(bufferHandle, gralloc4::MetadataType_Compression, gralloc4::decodeCompression,
587 outCompression);
588}
589
590status_t Gralloc4Mapper::getCompression(buffer_handle_t bufferHandle,
591 ui::Compression* outCompression) const {
592 if (!outCompression) {
593 return BAD_VALUE;
594 }
595 ExtendableType compression;
596 status_t error = getCompression(bufferHandle, &compression);
597 if (error) {
598 return error;
599 }
600 if (!gralloc4::isStandardCompression(compression)) {
601 return BAD_TYPE;
602 }
603 *outCompression = gralloc4::getStandardCompressionValue(compression);
604 return NO_ERROR;
605}
606
607status_t Gralloc4Mapper::getInterlaced(buffer_handle_t bufferHandle,
608 ExtendableType* outInterlaced) const {
609 return get(bufferHandle, gralloc4::MetadataType_Interlaced, gralloc4::decodeInterlaced,
610 outInterlaced);
611}
612
613status_t Gralloc4Mapper::getInterlaced(buffer_handle_t bufferHandle,
614 ui::Interlaced* outInterlaced) const {
615 if (!outInterlaced) {
616 return BAD_VALUE;
617 }
618 ExtendableType interlaced;
619 status_t error = getInterlaced(bufferHandle, &interlaced);
620 if (error) {
621 return error;
622 }
623 if (!gralloc4::isStandardInterlaced(interlaced)) {
624 return BAD_TYPE;
625 }
626 *outInterlaced = gralloc4::getStandardInterlacedValue(interlaced);
627 return NO_ERROR;
628}
629
630status_t Gralloc4Mapper::getChromaSiting(buffer_handle_t bufferHandle,
631 ExtendableType* outChromaSiting) const {
632 return get(bufferHandle, gralloc4::MetadataType_ChromaSiting, gralloc4::decodeChromaSiting,
633 outChromaSiting);
634}
635
636status_t Gralloc4Mapper::getChromaSiting(buffer_handle_t bufferHandle,
637 ui::ChromaSiting* outChromaSiting) const {
638 if (!outChromaSiting) {
639 return BAD_VALUE;
640 }
641 ExtendableType chromaSiting;
642 status_t error = getChromaSiting(bufferHandle, &chromaSiting);
643 if (error) {
644 return error;
645 }
646 if (!gralloc4::isStandardChromaSiting(chromaSiting)) {
647 return BAD_TYPE;
648 }
649 *outChromaSiting = gralloc4::getStandardChromaSitingValue(chromaSiting);
650 return NO_ERROR;
651}
652
653status_t Gralloc4Mapper::getPlaneLayouts(buffer_handle_t bufferHandle,
654 std::vector<ui::PlaneLayout>* outPlaneLayouts) const {
655 return get(bufferHandle, gralloc4::MetadataType_PlaneLayouts, gralloc4::decodePlaneLayouts,
656 outPlaneLayouts);
657}
658
659status_t Gralloc4Mapper::getDataspace(buffer_handle_t bufferHandle,
660 ui::Dataspace* outDataspace) const {
661 if (!outDataspace) {
662 return BAD_VALUE;
663 }
Yichi Chenba40db52021-04-30 00:18:32 +0800664 AidlDataspace dataspace;
Marissa Wall22b2de12019-12-02 18:11:43 -0800665 status_t error = get(bufferHandle, gralloc4::MetadataType_Dataspace, gralloc4::decodeDataspace,
666 &dataspace);
667 if (error) {
668 return error;
669 }
670
671 // Gralloc4 uses stable AIDL dataspace but the rest of the system still uses HIDL dataspace
672 *outDataspace = static_cast<ui::Dataspace>(dataspace);
673 return NO_ERROR;
674}
675
676status_t Gralloc4Mapper::getBlendMode(buffer_handle_t bufferHandle,
677 ui::BlendMode* outBlendMode) const {
678 return get(bufferHandle, gralloc4::MetadataType_BlendMode, gralloc4::decodeBlendMode,
679 outBlendMode);
680}
681
Marissa Wallef785e12019-12-12 14:26:59 -0800682status_t Gralloc4Mapper::getSmpte2086(buffer_handle_t bufferHandle,
683 std::optional<ui::Smpte2086>* outSmpte2086) const {
684 return get(bufferHandle, gralloc4::MetadataType_Smpte2086, gralloc4::decodeSmpte2086,
685 outSmpte2086);
686}
687
688status_t Gralloc4Mapper::getCta861_3(buffer_handle_t bufferHandle,
689 std::optional<ui::Cta861_3>* outCta861_3) const {
690 return get(bufferHandle, gralloc4::MetadataType_Cta861_3, gralloc4::decodeCta861_3,
691 outCta861_3);
692}
693
694status_t Gralloc4Mapper::getSmpte2094_40(
695 buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>>* outSmpte2094_40) const {
696 return get(bufferHandle, gralloc4::MetadataType_Smpte2094_40, gralloc4::decodeSmpte2094_40,
697 outSmpte2094_40);
698}
699
Alec Mouri332765e2021-10-06 16:38:12 -0700700status_t Gralloc4Mapper::getSmpte2094_10(
701 buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>>* outSmpte2094_10) const {
702 return get(bufferHandle, gralloc4::MetadataType_Smpte2094_10, gralloc4::decodeSmpte2094_10,
703 outSmpte2094_10);
704}
705
Marissa Wall22b2de12019-12-02 18:11:43 -0800706template <class T>
707status_t Gralloc4Mapper::getDefault(uint32_t width, uint32_t height, PixelFormat format,
708 uint32_t layerCount, uint64_t usage,
709 const MetadataType& metadataType,
710 DecodeFunction<T> decodeFunction, T* outMetadata) const {
711 if (!outMetadata) {
712 return BAD_VALUE;
713 }
714
715 IMapper::BufferDescriptorInfo descriptorInfo;
John Recke0711382022-01-26 12:10:59 -0500716 if (auto error = sBufferDescriptorInfo("getDefault", width, height, format, layerCount, usage,
717 &descriptorInfo) != OK) {
718 return error;
719 }
Marissa Wall22b2de12019-12-02 18:11:43 -0800720
721 hidl_vec<uint8_t> vec;
722 Error error;
723 auto ret = mMapper->getFromBufferDescriptorInfo(descriptorInfo, metadataType,
724 [&](const auto& tmpError,
725 const hidl_vec<uint8_t>& tmpVec) {
726 error = tmpError;
727 vec = tmpVec;
728 });
729
730 if (!ret.isOk()) {
731 error = kTransactionError;
732 }
733
734 if (error != Error::NONE) {
735 ALOGE("getDefault(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
736 metadataType.value, error);
737 return static_cast<status_t>(error);
738 }
739
740 return decodeFunction(vec, outMetadata);
741}
742
743status_t Gralloc4Mapper::getDefaultPixelFormatFourCC(uint32_t width, uint32_t height,
744 PixelFormat format, uint32_t layerCount,
745 uint64_t usage,
746 uint32_t* outPixelFormatFourCC) const {
747 return getDefault(width, height, format, layerCount, usage,
748 gralloc4::MetadataType_PixelFormatFourCC, gralloc4::decodePixelFormatFourCC,
749 outPixelFormatFourCC);
750}
751
752status_t Gralloc4Mapper::getDefaultPixelFormatModifier(uint32_t width, uint32_t height,
753 PixelFormat format, uint32_t layerCount,
754 uint64_t usage,
755 uint64_t* outPixelFormatModifier) const {
756 return getDefault(width, height, format, layerCount, usage,
757 gralloc4::MetadataType_PixelFormatModifier,
758 gralloc4::decodePixelFormatModifier, outPixelFormatModifier);
759}
760
761status_t Gralloc4Mapper::getDefaultAllocationSize(uint32_t width, uint32_t height,
762 PixelFormat format, uint32_t layerCount,
763 uint64_t usage,
764 uint64_t* outAllocationSize) const {
765 return getDefault(width, height, format, layerCount, usage,
766 gralloc4::MetadataType_AllocationSize, gralloc4::decodeAllocationSize,
767 outAllocationSize);
768}
769
770status_t Gralloc4Mapper::getDefaultProtectedContent(uint32_t width, uint32_t height,
771 PixelFormat format, uint32_t layerCount,
772 uint64_t usage,
773 uint64_t* outProtectedContent) const {
774 return getDefault(width, height, format, layerCount, usage,
775 gralloc4::MetadataType_ProtectedContent, gralloc4::decodeProtectedContent,
776 outProtectedContent);
777}
778
779status_t Gralloc4Mapper::getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
780 uint32_t layerCount, uint64_t usage,
781 ExtendableType* outCompression) const {
782 return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_Compression,
783 gralloc4::decodeCompression, outCompression);
784}
785
786status_t Gralloc4Mapper::getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
787 uint32_t layerCount, uint64_t usage,
788 ui::Compression* outCompression) const {
789 if (!outCompression) {
790 return BAD_VALUE;
791 }
792 ExtendableType compression;
793 status_t error = getDefaultCompression(width, height, format, layerCount, usage, &compression);
794 if (error) {
795 return error;
796 }
797 if (!gralloc4::isStandardCompression(compression)) {
798 return BAD_TYPE;
799 }
800 *outCompression = gralloc4::getStandardCompressionValue(compression);
801 return NO_ERROR;
802}
803
804status_t Gralloc4Mapper::getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
805 uint32_t layerCount, uint64_t usage,
806 ExtendableType* outInterlaced) const {
807 return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_Interlaced,
808 gralloc4::decodeInterlaced, outInterlaced);
809}
810
811status_t Gralloc4Mapper::getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
812 uint32_t layerCount, uint64_t usage,
813 ui::Interlaced* outInterlaced) const {
814 if (!outInterlaced) {
815 return BAD_VALUE;
816 }
817 ExtendableType interlaced;
818 status_t error = getDefaultInterlaced(width, height, format, layerCount, usage, &interlaced);
819 if (error) {
820 return error;
821 }
822 if (!gralloc4::isStandardInterlaced(interlaced)) {
823 return BAD_TYPE;
824 }
825 *outInterlaced = gralloc4::getStandardInterlacedValue(interlaced);
826 return NO_ERROR;
827}
828
829status_t Gralloc4Mapper::getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
830 uint32_t layerCount, uint64_t usage,
831 ExtendableType* outChromaSiting) const {
832 return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_ChromaSiting,
833 gralloc4::decodeChromaSiting, outChromaSiting);
834}
835
836status_t Gralloc4Mapper::getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
837 uint32_t layerCount, uint64_t usage,
838 ui::ChromaSiting* outChromaSiting) const {
839 if (!outChromaSiting) {
840 return BAD_VALUE;
841 }
842 ExtendableType chromaSiting;
843 status_t error =
844 getDefaultChromaSiting(width, height, format, layerCount, usage, &chromaSiting);
845 if (error) {
846 return error;
847 }
848 if (!gralloc4::isStandardChromaSiting(chromaSiting)) {
849 return BAD_TYPE;
850 }
851 *outChromaSiting = gralloc4::getStandardChromaSitingValue(chromaSiting);
852 return NO_ERROR;
853}
854
855status_t Gralloc4Mapper::getDefaultPlaneLayouts(
856 uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage,
857 std::vector<ui::PlaneLayout>* outPlaneLayouts) const {
858 return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_PlaneLayouts,
859 gralloc4::decodePlaneLayouts, outPlaneLayouts);
860}
861
862std::vector<MetadataTypeDescription> Gralloc4Mapper::listSupportedMetadataTypes() const {
863 hidl_vec<MetadataTypeDescription> descriptions;
864 Error error;
865 auto ret = mMapper->listSupportedMetadataTypes(
866 [&](const auto& tmpError, const auto& tmpDescriptions) {
867 error = tmpError;
868 descriptions = tmpDescriptions;
869 });
870
871 if (!ret.isOk()) {
872 error = kTransactionError;
873 }
874
875 if (error != Error::NONE) {
876 ALOGE("listSupportedMetadataType() failed with %d", error);
877 return {};
878 }
879
880 return static_cast<std::vector<MetadataTypeDescription>>(descriptions);
881}
882
883template <class T>
884status_t Gralloc4Mapper::metadataDumpHelper(const BufferDump& bufferDump,
885 StandardMetadataType metadataType,
886 DecodeFunction<T> decodeFunction, T* outT) const {
887 const auto& metadataDump = bufferDump.metadataDump;
888
889 auto itr =
890 std::find_if(metadataDump.begin(), metadataDump.end(),
891 [&](const MetadataDump& tmpMetadataDump) {
892 if (!gralloc4::isStandardMetadataType(tmpMetadataDump.metadataType)) {
893 return false;
894 }
895 return metadataType ==
896 gralloc4::getStandardMetadataTypeValue(
897 tmpMetadataDump.metadataType);
898 });
899 if (itr == metadataDump.end()) {
900 return BAD_VALUE;
901 }
902
903 return decodeFunction(itr->metadata, outT);
904}
905
906status_t Gralloc4Mapper::bufferDumpHelper(const BufferDump& bufferDump, std::ostringstream* outDump,
907 uint64_t* outAllocationSize, bool less) const {
908 uint64_t bufferId;
909 std::string name;
910 uint64_t width;
911 uint64_t height;
912 uint64_t layerCount;
913 ui::PixelFormat pixelFormatRequested;
914 uint32_t pixelFormatFourCC;
915 uint64_t pixelFormatModifier;
916 uint64_t usage;
Yichi Chenba40db52021-04-30 00:18:32 +0800917 AidlDataspace dataspace;
Marissa Wall22b2de12019-12-02 18:11:43 -0800918 uint64_t allocationSize;
919 uint64_t protectedContent;
920 ExtendableType compression;
921 ExtendableType interlaced;
922 ExtendableType chromaSiting;
923 std::vector<ui::PlaneLayout> planeLayouts;
924
925 status_t error = metadataDumpHelper(bufferDump, StandardMetadataType::BUFFER_ID,
926 gralloc4::decodeBufferId, &bufferId);
927 if (error != NO_ERROR) {
928 return error;
929 }
930 error = metadataDumpHelper(bufferDump, StandardMetadataType::NAME, gralloc4::decodeName, &name);
931 if (error != NO_ERROR) {
932 return error;
933 }
934 error = metadataDumpHelper(bufferDump, StandardMetadataType::WIDTH, gralloc4::decodeWidth,
935 &width);
936 if (error != NO_ERROR) {
937 return error;
938 }
939 error = metadataDumpHelper(bufferDump, StandardMetadataType::HEIGHT, gralloc4::decodeHeight,
940 &height);
941 if (error != NO_ERROR) {
942 return error;
943 }
944 error = metadataDumpHelper(bufferDump, StandardMetadataType::LAYER_COUNT,
945 gralloc4::decodeLayerCount, &layerCount);
946 if (error != NO_ERROR) {
947 return error;
948 }
949 error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_REQUESTED,
950 gralloc4::decodePixelFormatRequested, &pixelFormatRequested);
951 if (error != NO_ERROR) {
952 return error;
953 }
954 error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_FOURCC,
955 gralloc4::decodePixelFormatFourCC, &pixelFormatFourCC);
956 if (error != NO_ERROR) {
957 return error;
958 }
959 error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_MODIFIER,
960 gralloc4::decodePixelFormatModifier, &pixelFormatModifier);
961 if (error != NO_ERROR) {
962 return error;
963 }
964 error = metadataDumpHelper(bufferDump, StandardMetadataType::USAGE, gralloc4::decodeUsage,
965 &usage);
966 if (error != NO_ERROR) {
967 return error;
968 }
Yichi Chenba40db52021-04-30 00:18:32 +0800969 error = metadataDumpHelper(bufferDump, StandardMetadataType::DATASPACE,
970 gralloc4::decodeDataspace, &dataspace);
971 if (error != NO_ERROR) {
972 return error;
973 }
Marissa Wall22b2de12019-12-02 18:11:43 -0800974 error = metadataDumpHelper(bufferDump, StandardMetadataType::ALLOCATION_SIZE,
975 gralloc4::decodeAllocationSize, &allocationSize);
976 if (error != NO_ERROR) {
977 return error;
978 }
979 error = metadataDumpHelper(bufferDump, StandardMetadataType::PROTECTED_CONTENT,
980 gralloc4::decodeProtectedContent, &protectedContent);
981 if (error != NO_ERROR) {
982 return error;
983 }
984 error = metadataDumpHelper(bufferDump, StandardMetadataType::COMPRESSION,
985 gralloc4::decodeCompression, &compression);
986 if (error != NO_ERROR) {
987 return error;
988 }
989 error = metadataDumpHelper(bufferDump, StandardMetadataType::INTERLACED,
990 gralloc4::decodeInterlaced, &interlaced);
991 if (error != NO_ERROR) {
992 return error;
993 }
994 error = metadataDumpHelper(bufferDump, StandardMetadataType::CHROMA_SITING,
995 gralloc4::decodeChromaSiting, &chromaSiting);
996 if (error != NO_ERROR) {
997 return error;
998 }
999 error = metadataDumpHelper(bufferDump, StandardMetadataType::PLANE_LAYOUTS,
1000 gralloc4::decodePlaneLayouts, &planeLayouts);
1001 if (error != NO_ERROR) {
1002 return error;
1003 }
1004
1005 if (outAllocationSize) {
1006 *outAllocationSize = allocationSize;
1007 }
1008 double allocationSizeKiB = static_cast<double>(allocationSize) / 1024;
1009
Alec Mouri04511ef2022-01-06 12:57:12 -08001010 *outDump << "+ name:" << name << ", id:" << bufferId << ", size:" << std::fixed
1011 << allocationSizeKiB << "KiB, w/h:" << width << "x" << height << ", usage: 0x"
1012 << std::hex << usage << std::dec
1013 << ", req fmt:" << static_cast<int32_t>(pixelFormatRequested)
Marissa Wall22b2de12019-12-02 18:11:43 -08001014 << ", fourcc/mod:" << pixelFormatFourCC << "/" << pixelFormatModifier
Yichi Chen6de5b582021-09-13 20:00:52 +08001015 << ", dataspace: 0x" << std::hex << static_cast<uint32_t>(dataspace) << std::dec
Marissa Wall22b2de12019-12-02 18:11:43 -08001016 << ", compressed: ";
1017
1018 if (less) {
1019 bool isCompressed = !gralloc4::isStandardCompression(compression) ||
1020 (gralloc4::getStandardCompressionValue(compression) != ui::Compression::NONE);
1021 *outDump << std::boolalpha << isCompressed << "\n";
1022 } else {
1023 *outDump << gralloc4::getCompressionName(compression) << "\n";
1024 }
1025
1026 bool firstPlane = true;
1027 for (const auto& planeLayout : planeLayouts) {
1028 if (firstPlane) {
1029 firstPlane = false;
1030 *outDump << "\tplanes: ";
1031 } else {
1032 *outDump << "\t ";
1033 }
1034
1035 for (size_t i = 0; i < planeLayout.components.size(); i++) {
1036 const auto& planeLayoutComponent = planeLayout.components[i];
1037 *outDump << gralloc4::getPlaneLayoutComponentTypeName(planeLayoutComponent.type);
1038 if (i < planeLayout.components.size() - 1) {
1039 *outDump << "/";
1040 } else {
1041 *outDump << ":\t";
1042 }
1043 }
1044 *outDump << " w/h:" << planeLayout.widthInSamples << "x" << planeLayout.heightInSamples
1045 << ", stride:" << planeLayout.strideInBytes
1046 << " bytes, size:" << planeLayout.totalSizeInBytes;
1047 if (!less) {
1048 *outDump << ", inc:" << planeLayout.sampleIncrementInBits
1049 << " bits, subsampling w/h:" << planeLayout.horizontalSubsampling << "x"
1050 << planeLayout.verticalSubsampling;
1051 }
1052 *outDump << "\n";
1053 }
1054
1055 if (!less) {
1056 *outDump << "\tlayer cnt: " << layerCount << ", protected content: " << protectedContent
1057 << ", interlaced: " << gralloc4::getInterlacedName(interlaced)
1058 << ", chroma siting:" << gralloc4::getChromaSitingName(chromaSiting) << "\n";
1059 }
1060
1061 return NO_ERROR;
1062}
1063
1064std::string Gralloc4Mapper::dumpBuffer(buffer_handle_t bufferHandle, bool less) const {
1065 auto buffer = const_cast<native_handle_t*>(bufferHandle);
1066
1067 BufferDump bufferDump;
1068 Error error;
1069 auto ret = mMapper->dumpBuffer(buffer, [&](const auto& tmpError, const auto& tmpBufferDump) {
1070 error = tmpError;
1071 bufferDump = tmpBufferDump;
1072 });
1073
1074 if (!ret.isOk()) {
1075 error = kTransactionError;
1076 }
1077
1078 if (error != Error::NONE) {
1079 ALOGE("dumpBuffer() failed with %d", error);
1080 return "";
1081 }
1082
1083 std::ostringstream stream;
1084 stream.precision(2);
1085
1086 status_t err = bufferDumpHelper(bufferDump, &stream, nullptr, less);
1087 if (err != NO_ERROR) {
1088 ALOGE("bufferDumpHelper() failed with %d", err);
1089 return "";
1090 }
1091
1092 return stream.str();
1093}
1094
1095std::string Gralloc4Mapper::dumpBuffers(bool less) const {
1096 hidl_vec<BufferDump> bufferDumps;
1097 Error error;
1098 auto ret = mMapper->dumpBuffers([&](const auto& tmpError, const auto& tmpBufferDump) {
1099 error = tmpError;
1100 bufferDumps = tmpBufferDump;
1101 });
1102
1103 if (!ret.isOk()) {
1104 error = kTransactionError;
1105 }
1106
1107 if (error != Error::NONE) {
1108 ALOGE("dumpBuffer() failed with %d", error);
1109 return "";
1110 }
1111
1112 uint64_t totalAllocationSize = 0;
1113 std::ostringstream stream;
1114 stream.precision(2);
1115
1116 stream << "Imported gralloc buffers:\n";
1117
1118 for (const auto& bufferDump : bufferDumps) {
1119 uint64_t allocationSize = 0;
1120 status_t err = bufferDumpHelper(bufferDump, &stream, &allocationSize, less);
1121 if (err != NO_ERROR) {
1122 ALOGE("bufferDumpHelper() failed with %d", err);
1123 return "";
1124 }
1125 totalAllocationSize += allocationSize;
1126 }
1127
1128 double totalAllocationSizeKiB = static_cast<double>(totalAllocationSize) / 1024;
1129 stream << "Total imported by gralloc: " << totalAllocationSizeKiB << "KiB\n";
1130 return stream.str();
1131}
1132
Marissa Wall87c8ba72019-06-20 14:20:52 -07001133Gralloc4Allocator::Gralloc4Allocator(const Gralloc4Mapper& mapper) : mMapper(mapper) {
1134 mAllocator = IAllocator::getService();
1135 if (mAllocator == nullptr) {
Yiwei Zhange6124d92020-11-16 02:52:51 +00001136 ALOGW("allocator 4.x is not supported");
Marissa Wall87c8ba72019-06-20 14:20:52 -07001137 return;
1138 }
John Reck614326b2022-01-11 15:49:54 -05001139 if (__builtin_available(android 31, *)) {
1140 if (hasIAllocatorAidl()) {
1141 mAidlAllocator = AidlIAllocator::fromBinder(ndk::SpAIBinder(
1142 AServiceManager_waitForService(kAidlAllocatorServiceName.c_str())));
1143 ALOGE_IF(!mAidlAllocator, "AIDL IAllocator declared but failed to get service");
1144 }
1145 }
Marissa Wall87c8ba72019-06-20 14:20:52 -07001146}
1147
1148bool Gralloc4Allocator::isLoaded() const {
1149 return mAllocator != nullptr;
1150}
1151
Marissa Wall22b2de12019-12-02 18:11:43 -08001152std::string Gralloc4Allocator::dumpDebugInfo(bool less) const {
1153 return mMapper.dumpBuffers(less);
Marissa Wall87c8ba72019-06-20 14:20:52 -07001154}
1155
Marissa Wall22b2de12019-12-02 18:11:43 -08001156status_t Gralloc4Allocator::allocate(std::string requestorName, uint32_t width, uint32_t height,
1157 android::PixelFormat format, uint32_t layerCount,
1158 uint64_t usage, uint32_t bufferCount, uint32_t* outStride,
1159 buffer_handle_t* outBufferHandles, bool importBuffers) const {
Marissa Wall87c8ba72019-06-20 14:20:52 -07001160 IMapper::BufferDescriptorInfo descriptorInfo;
John Recke0711382022-01-26 12:10:59 -05001161 if (auto error = sBufferDescriptorInfo(requestorName, width, height, format, layerCount, usage,
1162 &descriptorInfo) != OK) {
1163 return error;
1164 }
Marissa Wall87c8ba72019-06-20 14:20:52 -07001165
1166 BufferDescriptor descriptor;
1167 status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),
1168 static_cast<void*>(&descriptor));
1169 if (error != NO_ERROR) {
1170 return error;
1171 }
1172
John Reck614326b2022-01-11 15:49:54 -05001173 if (mAidlAllocator) {
1174 AllocationResult result;
1175 auto status = mAidlAllocator->allocate(descriptor, bufferCount, &result);
1176 if (!status.isOk()) {
1177 error = status.getExceptionCode();
1178 if (error == EX_SERVICE_SPECIFIC) {
1179 error = status.getServiceSpecificError();
1180 }
1181 if (error == OK) {
1182 error = UNKNOWN_ERROR;
1183 }
1184 } else {
1185 if (importBuffers) {
1186 for (uint32_t i = 0; i < bufferCount; i++) {
1187 error = mMapper.importBuffer(makeFromAidl(result.buffers[i]),
1188 &outBufferHandles[i]);
1189 if (error != NO_ERROR) {
1190 for (uint32_t j = 0; j < i; j++) {
1191 mMapper.freeBuffer(outBufferHandles[j]);
1192 outBufferHandles[j] = nullptr;
1193 }
1194 break;
1195 }
1196 }
1197 } else {
1198 for (uint32_t i = 0; i < bufferCount; i++) {
1199 outBufferHandles[i] = dupFromAidl(result.buffers[i]);
1200 if (!outBufferHandles[i]) {
1201 for (uint32_t j = 0; j < i; j++) {
1202 auto buffer = const_cast<native_handle_t*>(outBufferHandles[j]);
1203 native_handle_close(buffer);
1204 native_handle_delete(buffer);
1205 outBufferHandles[j] = nullptr;
1206 }
1207 }
1208 }
1209 }
1210 }
1211 *outStride = result.stride;
1212 // Release all the resources held by AllocationResult (specifically any remaining FDs)
1213 result = {};
1214 // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
1215 hardware::IPCThreadState::self()->flushCommands();
1216 return error;
1217 }
1218
Marissa Wall87c8ba72019-06-20 14:20:52 -07001219 auto ret = mAllocator->allocate(descriptor, bufferCount,
1220 [&](const auto& tmpError, const auto& tmpStride,
1221 const auto& tmpBuffers) {
1222 error = static_cast<status_t>(tmpError);
1223 if (tmpError != Error::NONE) {
1224 return;
1225 }
1226
Marissa Wallbfcf81f2019-11-27 10:36:29 -08001227 if (importBuffers) {
1228 for (uint32_t i = 0; i < bufferCount; i++) {
1229 error = mMapper.importBuffer(tmpBuffers[i],
1230 &outBufferHandles[i]);
1231 if (error != NO_ERROR) {
1232 for (uint32_t j = 0; j < i; j++) {
1233 mMapper.freeBuffer(outBufferHandles[j]);
1234 outBufferHandles[j] = nullptr;
1235 }
1236 return;
Marissa Wall87c8ba72019-06-20 14:20:52 -07001237 }
Marissa Wallbfcf81f2019-11-27 10:36:29 -08001238 }
1239 } else {
1240 for (uint32_t i = 0; i < bufferCount; i++) {
1241 outBufferHandles[i] = native_handle_clone(
1242 tmpBuffers[i].getNativeHandle());
1243 if (!outBufferHandles[i]) {
1244 for (uint32_t j = 0; j < i; j++) {
1245 auto buffer = const_cast<native_handle_t*>(
1246 outBufferHandles[j]);
1247 native_handle_close(buffer);
1248 native_handle_delete(buffer);
1249 outBufferHandles[j] = nullptr;
1250 }
1251 }
Marissa Wall87c8ba72019-06-20 14:20:52 -07001252 }
1253 }
1254 *outStride = tmpStride;
1255 });
1256
1257 // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
1258 hardware::IPCThreadState::self()->flushCommands();
1259
1260 return (ret.isOk()) ? error : static_cast<status_t>(kTransactionError);
1261}
1262
1263} // namespace android