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