blob: c3af996b138626f51849ac6e7b08a236ffd8933d [file] [log] [blame]
Marissa Wall87c8ba72019-06-20 14:20:52 -07001/*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Gralloc4"
18
John Reck614326b2022-01-11 15:49:54 -050019#include <aidl/android/hardware/graphics/allocator/AllocationError.h>
20#include <aidl/android/hardware/graphics/allocator/AllocationResult.h>
21#include <aidl/android/hardware/graphics/common/BufferUsage.h>
22#include <aidlcommonsupport/NativeHandle.h>
23#include <android/binder_enums.h>
24#include <android/binder_manager.h>
Charles Chen788b58b2023-02-13 18:02:10 +000025#include <cutils/android_filesystem_config.h>
26#include <cutils/multiuser.h>
Alec Mouri9c604e32022-03-18 22:47:44 +000027#include <gralloctypes/Gralloc4.h>
Marissa Wall87c8ba72019-06-20 14:20:52 -070028#include <hidl/ServiceManagement.h>
29#include <hwbinder/IPCThreadState.h>
30#include <ui/Gralloc4.h>
31
32#include <inttypes.h>
33#include <log/log.h>
34#pragma clang diagnostic push
35#pragma clang diagnostic ignored "-Wzero-length-array"
36#include <sync/sync.h>
37#pragma clang diagnostic pop
38
John Reck614326b2022-01-11 15:49:54 -050039using aidl::android::hardware::graphics::allocator::AllocationError;
40using aidl::android::hardware::graphics::allocator::AllocationResult;
Marissa Wall22b2de12019-12-02 18:11:43 -080041using aidl::android::hardware::graphics::common::ExtendableType;
42using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
43using aidl::android::hardware::graphics::common::StandardMetadataType;
44using android::hardware::hidl_vec;
Marissa Wall87c8ba72019-06-20 14:20:52 -070045using android::hardware::graphics::allocator::V4_0::IAllocator;
46using android::hardware::graphics::common::V1_2::BufferUsage;
Chris Forbes6c09ee72022-01-26 18:48:55 +130047using android::hardware::graphics::common::V1_2::PixelFormat;
Marissa Wall87c8ba72019-06-20 14:20:52 -070048using android::hardware::graphics::mapper::V4_0::BufferDescriptor;
49using android::hardware::graphics::mapper::V4_0::Error;
50using android::hardware::graphics::mapper::V4_0::IMapper;
John Reck614326b2022-01-11 15:49:54 -050051using AidlIAllocator = ::aidl::android::hardware::graphics::allocator::IAllocator;
52using AidlBufferUsage = ::aidl::android::hardware::graphics::common::BufferUsage;
Yichi Chenba40db52021-04-30 00:18:32 +080053using AidlDataspace = ::aidl::android::hardware::graphics::common::Dataspace;
John Reck614326b2022-01-11 15:49:54 -050054using AidlNativeHandle = ::aidl::android::hardware::common::NativeHandle;
Marissa Wall22b2de12019-12-02 18:11:43 -080055using BufferDump = android::hardware::graphics::mapper::V4_0::IMapper::BufferDump;
56using MetadataDump = android::hardware::graphics::mapper::V4_0::IMapper::MetadataDump;
57using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
58using MetadataTypeDescription =
59 android::hardware::graphics::mapper::V4_0::IMapper::MetadataTypeDescription;
Marissa Wall87c8ba72019-06-20 14:20:52 -070060
61namespace android {
62
63namespace {
64
65static constexpr Error kTransactionError = Error::NO_RESOURCES;
John Reck614326b2022-01-11 15:49:54 -050066static const auto kAidlAllocatorServiceName = AidlIAllocator::descriptor + std::string("/default");
Marissa Wall87c8ba72019-06-20 14:20:52 -070067
Robin Lee38b59412022-02-02 22:53:15 +010068// TODO(b/72323293, b/72703005): Remove these invalid bits from callers
69static constexpr uint64_t kRemovedUsageBits = static_cast<uint64_t>((1 << 10) | (1 << 13));
70
Marissa Wall87c8ba72019-06-20 14:20:52 -070071uint64_t getValidUsageBits() {
72 static const uint64_t validUsageBits = []() -> uint64_t {
73 uint64_t bits = 0;
74 for (const auto bit :
75 hardware::hidl_enum_range<hardware::graphics::common::V1_2::BufferUsage>()) {
76 bits = bits | bit;
77 }
78 return bits;
79 }();
Robin Lee38b59412022-02-02 22:53:15 +010080 return validUsageBits | kRemovedUsageBits;
Marissa Wall87c8ba72019-06-20 14:20:52 -070081}
82
John Reck614326b2022-01-11 15:49:54 -050083uint64_t getValidUsageBits41() {
84 static const uint64_t validUsageBits = []() -> uint64_t {
85 uint64_t bits = 0;
86 for (const auto bit : ndk::enum_range<AidlBufferUsage>{}) {
87 bits |= static_cast<int64_t>(bit);
88 }
89 return bits;
90 }();
91 return validUsageBits;
92}
93
Marissa Wall87c8ba72019-06-20 14:20:52 -070094static inline IMapper::Rect sGralloc4Rect(const Rect& rect) {
95 IMapper::Rect outRect{};
96 outRect.left = rect.left;
97 outRect.top = rect.top;
98 outRect.width = rect.width();
99 outRect.height = rect.height();
100 return outRect;
101}
Marissa Wall87c8ba72019-06-20 14:20:52 -0700102
John Reck614326b2022-01-11 15:49:54 -0500103// See if gralloc "4.1" is available.
104static bool hasIAllocatorAidl() {
105 // Avoid re-querying repeatedly for this information;
106 static bool sHasIAllocatorAidl = []() -> bool {
John Reck614326b2022-01-11 15:49:54 -0500107 if (__builtin_available(android 31, *)) {
108 return AServiceManager_isDeclared(kAidlAllocatorServiceName.c_str());
109 }
110 return false;
111 }();
112 return sHasIAllocatorAidl;
113}
114
John Recke0711382022-01-26 12:10:59 -0500115// Determines whether the passed info is compatible with the mapper.
116static status_t validateBufferDescriptorInfo(IMapper::BufferDescriptorInfo* descriptorInfo) {
117 uint64_t validUsageBits = getValidUsageBits();
118 if (hasIAllocatorAidl()) {
119 validUsageBits |= getValidUsageBits41();
120 }
121
122 if (descriptorInfo->usage & ~validUsageBits) {
123 ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64,
124 descriptorInfo->usage & ~validUsageBits);
125 return BAD_VALUE;
126 }
Chris Forbes6c09ee72022-01-26 18:48:55 +1300127
128 // Combinations that are only allowed with gralloc 4.1.
129 // Previous grallocs must be protected from this.
130 if (!hasIAllocatorAidl() &&
131 descriptorInfo->format != hardware::graphics::common::V1_2::PixelFormat::BLOB &&
132 descriptorInfo->usage & BufferUsage::GPU_DATA_BUFFER) {
133 ALOGE("non-BLOB pixel format with GPU_DATA_BUFFER usage is not supported prior to gralloc 4.1");
134 return BAD_VALUE;
135 }
136
John Recke0711382022-01-26 12:10:59 -0500137 return NO_ERROR;
138}
139
140static inline status_t sBufferDescriptorInfo(std::string name, uint32_t width, uint32_t height,
141 PixelFormat format, uint32_t layerCount,
142 uint64_t usage,
143 IMapper::BufferDescriptorInfo* outDescriptorInfo) {
144 outDescriptorInfo->name = name;
145 outDescriptorInfo->width = width;
146 outDescriptorInfo->height = height;
147 outDescriptorInfo->layerCount = layerCount;
148 outDescriptorInfo->format = static_cast<hardware::graphics::common::V1_2::PixelFormat>(format);
149 outDescriptorInfo->usage = usage;
150 outDescriptorInfo->reservedSize = 0;
151
152 return validateBufferDescriptorInfo(outDescriptorInfo);
153}
154
Marissa Wall87c8ba72019-06-20 14:20:52 -0700155} // anonymous namespace
156
157void Gralloc4Mapper::preload() {
158 android::hardware::preloadPassthroughService<IMapper>();
159}
160
161Gralloc4Mapper::Gralloc4Mapper() {
162 mMapper = IMapper::getService();
163 if (mMapper == nullptr) {
164 ALOGI("mapper 4.x is not supported");
165 return;
166 }
167 if (mMapper->isRemote()) {
168 LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
169 }
170}
171
172bool Gralloc4Mapper::isLoaded() const {
173 return mMapper != nullptr;
174}
175
Marissa Wall87c8ba72019-06-20 14:20:52 -0700176status_t Gralloc4Mapper::createDescriptor(void* bufferDescriptorInfo,
177 void* outBufferDescriptor) const {
178 IMapper::BufferDescriptorInfo* descriptorInfo =
179 static_cast<IMapper::BufferDescriptorInfo*>(bufferDescriptorInfo);
180 BufferDescriptor* outDescriptor = static_cast<BufferDescriptor*>(outBufferDescriptor);
181
182 status_t status = validateBufferDescriptorInfo(descriptorInfo);
183 if (status != NO_ERROR) {
184 return status;
185 }
186
187 Error error;
188 auto hidl_cb = [&](const auto& tmpError, const auto& tmpDescriptor) {
189 error = tmpError;
190 if (error != Error::NONE) {
191 return;
192 }
193 *outDescriptor = tmpDescriptor;
194 };
195
196 hardware::Return<void> ret = mMapper->createDescriptor(*descriptorInfo, hidl_cb);
197
198 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
199}
200
John Reck0ff95c92022-12-08 11:45:29 -0500201status_t Gralloc4Mapper::importBuffer(const native_handle_t* rawHandle,
Marissa Wall87c8ba72019-06-20 14:20:52 -0700202 buffer_handle_t* outBufferHandle) const {
203 Error error;
204 auto ret = mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
205 error = tmpError;
206 if (error != Error::NONE) {
207 return;
208 }
209 *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
210 });
211
212 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
213}
214
215void Gralloc4Mapper::freeBuffer(buffer_handle_t bufferHandle) const {
216 auto buffer = const_cast<native_handle_t*>(bufferHandle);
217 auto ret = mMapper->freeBuffer(buffer);
218
219 auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
220 ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d", buffer, error);
221}
222
223status_t Gralloc4Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
Marissa Wall22b2de12019-12-02 18:11:43 -0800224 uint32_t height, PixelFormat format,
Marissa Wall87c8ba72019-06-20 14:20:52 -0700225 uint32_t layerCount, uint64_t usage,
226 uint32_t stride) const {
227 IMapper::BufferDescriptorInfo descriptorInfo;
John Recke0711382022-01-26 12:10:59 -0500228 if (auto error = sBufferDescriptorInfo("validateBufferSize", width, height, format, layerCount,
229 usage, &descriptorInfo) != OK) {
230 return error;
231 }
Marissa Wall87c8ba72019-06-20 14:20:52 -0700232
233 auto buffer = const_cast<native_handle_t*>(bufferHandle);
234 auto ret = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
235
236 return static_cast<status_t>((ret.isOk()) ? static_cast<Error>(ret) : kTransactionError);
237}
238
239void Gralloc4Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t* outNumFds,
240 uint32_t* outNumInts) const {
241 *outNumFds = uint32_t(bufferHandle->numFds);
242 *outNumInts = uint32_t(bufferHandle->numInts);
243
244 Error error;
245 auto buffer = const_cast<native_handle_t*>(bufferHandle);
246 auto ret = mMapper->getTransportSize(buffer,
247 [&](const auto& tmpError, const auto& tmpNumFds,
248 const auto& tmpNumInts) {
249 error = tmpError;
250 if (error != Error::NONE) {
251 return;
252 }
253 *outNumFds = tmpNumFds;
254 *outNumInts = tmpNumInts;
255 });
256
257 error = (ret.isOk()) ? error : kTransactionError;
258
259 ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d", buffer, error);
260}
261
262status_t Gralloc4Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
263 int acquireFence, void** outData, int32_t* outBytesPerPixel,
264 int32_t* outBytesPerStride) const {
Marissa Wall22b2de12019-12-02 18:11:43 -0800265 std::vector<ui::PlaneLayout> planeLayouts;
266 status_t err = getPlaneLayouts(bufferHandle, &planeLayouts);
267
Valerie Hau3bb97912020-04-09 10:40:10 -0700268 if (err == NO_ERROR && !planeLayouts.empty()) {
Marissa Wall22b2de12019-12-02 18:11:43 -0800269 if (outBytesPerPixel) {
270 int32_t bitsPerPixel = planeLayouts.front().sampleIncrementInBits;
271 for (const auto& planeLayout : planeLayouts) {
272 if (bitsPerPixel != planeLayout.sampleIncrementInBits) {
273 bitsPerPixel = -1;
274 }
275 }
276 if (bitsPerPixel >= 0 && bitsPerPixel % 8 == 0) {
277 *outBytesPerPixel = bitsPerPixel / 8;
278 } else {
279 *outBytesPerPixel = -1;
280 }
281 }
282 if (outBytesPerStride) {
283 int32_t bytesPerStride = planeLayouts.front().strideInBytes;
284 for (const auto& planeLayout : planeLayouts) {
285 if (bytesPerStride != planeLayout.strideInBytes) {
286 bytesPerStride = -1;
287 }
288 }
289 if (bytesPerStride >= 0) {
290 *outBytesPerStride = bytesPerStride;
291 } else {
292 *outBytesPerStride = -1;
293 }
294 }
Marissa Wall20611c62019-11-05 15:06:24 -0800295 }
296
Marissa Wall87c8ba72019-06-20 14:20:52 -0700297 auto buffer = const_cast<native_handle_t*>(bufferHandle);
298
299 IMapper::Rect accessRegion = sGralloc4Rect(bounds);
300
301 // put acquireFence in a hidl_handle
302 hardware::hidl_handle acquireFenceHandle;
303 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
304 if (acquireFence >= 0) {
305 auto h = native_handle_init(acquireFenceStorage, 1, 0);
306 h->data[0] = acquireFence;
307 acquireFenceHandle = h;
308 }
309
310 Error error;
311 auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
Marissa Wall20611c62019-11-05 15:06:24 -0800312 [&](const auto& tmpError, const auto& tmpData) {
Marissa Wall87c8ba72019-06-20 14:20:52 -0700313 error = tmpError;
314 if (error != Error::NONE) {
315 return;
316 }
317 *outData = tmpData;
Marissa Wall87c8ba72019-06-20 14:20:52 -0700318 });
319
320 // we own acquireFence even on errors
321 if (acquireFence >= 0) {
322 close(acquireFence);
323 }
324
325 error = (ret.isOk()) ? error : kTransactionError;
326
327 ALOGW_IF(error != Error::NONE, "lock(%p, ...) failed: %d", bufferHandle, error);
328
329 return static_cast<status_t>(error);
330}
331
Marissa Wall22b2de12019-12-02 18:11:43 -0800332status_t Gralloc4Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
333 int acquireFence, android_ycbcr* outYcbcr) const {
334 if (!outYcbcr) {
335 return BAD_VALUE;
336 }
337
338 std::vector<ui::PlaneLayout> planeLayouts;
339 status_t error = getPlaneLayouts(bufferHandle, &planeLayouts);
340 if (error != NO_ERROR) {
341 return error;
342 }
343
344 void* data = nullptr;
345 error = lock(bufferHandle, usage, bounds, acquireFence, &data, nullptr, nullptr);
346 if (error != NO_ERROR) {
347 return error;
348 }
349
350 android_ycbcr ycbcr;
351
352 ycbcr.y = nullptr;
353 ycbcr.cb = nullptr;
354 ycbcr.cr = nullptr;
355 ycbcr.ystride = 0;
356 ycbcr.cstride = 0;
357 ycbcr.chroma_step = 0;
358
359 for (const auto& planeLayout : planeLayouts) {
360 for (const auto& planeLayoutComponent : planeLayout.components) {
361 if (!gralloc4::isStandardPlaneLayoutComponentType(planeLayoutComponent.type)) {
362 continue;
363 }
Marissa Wall22b2de12019-12-02 18:11:43 -0800364
Jason Macnak41209912022-02-16 14:44:44 -0800365 uint8_t* tmpData = static_cast<uint8_t*>(data) + planeLayout.offsetInBytes;
366
367 // Note that `offsetInBits` may not be a multiple of 8 for packed formats (e.g. P010)
368 // but we still want to point to the start of the first byte.
369 tmpData += (planeLayoutComponent.offsetInBits / 8);
370
Marissa Wall22b2de12019-12-02 18:11:43 -0800371 uint64_t sampleIncrementInBytes;
372
373 auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
374 switch (type) {
375 case PlaneLayoutComponentType::Y:
Jason Macnak41209912022-02-16 14:44:44 -0800376 if ((ycbcr.y != nullptr) || (planeLayout.sampleIncrementInBits % 8 != 0)) {
Marissa Wall22b2de12019-12-02 18:11:43 -0800377 unlock(bufferHandle);
378 return BAD_VALUE;
379 }
380 ycbcr.y = tmpData;
381 ycbcr.ystride = planeLayout.strideInBytes;
382 break;
383
384 case PlaneLayoutComponentType::CB:
385 case PlaneLayoutComponentType::CR:
386 if (planeLayout.sampleIncrementInBits % 8 != 0) {
387 unlock(bufferHandle);
388 return BAD_VALUE;
389 }
390
391 sampleIncrementInBytes = planeLayout.sampleIncrementInBits / 8;
Jason Macnak41209912022-02-16 14:44:44 -0800392 if ((sampleIncrementInBytes != 1) && (sampleIncrementInBytes != 2) &&
393 (sampleIncrementInBytes != 4)) {
Marissa Wall22b2de12019-12-02 18:11:43 -0800394 unlock(bufferHandle);
395 return BAD_VALUE;
396 }
397
398 if (ycbcr.cstride == 0 && ycbcr.chroma_step == 0) {
399 ycbcr.cstride = planeLayout.strideInBytes;
400 ycbcr.chroma_step = sampleIncrementInBytes;
401 } else {
402 if ((static_cast<int64_t>(ycbcr.cstride) != planeLayout.strideInBytes) ||
403 (ycbcr.chroma_step != sampleIncrementInBytes)) {
404 unlock(bufferHandle);
405 return BAD_VALUE;
406 }
407 }
408
409 if (type == PlaneLayoutComponentType::CB) {
410 if (ycbcr.cb != nullptr) {
411 unlock(bufferHandle);
412 return BAD_VALUE;
413 }
414 ycbcr.cb = tmpData;
415 } else {
416 if (ycbcr.cr != nullptr) {
417 unlock(bufferHandle);
418 return BAD_VALUE;
419 }
420 ycbcr.cr = tmpData;
421 }
422 break;
423 default:
424 break;
425 };
426 }
427 }
428
429 *outYcbcr = ycbcr;
Marissa Wall90df5852020-02-27 10:17:02 -0800430 return static_cast<status_t>(Error::NONE);
Marissa Wall87c8ba72019-06-20 14:20:52 -0700431}
432
433int Gralloc4Mapper::unlock(buffer_handle_t bufferHandle) const {
434 auto buffer = const_cast<native_handle_t*>(bufferHandle);
435
436 int releaseFence = -1;
437 Error error;
438 auto ret = mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
439 error = tmpError;
440 if (error != Error::NONE) {
441 return;
442 }
443
444 auto fenceHandle = tmpReleaseFence.getNativeHandle();
445 if (fenceHandle && fenceHandle->numFds == 1) {
446 int fd = dup(fenceHandle->data[0]);
447 if (fd >= 0) {
448 releaseFence = fd;
449 } else {
John Recke0711382022-01-26 12:10:59 -0500450 ALOGW("failed to dup unlock release fence");
Marissa Wall87c8ba72019-06-20 14:20:52 -0700451 sync_wait(fenceHandle->data[0], -1);
452 }
453 }
454 });
455
456 if (!ret.isOk()) {
457 error = kTransactionError;
458 }
459
460 if (error != Error::NONE) {
461 ALOGE("unlock(%p) failed with %d", buffer, error);
462 }
463
464 return releaseFence;
465}
466
Marissa Wall22b2de12019-12-02 18:11:43 -0800467status_t Gralloc4Mapper::isSupported(uint32_t width, uint32_t height, PixelFormat format,
Marissa Wall87c8ba72019-06-20 14:20:52 -0700468 uint32_t layerCount, uint64_t usage,
469 bool* outSupported) const {
470 IMapper::BufferDescriptorInfo descriptorInfo;
John Recke0711382022-01-26 12:10:59 -0500471 if (auto error = sBufferDescriptorInfo("isSupported", width, height, format, layerCount, usage,
472 &descriptorInfo) != OK) {
473 // Usage isn't known to the HAL or otherwise failed validation.
474 *outSupported = false;
475 return OK;
476 }
Marissa Wall87c8ba72019-06-20 14:20:52 -0700477
478 Error error;
479 auto ret = mMapper->isSupported(descriptorInfo,
480 [&](const auto& tmpError, const auto& tmpSupported) {
481 error = tmpError;
482 if (error != Error::NONE) {
483 return;
484 }
485 if (outSupported) {
486 *outSupported = tmpSupported;
487 }
488 });
489
490 if (!ret.isOk()) {
491 error = kTransactionError;
492 }
493
494 if (error != Error::NONE) {
495 ALOGE("isSupported(%u, %u, %d, %u, ...) failed with %d", width, height, format, layerCount,
496 error);
497 }
498
499 return static_cast<status_t>(error);
500}
501
Marissa Wall22b2de12019-12-02 18:11:43 -0800502template <class T>
503status_t Gralloc4Mapper::get(buffer_handle_t bufferHandle, const MetadataType& metadataType,
504 DecodeFunction<T> decodeFunction, T* outMetadata) const {
505 if (!outMetadata) {
506 return BAD_VALUE;
507 }
508
509 hidl_vec<uint8_t> vec;
510 Error error;
511 auto ret = mMapper->get(const_cast<native_handle_t*>(bufferHandle), metadataType,
512 [&](const auto& tmpError, const hidl_vec<uint8_t>& tmpVec) {
513 error = tmpError;
514 vec = tmpVec;
515 });
516
517 if (!ret.isOk()) {
518 error = kTransactionError;
519 }
520
521 if (error != Error::NONE) {
522 ALOGE("get(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
523 metadataType.value, error);
524 return static_cast<status_t>(error);
525 }
526
527 return decodeFunction(vec, outMetadata);
528}
529
Alec Mouri9c604e32022-03-18 22:47:44 +0000530template <class T>
531status_t Gralloc4Mapper::set(buffer_handle_t bufferHandle, const MetadataType& metadataType,
532 const T& metadata, EncodeFunction<T> encodeFunction) const {
533 hidl_vec<uint8_t> encodedMetadata;
534 if (const status_t status = encodeFunction(metadata, &encodedMetadata); status != OK) {
535 ALOGE("Encoding metadata(%s) failed with %d", metadataType.name.c_str(), status);
536 return status;
537 }
538 hidl_vec<uint8_t> vec;
539 auto ret =
540 mMapper->set(const_cast<native_handle_t*>(bufferHandle), metadataType, encodedMetadata);
541
542 const Error error = ret.withDefault(kTransactionError);
543 switch (error) {
544 case Error::BAD_DESCRIPTOR:
545 case Error::BAD_BUFFER:
546 case Error::BAD_VALUE:
547 case Error::NO_RESOURCES:
548 ALOGE("set(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
549 metadataType.value, error);
550 break;
551 // It is not an error to attempt to set metadata that a particular gralloc implementation
552 // happens to not support.
553 case Error::UNSUPPORTED:
554 case Error::NONE:
555 break;
556 }
557
558 return static_cast<status_t>(error);
559}
560
Marissa Wall22b2de12019-12-02 18:11:43 -0800561status_t Gralloc4Mapper::getBufferId(buffer_handle_t bufferHandle, uint64_t* outBufferId) const {
562 return get(bufferHandle, gralloc4::MetadataType_BufferId, gralloc4::decodeBufferId,
563 outBufferId);
564}
565
566status_t Gralloc4Mapper::getName(buffer_handle_t bufferHandle, std::string* outName) const {
567 return get(bufferHandle, gralloc4::MetadataType_Name, gralloc4::decodeName, outName);
568}
569
570status_t Gralloc4Mapper::getWidth(buffer_handle_t bufferHandle, uint64_t* outWidth) const {
571 return get(bufferHandle, gralloc4::MetadataType_Width, gralloc4::decodeWidth, outWidth);
572}
573
574status_t Gralloc4Mapper::getHeight(buffer_handle_t bufferHandle, uint64_t* outHeight) const {
575 return get(bufferHandle, gralloc4::MetadataType_Height, gralloc4::decodeHeight, outHeight);
576}
577
578status_t Gralloc4Mapper::getLayerCount(buffer_handle_t bufferHandle,
579 uint64_t* outLayerCount) const {
580 return get(bufferHandle, gralloc4::MetadataType_LayerCount, gralloc4::decodeLayerCount,
581 outLayerCount);
582}
583
584status_t Gralloc4Mapper::getPixelFormatRequested(buffer_handle_t bufferHandle,
585 ui::PixelFormat* outPixelFormatRequested) const {
586 return get(bufferHandle, gralloc4::MetadataType_PixelFormatRequested,
587 gralloc4::decodePixelFormatRequested, outPixelFormatRequested);
588}
589
590status_t Gralloc4Mapper::getPixelFormatFourCC(buffer_handle_t bufferHandle,
591 uint32_t* outPixelFormatFourCC) const {
592 return get(bufferHandle, gralloc4::MetadataType_PixelFormatFourCC,
593 gralloc4::decodePixelFormatFourCC, outPixelFormatFourCC);
594}
595
596status_t Gralloc4Mapper::getPixelFormatModifier(buffer_handle_t bufferHandle,
597 uint64_t* outPixelFormatModifier) const {
598 return get(bufferHandle, gralloc4::MetadataType_PixelFormatModifier,
599 gralloc4::decodePixelFormatModifier, outPixelFormatModifier);
600}
601
602status_t Gralloc4Mapper::getUsage(buffer_handle_t bufferHandle, uint64_t* outUsage) const {
603 return get(bufferHandle, gralloc4::MetadataType_Usage, gralloc4::decodeUsage, outUsage);
604}
605
606status_t Gralloc4Mapper::getAllocationSize(buffer_handle_t bufferHandle,
607 uint64_t* outAllocationSize) const {
608 return get(bufferHandle, gralloc4::MetadataType_AllocationSize, gralloc4::decodeAllocationSize,
609 outAllocationSize);
610}
611
612status_t Gralloc4Mapper::getProtectedContent(buffer_handle_t bufferHandle,
613 uint64_t* outProtectedContent) const {
614 return get(bufferHandle, gralloc4::MetadataType_ProtectedContent,
615 gralloc4::decodeProtectedContent, outProtectedContent);
616}
617
618status_t Gralloc4Mapper::getCompression(buffer_handle_t bufferHandle,
619 ExtendableType* outCompression) const {
620 return get(bufferHandle, gralloc4::MetadataType_Compression, gralloc4::decodeCompression,
621 outCompression);
622}
623
624status_t Gralloc4Mapper::getCompression(buffer_handle_t bufferHandle,
625 ui::Compression* outCompression) const {
626 if (!outCompression) {
627 return BAD_VALUE;
628 }
629 ExtendableType compression;
630 status_t error = getCompression(bufferHandle, &compression);
631 if (error) {
632 return error;
633 }
634 if (!gralloc4::isStandardCompression(compression)) {
635 return BAD_TYPE;
636 }
637 *outCompression = gralloc4::getStandardCompressionValue(compression);
638 return NO_ERROR;
639}
640
641status_t Gralloc4Mapper::getInterlaced(buffer_handle_t bufferHandle,
642 ExtendableType* outInterlaced) const {
643 return get(bufferHandle, gralloc4::MetadataType_Interlaced, gralloc4::decodeInterlaced,
644 outInterlaced);
645}
646
647status_t Gralloc4Mapper::getInterlaced(buffer_handle_t bufferHandle,
648 ui::Interlaced* outInterlaced) const {
649 if (!outInterlaced) {
650 return BAD_VALUE;
651 }
652 ExtendableType interlaced;
653 status_t error = getInterlaced(bufferHandle, &interlaced);
654 if (error) {
655 return error;
656 }
657 if (!gralloc4::isStandardInterlaced(interlaced)) {
658 return BAD_TYPE;
659 }
660 *outInterlaced = gralloc4::getStandardInterlacedValue(interlaced);
661 return NO_ERROR;
662}
663
664status_t Gralloc4Mapper::getChromaSiting(buffer_handle_t bufferHandle,
665 ExtendableType* outChromaSiting) const {
666 return get(bufferHandle, gralloc4::MetadataType_ChromaSiting, gralloc4::decodeChromaSiting,
667 outChromaSiting);
668}
669
670status_t Gralloc4Mapper::getChromaSiting(buffer_handle_t bufferHandle,
671 ui::ChromaSiting* outChromaSiting) const {
672 if (!outChromaSiting) {
673 return BAD_VALUE;
674 }
675 ExtendableType chromaSiting;
676 status_t error = getChromaSiting(bufferHandle, &chromaSiting);
677 if (error) {
678 return error;
679 }
680 if (!gralloc4::isStandardChromaSiting(chromaSiting)) {
681 return BAD_TYPE;
682 }
683 *outChromaSiting = gralloc4::getStandardChromaSitingValue(chromaSiting);
684 return NO_ERROR;
685}
686
687status_t Gralloc4Mapper::getPlaneLayouts(buffer_handle_t bufferHandle,
688 std::vector<ui::PlaneLayout>* outPlaneLayouts) const {
689 return get(bufferHandle, gralloc4::MetadataType_PlaneLayouts, gralloc4::decodePlaneLayouts,
690 outPlaneLayouts);
691}
692
693status_t Gralloc4Mapper::getDataspace(buffer_handle_t bufferHandle,
694 ui::Dataspace* outDataspace) const {
695 if (!outDataspace) {
696 return BAD_VALUE;
697 }
Yichi Chenba40db52021-04-30 00:18:32 +0800698 AidlDataspace dataspace;
Marissa Wall22b2de12019-12-02 18:11:43 -0800699 status_t error = get(bufferHandle, gralloc4::MetadataType_Dataspace, gralloc4::decodeDataspace,
700 &dataspace);
701 if (error) {
702 return error;
703 }
704
705 // Gralloc4 uses stable AIDL dataspace but the rest of the system still uses HIDL dataspace
706 *outDataspace = static_cast<ui::Dataspace>(dataspace);
707 return NO_ERROR;
708}
709
Alec Mouri9c604e32022-03-18 22:47:44 +0000710status_t Gralloc4Mapper::setDataspace(buffer_handle_t bufferHandle, ui::Dataspace dataspace) const {
711 return set(bufferHandle, gralloc4::MetadataType_Dataspace,
712 static_cast<aidl::android::hardware::graphics::common::Dataspace>(dataspace),
713 gralloc4::encodeDataspace);
714}
715
Marissa Wall22b2de12019-12-02 18:11:43 -0800716status_t Gralloc4Mapper::getBlendMode(buffer_handle_t bufferHandle,
717 ui::BlendMode* outBlendMode) const {
718 return get(bufferHandle, gralloc4::MetadataType_BlendMode, gralloc4::decodeBlendMode,
719 outBlendMode);
720}
721
Marissa Wallef785e12019-12-12 14:26:59 -0800722status_t Gralloc4Mapper::getSmpte2086(buffer_handle_t bufferHandle,
723 std::optional<ui::Smpte2086>* outSmpte2086) const {
724 return get(bufferHandle, gralloc4::MetadataType_Smpte2086, gralloc4::decodeSmpte2086,
725 outSmpte2086);
726}
727
Alec Mouri9c604e32022-03-18 22:47:44 +0000728status_t Gralloc4Mapper::setSmpte2086(buffer_handle_t bufferHandle,
729 std::optional<ui::Smpte2086> smpte2086) const {
730 return set(bufferHandle, gralloc4::MetadataType_Smpte2086, smpte2086,
731 gralloc4::encodeSmpte2086);
732}
733
Marissa Wallef785e12019-12-12 14:26:59 -0800734status_t Gralloc4Mapper::getCta861_3(buffer_handle_t bufferHandle,
735 std::optional<ui::Cta861_3>* outCta861_3) const {
736 return get(bufferHandle, gralloc4::MetadataType_Cta861_3, gralloc4::decodeCta861_3,
737 outCta861_3);
738}
739
Alec Mouri9c604e32022-03-18 22:47:44 +0000740status_t Gralloc4Mapper::setCta861_3(buffer_handle_t bufferHandle,
741 std::optional<ui::Cta861_3> cta861_3) const {
742 return set(bufferHandle, gralloc4::MetadataType_Cta861_3, cta861_3, gralloc4::encodeCta861_3);
743}
744
Marissa Wallef785e12019-12-12 14:26:59 -0800745status_t Gralloc4Mapper::getSmpte2094_40(
746 buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>>* outSmpte2094_40) const {
747 return get(bufferHandle, gralloc4::MetadataType_Smpte2094_40, gralloc4::decodeSmpte2094_40,
748 outSmpte2094_40);
749}
750
Alec Mouri9c604e32022-03-18 22:47:44 +0000751status_t Gralloc4Mapper::setSmpte2094_40(buffer_handle_t bufferHandle,
752 std::optional<std::vector<uint8_t>> smpte2094_40) const {
753 return set(bufferHandle, gralloc4::MetadataType_Smpte2094_40, smpte2094_40,
754 gralloc4::encodeSmpte2094_40);
755}
756
Alec Mouri332765e2021-10-06 16:38:12 -0700757status_t Gralloc4Mapper::getSmpte2094_10(
758 buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>>* outSmpte2094_10) const {
759 return get(bufferHandle, gralloc4::MetadataType_Smpte2094_10, gralloc4::decodeSmpte2094_10,
760 outSmpte2094_10);
761}
762
Alec Mouri9c604e32022-03-18 22:47:44 +0000763status_t Gralloc4Mapper::setSmpte2094_10(buffer_handle_t bufferHandle,
764 std::optional<std::vector<uint8_t>> smpte2094_10) const {
765 return set(bufferHandle, gralloc4::MetadataType_Smpte2094_10, smpte2094_10,
766 gralloc4::encodeSmpte2094_10);
767}
768
Marissa Wall22b2de12019-12-02 18:11:43 -0800769template <class T>
770status_t Gralloc4Mapper::getDefault(uint32_t width, uint32_t height, PixelFormat format,
771 uint32_t layerCount, uint64_t usage,
772 const MetadataType& metadataType,
773 DecodeFunction<T> decodeFunction, T* outMetadata) const {
774 if (!outMetadata) {
775 return BAD_VALUE;
776 }
777
778 IMapper::BufferDescriptorInfo descriptorInfo;
John Recke0711382022-01-26 12:10:59 -0500779 if (auto error = sBufferDescriptorInfo("getDefault", width, height, format, layerCount, usage,
780 &descriptorInfo) != OK) {
781 return error;
782 }
Marissa Wall22b2de12019-12-02 18:11:43 -0800783
784 hidl_vec<uint8_t> vec;
785 Error error;
786 auto ret = mMapper->getFromBufferDescriptorInfo(descriptorInfo, metadataType,
787 [&](const auto& tmpError,
788 const hidl_vec<uint8_t>& tmpVec) {
789 error = tmpError;
790 vec = tmpVec;
791 });
792
793 if (!ret.isOk()) {
794 error = kTransactionError;
795 }
796
797 if (error != Error::NONE) {
798 ALOGE("getDefault(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
799 metadataType.value, error);
800 return static_cast<status_t>(error);
801 }
802
803 return decodeFunction(vec, outMetadata);
804}
805
806status_t Gralloc4Mapper::getDefaultPixelFormatFourCC(uint32_t width, uint32_t height,
807 PixelFormat format, uint32_t layerCount,
808 uint64_t usage,
809 uint32_t* outPixelFormatFourCC) const {
810 return getDefault(width, height, format, layerCount, usage,
811 gralloc4::MetadataType_PixelFormatFourCC, gralloc4::decodePixelFormatFourCC,
812 outPixelFormatFourCC);
813}
814
815status_t Gralloc4Mapper::getDefaultPixelFormatModifier(uint32_t width, uint32_t height,
816 PixelFormat format, uint32_t layerCount,
817 uint64_t usage,
818 uint64_t* outPixelFormatModifier) const {
819 return getDefault(width, height, format, layerCount, usage,
820 gralloc4::MetadataType_PixelFormatModifier,
821 gralloc4::decodePixelFormatModifier, outPixelFormatModifier);
822}
823
824status_t Gralloc4Mapper::getDefaultAllocationSize(uint32_t width, uint32_t height,
825 PixelFormat format, uint32_t layerCount,
826 uint64_t usage,
827 uint64_t* outAllocationSize) const {
828 return getDefault(width, height, format, layerCount, usage,
829 gralloc4::MetadataType_AllocationSize, gralloc4::decodeAllocationSize,
830 outAllocationSize);
831}
832
833status_t Gralloc4Mapper::getDefaultProtectedContent(uint32_t width, uint32_t height,
834 PixelFormat format, uint32_t layerCount,
835 uint64_t usage,
836 uint64_t* outProtectedContent) const {
837 return getDefault(width, height, format, layerCount, usage,
838 gralloc4::MetadataType_ProtectedContent, gralloc4::decodeProtectedContent,
839 outProtectedContent);
840}
841
842status_t Gralloc4Mapper::getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
843 uint32_t layerCount, uint64_t usage,
844 ExtendableType* outCompression) const {
845 return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_Compression,
846 gralloc4::decodeCompression, outCompression);
847}
848
849status_t Gralloc4Mapper::getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
850 uint32_t layerCount, uint64_t usage,
851 ui::Compression* outCompression) const {
852 if (!outCompression) {
853 return BAD_VALUE;
854 }
855 ExtendableType compression;
856 status_t error = getDefaultCompression(width, height, format, layerCount, usage, &compression);
857 if (error) {
858 return error;
859 }
860 if (!gralloc4::isStandardCompression(compression)) {
861 return BAD_TYPE;
862 }
863 *outCompression = gralloc4::getStandardCompressionValue(compression);
864 return NO_ERROR;
865}
866
867status_t Gralloc4Mapper::getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
868 uint32_t layerCount, uint64_t usage,
869 ExtendableType* outInterlaced) const {
870 return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_Interlaced,
871 gralloc4::decodeInterlaced, outInterlaced);
872}
873
874status_t Gralloc4Mapper::getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
875 uint32_t layerCount, uint64_t usage,
876 ui::Interlaced* outInterlaced) const {
877 if (!outInterlaced) {
878 return BAD_VALUE;
879 }
880 ExtendableType interlaced;
881 status_t error = getDefaultInterlaced(width, height, format, layerCount, usage, &interlaced);
882 if (error) {
883 return error;
884 }
885 if (!gralloc4::isStandardInterlaced(interlaced)) {
886 return BAD_TYPE;
887 }
888 *outInterlaced = gralloc4::getStandardInterlacedValue(interlaced);
889 return NO_ERROR;
890}
891
892status_t Gralloc4Mapper::getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
893 uint32_t layerCount, uint64_t usage,
894 ExtendableType* outChromaSiting) const {
895 return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_ChromaSiting,
896 gralloc4::decodeChromaSiting, outChromaSiting);
897}
898
899status_t Gralloc4Mapper::getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
900 uint32_t layerCount, uint64_t usage,
901 ui::ChromaSiting* outChromaSiting) const {
902 if (!outChromaSiting) {
903 return BAD_VALUE;
904 }
905 ExtendableType chromaSiting;
906 status_t error =
907 getDefaultChromaSiting(width, height, format, layerCount, usage, &chromaSiting);
908 if (error) {
909 return error;
910 }
911 if (!gralloc4::isStandardChromaSiting(chromaSiting)) {
912 return BAD_TYPE;
913 }
914 *outChromaSiting = gralloc4::getStandardChromaSitingValue(chromaSiting);
915 return NO_ERROR;
916}
917
918status_t Gralloc4Mapper::getDefaultPlaneLayouts(
919 uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage,
920 std::vector<ui::PlaneLayout>* outPlaneLayouts) const {
921 return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_PlaneLayouts,
922 gralloc4::decodePlaneLayouts, outPlaneLayouts);
923}
924
925std::vector<MetadataTypeDescription> Gralloc4Mapper::listSupportedMetadataTypes() const {
926 hidl_vec<MetadataTypeDescription> descriptions;
927 Error error;
928 auto ret = mMapper->listSupportedMetadataTypes(
929 [&](const auto& tmpError, const auto& tmpDescriptions) {
930 error = tmpError;
931 descriptions = tmpDescriptions;
932 });
933
934 if (!ret.isOk()) {
935 error = kTransactionError;
936 }
937
938 if (error != Error::NONE) {
939 ALOGE("listSupportedMetadataType() failed with %d", error);
940 return {};
941 }
942
943 return static_cast<std::vector<MetadataTypeDescription>>(descriptions);
944}
945
946template <class T>
947status_t Gralloc4Mapper::metadataDumpHelper(const BufferDump& bufferDump,
948 StandardMetadataType metadataType,
949 DecodeFunction<T> decodeFunction, T* outT) const {
950 const auto& metadataDump = bufferDump.metadataDump;
951
952 auto itr =
953 std::find_if(metadataDump.begin(), metadataDump.end(),
954 [&](const MetadataDump& tmpMetadataDump) {
955 if (!gralloc4::isStandardMetadataType(tmpMetadataDump.metadataType)) {
956 return false;
957 }
958 return metadataType ==
959 gralloc4::getStandardMetadataTypeValue(
960 tmpMetadataDump.metadataType);
961 });
962 if (itr == metadataDump.end()) {
963 return BAD_VALUE;
964 }
965
966 return decodeFunction(itr->metadata, outT);
967}
968
969status_t Gralloc4Mapper::bufferDumpHelper(const BufferDump& bufferDump, std::ostringstream* outDump,
970 uint64_t* outAllocationSize, bool less) const {
971 uint64_t bufferId;
972 std::string name;
973 uint64_t width;
974 uint64_t height;
975 uint64_t layerCount;
976 ui::PixelFormat pixelFormatRequested;
977 uint32_t pixelFormatFourCC;
978 uint64_t pixelFormatModifier;
979 uint64_t usage;
Yichi Chenba40db52021-04-30 00:18:32 +0800980 AidlDataspace dataspace;
Marissa Wall22b2de12019-12-02 18:11:43 -0800981 uint64_t allocationSize;
982 uint64_t protectedContent;
983 ExtendableType compression;
984 ExtendableType interlaced;
985 ExtendableType chromaSiting;
986 std::vector<ui::PlaneLayout> planeLayouts;
987
988 status_t error = metadataDumpHelper(bufferDump, StandardMetadataType::BUFFER_ID,
989 gralloc4::decodeBufferId, &bufferId);
990 if (error != NO_ERROR) {
991 return error;
992 }
993 error = metadataDumpHelper(bufferDump, StandardMetadataType::NAME, gralloc4::decodeName, &name);
994 if (error != NO_ERROR) {
995 return error;
996 }
997 error = metadataDumpHelper(bufferDump, StandardMetadataType::WIDTH, gralloc4::decodeWidth,
998 &width);
999 if (error != NO_ERROR) {
1000 return error;
1001 }
1002 error = metadataDumpHelper(bufferDump, StandardMetadataType::HEIGHT, gralloc4::decodeHeight,
1003 &height);
1004 if (error != NO_ERROR) {
1005 return error;
1006 }
1007 error = metadataDumpHelper(bufferDump, StandardMetadataType::LAYER_COUNT,
1008 gralloc4::decodeLayerCount, &layerCount);
1009 if (error != NO_ERROR) {
1010 return error;
1011 }
1012 error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_REQUESTED,
1013 gralloc4::decodePixelFormatRequested, &pixelFormatRequested);
1014 if (error != NO_ERROR) {
1015 return error;
1016 }
1017 error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_FOURCC,
1018 gralloc4::decodePixelFormatFourCC, &pixelFormatFourCC);
1019 if (error != NO_ERROR) {
1020 return error;
1021 }
1022 error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_MODIFIER,
1023 gralloc4::decodePixelFormatModifier, &pixelFormatModifier);
1024 if (error != NO_ERROR) {
1025 return error;
1026 }
1027 error = metadataDumpHelper(bufferDump, StandardMetadataType::USAGE, gralloc4::decodeUsage,
1028 &usage);
1029 if (error != NO_ERROR) {
1030 return error;
1031 }
Yichi Chenba40db52021-04-30 00:18:32 +08001032 error = metadataDumpHelper(bufferDump, StandardMetadataType::DATASPACE,
1033 gralloc4::decodeDataspace, &dataspace);
1034 if (error != NO_ERROR) {
1035 return error;
1036 }
Marissa Wall22b2de12019-12-02 18:11:43 -08001037 error = metadataDumpHelper(bufferDump, StandardMetadataType::ALLOCATION_SIZE,
1038 gralloc4::decodeAllocationSize, &allocationSize);
1039 if (error != NO_ERROR) {
1040 return error;
1041 }
1042 error = metadataDumpHelper(bufferDump, StandardMetadataType::PROTECTED_CONTENT,
1043 gralloc4::decodeProtectedContent, &protectedContent);
1044 if (error != NO_ERROR) {
1045 return error;
1046 }
1047 error = metadataDumpHelper(bufferDump, StandardMetadataType::COMPRESSION,
1048 gralloc4::decodeCompression, &compression);
1049 if (error != NO_ERROR) {
1050 return error;
1051 }
1052 error = metadataDumpHelper(bufferDump, StandardMetadataType::INTERLACED,
1053 gralloc4::decodeInterlaced, &interlaced);
1054 if (error != NO_ERROR) {
1055 return error;
1056 }
1057 error = metadataDumpHelper(bufferDump, StandardMetadataType::CHROMA_SITING,
1058 gralloc4::decodeChromaSiting, &chromaSiting);
1059 if (error != NO_ERROR) {
1060 return error;
1061 }
1062 error = metadataDumpHelper(bufferDump, StandardMetadataType::PLANE_LAYOUTS,
1063 gralloc4::decodePlaneLayouts, &planeLayouts);
1064 if (error != NO_ERROR) {
1065 return error;
1066 }
1067
1068 if (outAllocationSize) {
1069 *outAllocationSize = allocationSize;
1070 }
1071 double allocationSizeKiB = static_cast<double>(allocationSize) / 1024;
1072
Alec Mouri04511ef2022-01-06 12:57:12 -08001073 *outDump << "+ name:" << name << ", id:" << bufferId << ", size:" << std::fixed
1074 << allocationSizeKiB << "KiB, w/h:" << width << "x" << height << ", usage: 0x"
1075 << std::hex << usage << std::dec
1076 << ", req fmt:" << static_cast<int32_t>(pixelFormatRequested)
Marissa Wall22b2de12019-12-02 18:11:43 -08001077 << ", fourcc/mod:" << pixelFormatFourCC << "/" << pixelFormatModifier
Yichi Chen6de5b582021-09-13 20:00:52 +08001078 << ", dataspace: 0x" << std::hex << static_cast<uint32_t>(dataspace) << std::dec
Marissa Wall22b2de12019-12-02 18:11:43 -08001079 << ", compressed: ";
1080
1081 if (less) {
1082 bool isCompressed = !gralloc4::isStandardCompression(compression) ||
1083 (gralloc4::getStandardCompressionValue(compression) != ui::Compression::NONE);
1084 *outDump << std::boolalpha << isCompressed << "\n";
1085 } else {
1086 *outDump << gralloc4::getCompressionName(compression) << "\n";
1087 }
1088
1089 bool firstPlane = true;
1090 for (const auto& planeLayout : planeLayouts) {
1091 if (firstPlane) {
1092 firstPlane = false;
1093 *outDump << "\tplanes: ";
1094 } else {
1095 *outDump << "\t ";
1096 }
1097
1098 for (size_t i = 0; i < planeLayout.components.size(); i++) {
1099 const auto& planeLayoutComponent = planeLayout.components[i];
1100 *outDump << gralloc4::getPlaneLayoutComponentTypeName(planeLayoutComponent.type);
1101 if (i < planeLayout.components.size() - 1) {
1102 *outDump << "/";
1103 } else {
1104 *outDump << ":\t";
1105 }
1106 }
1107 *outDump << " w/h:" << planeLayout.widthInSamples << "x" << planeLayout.heightInSamples
1108 << ", stride:" << planeLayout.strideInBytes
1109 << " bytes, size:" << planeLayout.totalSizeInBytes;
1110 if (!less) {
1111 *outDump << ", inc:" << planeLayout.sampleIncrementInBits
1112 << " bits, subsampling w/h:" << planeLayout.horizontalSubsampling << "x"
1113 << planeLayout.verticalSubsampling;
1114 }
1115 *outDump << "\n";
1116 }
1117
1118 if (!less) {
1119 *outDump << "\tlayer cnt: " << layerCount << ", protected content: " << protectedContent
1120 << ", interlaced: " << gralloc4::getInterlacedName(interlaced)
1121 << ", chroma siting:" << gralloc4::getChromaSitingName(chromaSiting) << "\n";
1122 }
1123
1124 return NO_ERROR;
1125}
1126
1127std::string Gralloc4Mapper::dumpBuffer(buffer_handle_t bufferHandle, bool less) const {
1128 auto buffer = const_cast<native_handle_t*>(bufferHandle);
1129
1130 BufferDump bufferDump;
1131 Error error;
1132 auto ret = mMapper->dumpBuffer(buffer, [&](const auto& tmpError, const auto& tmpBufferDump) {
1133 error = tmpError;
1134 bufferDump = tmpBufferDump;
1135 });
1136
1137 if (!ret.isOk()) {
1138 error = kTransactionError;
1139 }
1140
1141 if (error != Error::NONE) {
1142 ALOGE("dumpBuffer() failed with %d", error);
1143 return "";
1144 }
1145
1146 std::ostringstream stream;
1147 stream.precision(2);
1148
1149 status_t err = bufferDumpHelper(bufferDump, &stream, nullptr, less);
1150 if (err != NO_ERROR) {
1151 ALOGE("bufferDumpHelper() failed with %d", err);
1152 return "";
1153 }
1154
1155 return stream.str();
1156}
1157
1158std::string Gralloc4Mapper::dumpBuffers(bool less) const {
1159 hidl_vec<BufferDump> bufferDumps;
1160 Error error;
1161 auto ret = mMapper->dumpBuffers([&](const auto& tmpError, const auto& tmpBufferDump) {
1162 error = tmpError;
1163 bufferDumps = tmpBufferDump;
1164 });
1165
1166 if (!ret.isOk()) {
1167 error = kTransactionError;
1168 }
1169
1170 if (error != Error::NONE) {
1171 ALOGE("dumpBuffer() failed with %d", error);
1172 return "";
1173 }
1174
1175 uint64_t totalAllocationSize = 0;
1176 std::ostringstream stream;
1177 stream.precision(2);
1178
1179 stream << "Imported gralloc buffers:\n";
1180
1181 for (const auto& bufferDump : bufferDumps) {
1182 uint64_t allocationSize = 0;
1183 status_t err = bufferDumpHelper(bufferDump, &stream, &allocationSize, less);
1184 if (err != NO_ERROR) {
1185 ALOGE("bufferDumpHelper() failed with %d", err);
1186 return "";
1187 }
1188 totalAllocationSize += allocationSize;
1189 }
1190
1191 double totalAllocationSizeKiB = static_cast<double>(totalAllocationSize) / 1024;
1192 stream << "Total imported by gralloc: " << totalAllocationSizeKiB << "KiB\n";
1193 return stream.str();
1194}
1195
Marissa Wall87c8ba72019-06-20 14:20:52 -07001196Gralloc4Allocator::Gralloc4Allocator(const Gralloc4Mapper& mapper) : mMapper(mapper) {
1197 mAllocator = IAllocator::getService();
John Reck614326b2022-01-11 15:49:54 -05001198 if (__builtin_available(android 31, *)) {
1199 if (hasIAllocatorAidl()) {
Charles Chen788b58b2023-02-13 18:02:10 +00001200 // TODO(b/269517338): Perform the isolated checking for this in service manager instead.
1201 uid_t aid = multiuser_get_app_id(getuid());
1202 if (aid >= AID_ISOLATED_START && aid <= AID_ISOLATED_END) {
1203 mAidlAllocator = AidlIAllocator::fromBinder(ndk::SpAIBinder(
1204 AServiceManager_getService(kAidlAllocatorServiceName.c_str())));
1205 } else {
1206 mAidlAllocator = AidlIAllocator::fromBinder(ndk::SpAIBinder(
1207 AServiceManager_waitForService(kAidlAllocatorServiceName.c_str())));
1208 }
John Reck614326b2022-01-11 15:49:54 -05001209 ALOGE_IF(!mAidlAllocator, "AIDL IAllocator declared but failed to get service");
1210 }
1211 }
Devin Mooree401e882022-04-11 22:41:58 +00001212 if (mAllocator == nullptr && mAidlAllocator == nullptr) {
1213 ALOGW("allocator 4.x is not supported");
1214 return;
1215 }
Marissa Wall87c8ba72019-06-20 14:20:52 -07001216}
1217
1218bool Gralloc4Allocator::isLoaded() const {
Devin Mooree401e882022-04-11 22:41:58 +00001219 return mAllocator != nullptr || mAidlAllocator != nullptr;
Marissa Wall87c8ba72019-06-20 14:20:52 -07001220}
1221
Marissa Wall22b2de12019-12-02 18:11:43 -08001222std::string Gralloc4Allocator::dumpDebugInfo(bool less) const {
1223 return mMapper.dumpBuffers(less);
Marissa Wall87c8ba72019-06-20 14:20:52 -07001224}
1225
Marissa Wall22b2de12019-12-02 18:11:43 -08001226status_t Gralloc4Allocator::allocate(std::string requestorName, uint32_t width, uint32_t height,
1227 android::PixelFormat format, uint32_t layerCount,
1228 uint64_t usage, uint32_t bufferCount, uint32_t* outStride,
1229 buffer_handle_t* outBufferHandles, bool importBuffers) const {
Marissa Wall87c8ba72019-06-20 14:20:52 -07001230 IMapper::BufferDescriptorInfo descriptorInfo;
John Recke0711382022-01-26 12:10:59 -05001231 if (auto error = sBufferDescriptorInfo(requestorName, width, height, format, layerCount, usage,
1232 &descriptorInfo) != OK) {
1233 return error;
1234 }
Marissa Wall87c8ba72019-06-20 14:20:52 -07001235
1236 BufferDescriptor descriptor;
1237 status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),
1238 static_cast<void*>(&descriptor));
1239 if (error != NO_ERROR) {
1240 return error;
1241 }
1242
John Reck614326b2022-01-11 15:49:54 -05001243 if (mAidlAllocator) {
1244 AllocationResult result;
John Reck0ff95c92022-12-08 11:45:29 -05001245#pragma clang diagnostic push
1246#pragma clang diagnostic ignored "-Wdeprecated-declarations"
John Reck614326b2022-01-11 15:49:54 -05001247 auto status = mAidlAllocator->allocate(descriptor, bufferCount, &result);
John Reck0ff95c92022-12-08 11:45:29 -05001248#pragma clang diagnostic pop // deprecation
John Reck614326b2022-01-11 15:49:54 -05001249 if (!status.isOk()) {
1250 error = status.getExceptionCode();
1251 if (error == EX_SERVICE_SPECIFIC) {
1252 error = status.getServiceSpecificError();
1253 }
1254 if (error == OK) {
1255 error = UNKNOWN_ERROR;
1256 }
1257 } else {
1258 if (importBuffers) {
1259 for (uint32_t i = 0; i < bufferCount; i++) {
Christopher Ferris14ec0802022-04-22 13:23:43 -07001260 auto handle = makeFromAidl(result.buffers[i]);
1261 error = mMapper.importBuffer(handle, &outBufferHandles[i]);
1262 native_handle_delete(handle);
John Reck614326b2022-01-11 15:49:54 -05001263 if (error != NO_ERROR) {
1264 for (uint32_t j = 0; j < i; j++) {
1265 mMapper.freeBuffer(outBufferHandles[j]);
1266 outBufferHandles[j] = nullptr;
1267 }
1268 break;
1269 }
1270 }
1271 } else {
1272 for (uint32_t i = 0; i < bufferCount; i++) {
1273 outBufferHandles[i] = dupFromAidl(result.buffers[i]);
1274 if (!outBufferHandles[i]) {
1275 for (uint32_t j = 0; j < i; j++) {
1276 auto buffer = const_cast<native_handle_t*>(outBufferHandles[j]);
1277 native_handle_close(buffer);
1278 native_handle_delete(buffer);
1279 outBufferHandles[j] = nullptr;
1280 }
1281 }
1282 }
1283 }
1284 }
1285 *outStride = result.stride;
1286 // Release all the resources held by AllocationResult (specifically any remaining FDs)
1287 result = {};
1288 // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
1289 hardware::IPCThreadState::self()->flushCommands();
1290 return error;
1291 }
1292
Marissa Wall87c8ba72019-06-20 14:20:52 -07001293 auto ret = mAllocator->allocate(descriptor, bufferCount,
1294 [&](const auto& tmpError, const auto& tmpStride,
1295 const auto& tmpBuffers) {
1296 error = static_cast<status_t>(tmpError);
1297 if (tmpError != Error::NONE) {
1298 return;
1299 }
1300
Marissa Wallbfcf81f2019-11-27 10:36:29 -08001301 if (importBuffers) {
1302 for (uint32_t i = 0; i < bufferCount; i++) {
1303 error = mMapper.importBuffer(tmpBuffers[i],
1304 &outBufferHandles[i]);
1305 if (error != NO_ERROR) {
1306 for (uint32_t j = 0; j < i; j++) {
1307 mMapper.freeBuffer(outBufferHandles[j]);
1308 outBufferHandles[j] = nullptr;
1309 }
1310 return;
Marissa Wall87c8ba72019-06-20 14:20:52 -07001311 }
Marissa Wallbfcf81f2019-11-27 10:36:29 -08001312 }
1313 } else {
1314 for (uint32_t i = 0; i < bufferCount; i++) {
1315 outBufferHandles[i] = native_handle_clone(
1316 tmpBuffers[i].getNativeHandle());
1317 if (!outBufferHandles[i]) {
1318 for (uint32_t j = 0; j < i; j++) {
1319 auto buffer = const_cast<native_handle_t*>(
1320 outBufferHandles[j]);
1321 native_handle_close(buffer);
1322 native_handle_delete(buffer);
1323 outBufferHandles[j] = nullptr;
1324 }
1325 }
Marissa Wall87c8ba72019-06-20 14:20:52 -07001326 }
1327 }
1328 *outStride = tmpStride;
1329 });
1330
1331 // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
1332 hardware::IPCThreadState::self()->flushCommands();
1333
1334 return (ret.isOk()) ? error : static_cast<status_t>(kTransactionError);
1335}
1336
1337} // namespace android