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