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