blob: 123bef4a4fd4fea94e29a8d2627ec1b83b58541a [file] [log] [blame]
John Reck0ff95c92022-12-08 11:45:29 -05001/*
2 * Copyright (C) 2022 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 "Gralloc5"
18#define ATRACE_TAG ATRACE_TAG_GRAPHICS
19
20#include <ui/Gralloc5.h>
21
22#include <aidlcommonsupport/NativeHandle.h>
23#include <android/binder_manager.h>
24#include <android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h>
25#include <binder/IPCThreadState.h>
26#include <dlfcn.h>
27#include <ui/FatVector.h>
28#include <vndksupport/linker.h>
29
30using namespace aidl::android::hardware::graphics::allocator;
31using namespace aidl::android::hardware::graphics::common;
32using namespace ::android::hardware::graphics::mapper;
33
34namespace android {
35
36static const auto kIAllocatorServiceName = IAllocator::descriptor + std::string("/default");
37static const auto kIAllocatorMinimumVersion = 2;
38
39// TODO(b/72323293, b/72703005): Remove these invalid bits from callers
40static constexpr uint64_t kRemovedUsageBits = static_cast<uint64_t>((1 << 10) | (1 << 13));
41
42typedef AIMapper_Error (*AIMapper_loadIMapperFn)(AIMapper *_Nullable *_Nonnull outImplementation);
43
44struct Gralloc5 {
45 std::shared_ptr<IAllocator> allocator;
46 AIMapper *mapper = nullptr;
47};
48
49static std::shared_ptr<IAllocator> waitForAllocator() {
50 if (__builtin_available(android 31, *)) {
51 if (!AServiceManager_isDeclared(kIAllocatorServiceName.c_str())) {
52 return nullptr;
53 }
54 auto allocator = IAllocator::fromBinder(
55 ndk::SpAIBinder(AServiceManager_waitForService(kIAllocatorServiceName.c_str())));
56 if (!allocator) {
57 ALOGE("AIDL IAllocator declared but failed to get service");
58 return nullptr;
59 }
60
61 int32_t version = 0;
62 if (!allocator->getInterfaceVersion(&version).isOk()) {
63 ALOGE("Failed to query interface version");
64 return nullptr;
65 }
66 if (version < kIAllocatorMinimumVersion) {
67 return nullptr;
68 }
69 return allocator;
70 } else {
71 // TODO: LOG_ALWAYS_FATAL("libui is not backwards compatible");
72 return nullptr;
73 }
74}
75
76static void *loadIMapperLibrary() {
77 static void *imapperLibrary = []() -> void * {
78 auto allocator = waitForAllocator();
79 std::string mapperSuffix;
80 auto status = allocator->getIMapperLibrarySuffix(&mapperSuffix);
81 if (!status.isOk()) {
82 ALOGE("Failed to get IMapper library suffix");
83 return nullptr;
84 }
85
Jooyung Han75fc06f2024-02-03 03:56:59 +090086 void* so = nullptr;
87 // TODO(b/322384429) switch this to __ANDROID_API_V__ when V is finalized
88 // TODO(b/302113279) use __ANDROID_VENDOR_API__ for vendor variant
89 if (__builtin_available(android __ANDROID_API_FUTURE__, *)) {
90 so = AServiceManager_openDeclaredPassthroughHal("mapper", mapperSuffix.c_str(),
91 RTLD_LOCAL | RTLD_NOW);
92 } else {
93 std::string lib_name = "mapper." + mapperSuffix + ".so";
94 so = android_load_sphal_library(lib_name.c_str(), RTLD_LOCAL | RTLD_NOW);
95 }
John Reck0ff95c92022-12-08 11:45:29 -050096 if (!so) {
Jooyung Han75fc06f2024-02-03 03:56:59 +090097 ALOGE("Failed to load mapper.%s.so", mapperSuffix.c_str());
John Reck0ff95c92022-12-08 11:45:29 -050098 }
99 return so;
100 }();
101 return imapperLibrary;
102}
103
104static const Gralloc5 &getInstance() {
105 static Gralloc5 instance = []() {
106 auto allocator = waitForAllocator();
107 if (!allocator) {
108 return Gralloc5{};
109 }
110 void *so = loadIMapperLibrary();
111 if (!so) {
112 return Gralloc5{};
113 }
114 auto loadIMapper = (AIMapper_loadIMapperFn)dlsym(so, "AIMapper_loadIMapper");
115 AIMapper *mapper = nullptr;
116 AIMapper_Error error = loadIMapper(&mapper);
117 if (error != AIMAPPER_ERROR_NONE) {
118 ALOGE("AIMapper_loadIMapper failed %d", error);
119 return Gralloc5{};
120 }
121 return Gralloc5{std::move(allocator), mapper};
122 }();
123 return instance;
124}
125
126template <StandardMetadataType T>
127static auto getStandardMetadata(AIMapper *mapper, buffer_handle_t bufferHandle)
128 -> decltype(StandardMetadata<T>::value::decode(nullptr, 0)) {
129 using Value = typename StandardMetadata<T>::value;
130 // TODO: Tune for common-case better
131 FatVector<uint8_t, 128> buffer;
132 int32_t sizeRequired = mapper->v5.getStandardMetadata(bufferHandle, static_cast<int64_t>(T),
133 buffer.data(), buffer.size());
134 if (sizeRequired < 0) {
135 ALOGW_IF(-AIMAPPER_ERROR_UNSUPPORTED != sizeRequired,
136 "Unexpected error %d from valid getStandardMetadata call", -sizeRequired);
137 return std::nullopt;
138 }
139 if ((size_t)sizeRequired > buffer.size()) {
140 buffer.resize(sizeRequired);
141 sizeRequired = mapper->v5.getStandardMetadata(bufferHandle, static_cast<int64_t>(T),
142 buffer.data(), buffer.size());
143 }
144 if (sizeRequired < 0 || (size_t)sizeRequired > buffer.size()) {
145 ALOGW("getStandardMetadata failed, received %d with buffer size %zd", sizeRequired,
146 buffer.size());
147 // Generate a fail type
148 return std::nullopt;
149 }
150 return Value::decode(buffer.data(), sizeRequired);
151}
152
153template <StandardMetadataType T>
154static AIMapper_Error setStandardMetadata(AIMapper *mapper, buffer_handle_t bufferHandle,
155 const typename StandardMetadata<T>::value_type &value) {
156 using Value = typename StandardMetadata<T>::value;
157 int32_t sizeRequired = Value::encode(value, nullptr, 0);
158 if (sizeRequired < 0) {
159 ALOGW("Failed to calculate required size");
160 return static_cast<AIMapper_Error>(-sizeRequired);
161 }
162 FatVector<uint8_t, 128> buffer;
163 buffer.resize(sizeRequired);
164 sizeRequired = Value::encode(value, buffer.data(), buffer.size());
165 if (sizeRequired < 0 || (size_t)sizeRequired > buffer.size()) {
166 ALOGW("Failed to encode with calculated size %d; buffer size %zd", sizeRequired,
167 buffer.size());
168 return static_cast<AIMapper_Error>(-sizeRequired);
169 }
170 return mapper->v5.setStandardMetadata(bufferHandle, static_cast<int64_t>(T), buffer.data(),
171 sizeRequired);
172}
173
174Gralloc5Allocator::Gralloc5Allocator(const Gralloc5Mapper &mapper) : mMapper(mapper) {
175 mAllocator = getInstance().allocator;
176}
177
178bool Gralloc5Allocator::isLoaded() const {
179 return mAllocator != nullptr;
180}
181
182static uint64_t getValidUsageBits() {
183 static const uint64_t validUsageBits = []() -> uint64_t {
184 uint64_t bits = 0;
185 for (const auto bit : ndk::enum_range<BufferUsage>{}) {
186 bits |= static_cast<int64_t>(bit);
187 }
188 return bits;
189 }();
190 return validUsageBits | kRemovedUsageBits;
191}
192
193static std::optional<BufferDescriptorInfo> makeDescriptor(std::string requestorName, uint32_t width,
194 uint32_t height, PixelFormat format,
195 uint32_t layerCount, uint64_t usage) {
196 uint64_t validUsageBits = getValidUsageBits();
197 if (usage & ~validUsageBits) {
198 ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64, usage & ~validUsageBits);
199 return std::nullopt;
200 }
201
202 BufferDescriptorInfo descriptorInfo{
203 .width = static_cast<int32_t>(width),
204 .height = static_cast<int32_t>(height),
205 .layerCount = static_cast<int32_t>(layerCount),
206 .format = static_cast<::aidl::android::hardware::graphics::common::PixelFormat>(format),
207 .usage = static_cast<BufferUsage>(usage),
208 };
209 auto nameLength = std::min(requestorName.length(), descriptorInfo.name.size() - 1);
210 memcpy(descriptorInfo.name.data(), requestorName.data(), nameLength);
211 requestorName.data()[nameLength] = 0;
212 return descriptorInfo;
213}
214
215std::string Gralloc5Allocator::dumpDebugInfo(bool less) const {
216 return mMapper.dumpBuffers(less);
217}
218
219status_t Gralloc5Allocator::allocate(std::string requestorName, uint32_t width, uint32_t height,
220 android::PixelFormat format, uint32_t layerCount,
221 uint64_t usage, uint32_t bufferCount, uint32_t *outStride,
222 buffer_handle_t *outBufferHandles, bool importBuffers) const {
223 auto descriptorInfo = makeDescriptor(requestorName, width, height, format, layerCount, usage);
224 if (!descriptorInfo) {
225 return BAD_VALUE;
226 }
227
228 AllocationResult result;
229 auto status = mAllocator->allocate2(*descriptorInfo, bufferCount, &result);
230 if (!status.isOk()) {
231 auto error = status.getExceptionCode();
232 if (error == EX_SERVICE_SPECIFIC) {
233 error = status.getServiceSpecificError();
234 }
235 if (error == OK) {
236 error = UNKNOWN_ERROR;
237 }
238 return error;
239 }
240
241 if (importBuffers) {
242 for (uint32_t i = 0; i < bufferCount; i++) {
243 auto handle = makeFromAidl(result.buffers[i]);
244 auto error = mMapper.importBuffer(handle, &outBufferHandles[i]);
245 native_handle_delete(handle);
246 if (error != NO_ERROR) {
247 for (uint32_t j = 0; j < i; j++) {
248 mMapper.freeBuffer(outBufferHandles[j]);
249 outBufferHandles[j] = nullptr;
250 }
251 return error;
252 }
253 }
254 } else {
255 for (uint32_t i = 0; i < bufferCount; i++) {
256 outBufferHandles[i] = dupFromAidl(result.buffers[i]);
257 if (!outBufferHandles[i]) {
258 for (uint32_t j = 0; j < i; j++) {
259 auto buffer = const_cast<native_handle_t *>(outBufferHandles[j]);
260 native_handle_close(buffer);
261 native_handle_delete(buffer);
262 outBufferHandles[j] = nullptr;
263 }
264 return NO_MEMORY;
265 }
266 }
267 }
268
269 *outStride = result.stride;
270
271 // Release all the resources held by AllocationResult (specifically any remaining FDs)
272 result = {};
273 // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
274 // TODO: Re-enable this at some point if it's necessary. We can't do it now because libui
275 // is marked apex_available (b/214400477) and libbinder isn't (which of course is correct)
276 // IPCThreadState::self()->flushCommands();
277
278 return OK;
279}
280
281void Gralloc5Mapper::preload() {
282 // TODO(b/261858155): Implement. We can't bounce off of IAllocator for this because zygote can't
283 // use binder. So when an alternate strategy of retrieving the library prefix is available,
284 // use that here.
285}
286
287Gralloc5Mapper::Gralloc5Mapper() {
288 mMapper = getInstance().mapper;
289}
290
291bool Gralloc5Mapper::isLoaded() const {
292 return mMapper != nullptr && mMapper->version >= AIMAPPER_VERSION_5;
293}
294
295std::string Gralloc5Mapper::dumpBuffer(buffer_handle_t bufferHandle, bool less) const {
296 // TODO(b/261858392): Implement
297 (void)bufferHandle;
298 (void)less;
299 return {};
300}
301
302std::string Gralloc5Mapper::dumpBuffers(bool less) const {
303 // TODO(b/261858392): Implement
304 (void)less;
305 return {};
306}
307
308status_t Gralloc5Mapper::importBuffer(const native_handle_t *rawHandle,
309 buffer_handle_t *outBufferHandle) const {
310 return mMapper->v5.importBuffer(rawHandle, outBufferHandle);
311}
312
313void Gralloc5Mapper::freeBuffer(buffer_handle_t bufferHandle) const {
314 mMapper->v5.freeBuffer(bufferHandle);
315}
316
317status_t Gralloc5Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
318 uint32_t height, PixelFormat format,
319 uint32_t layerCount, uint64_t usage,
320 uint32_t stride) const {
321 {
322 auto value = getStandardMetadata<StandardMetadataType::WIDTH>(mMapper, bufferHandle);
323 if (width != value) {
324 ALOGW("Width didn't match, expected %d got %" PRId64, width, value.value_or(-1));
325 return BAD_VALUE;
326 }
327 }
328 {
329 auto value = getStandardMetadata<StandardMetadataType::HEIGHT>(mMapper, bufferHandle);
330 if (height != value) {
331 ALOGW("Height didn't match, expected %d got %" PRId64, height, value.value_or(-1));
332 return BAD_VALUE;
333 }
334 }
335 {
336 auto value =
337 getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_REQUESTED>(mMapper,
338 bufferHandle);
339 if (static_cast<::aidl::android::hardware::graphics::common::PixelFormat>(format) !=
340 value) {
341 ALOGW("Format didn't match, expected %d got %s", format,
342 value.has_value() ? toString(*value).c_str() : "<null>");
343 return BAD_VALUE;
344 }
345 }
346 {
347 auto value = getStandardMetadata<StandardMetadataType::LAYER_COUNT>(mMapper, bufferHandle);
348 if (layerCount != value) {
349 ALOGW("Layer count didn't match, expected %d got %" PRId64, layerCount,
350 value.value_or(-1));
351 return BAD_VALUE;
352 }
353 }
John Reck47390ec2023-05-24 13:46:37 -0400354 // TODO: This can false-positive fail if the allocator adjusted the USAGE bits internally
355 // Investigate further & re-enable or remove, but for now ignoring usage should be OK
356 (void)usage;
357 // {
358 // auto value = getStandardMetadata<StandardMetadataType::USAGE>(mMapper, bufferHandle);
359 // if (static_cast<BufferUsage>(usage) != value) {
360 // ALOGW("Usage didn't match, expected %" PRIu64 " got %" PRId64, usage,
361 // static_cast<int64_t>(value.value_or(BufferUsage::CPU_READ_NEVER)));
362 // return BAD_VALUE;
363 // }
364 // }
John Reck0ff95c92022-12-08 11:45:29 -0500365 {
John Recke225b282023-03-24 16:15:17 -0400366 auto value = getStandardMetadata<StandardMetadataType::STRIDE>(mMapper, bufferHandle);
367 if (stride != value) {
368 ALOGW("Stride didn't match, expected %" PRIu32 " got %" PRId32, stride,
369 value.value_or(-1));
370 return BAD_VALUE;
371 }
John Reck0ff95c92022-12-08 11:45:29 -0500372 }
373 return OK;
374}
375
376void Gralloc5Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t *outNumFds,
377 uint32_t *outNumInts) const {
378 mMapper->v5.getTransportSize(bufferHandle, outNumFds, outNumInts);
379}
380
381status_t Gralloc5Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect &bounds,
382 int acquireFence, void **outData, int32_t *outBytesPerPixel,
383 int32_t *outBytesPerStride) const {
384 std::vector<ui::PlaneLayout> planeLayouts;
385 status_t err = getPlaneLayouts(bufferHandle, &planeLayouts);
386
387 if (err == NO_ERROR && !planeLayouts.empty()) {
388 if (outBytesPerPixel) {
389 int32_t bitsPerPixel = planeLayouts.front().sampleIncrementInBits;
390 for (const auto &planeLayout : planeLayouts) {
391 if (bitsPerPixel != planeLayout.sampleIncrementInBits) {
392 bitsPerPixel = -1;
393 }
394 }
395 if (bitsPerPixel >= 0 && bitsPerPixel % 8 == 0) {
396 *outBytesPerPixel = bitsPerPixel / 8;
397 } else {
398 *outBytesPerPixel = -1;
399 }
400 }
401 if (outBytesPerStride) {
402 int32_t bytesPerStride = planeLayouts.front().strideInBytes;
403 for (const auto &planeLayout : planeLayouts) {
404 if (bytesPerStride != planeLayout.strideInBytes) {
405 bytesPerStride = -1;
406 }
407 }
408 if (bytesPerStride >= 0) {
409 *outBytesPerStride = bytesPerStride;
410 } else {
411 *outBytesPerStride = -1;
412 }
413 }
414 }
415
416 auto status = mMapper->v5.lock(bufferHandle, usage, bounds, acquireFence, outData);
417
418 ALOGW_IF(status != AIMAPPER_ERROR_NONE, "lock(%p, ...) failed: %d", bufferHandle, status);
419 return static_cast<status_t>(status);
420}
421
422status_t Gralloc5Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect &bounds,
423 int acquireFence, android_ycbcr *outYcbcr) const {
424 if (!outYcbcr) {
425 return BAD_VALUE;
426 }
427
428 // TODO(b/262279301): Change the return type of ::unlock to unique_fd instead of int so that
429 // ignoring the return value "just works" instead
430 auto unlock = [this](buffer_handle_t bufferHandle) {
431 int fence = this->unlock(bufferHandle);
432 if (fence != -1) {
433 ::close(fence);
434 }
435 };
436
437 std::vector<ui::PlaneLayout> planeLayouts;
438 status_t error = getPlaneLayouts(bufferHandle, &planeLayouts);
439 if (error != NO_ERROR) {
440 return error;
441 }
442
443 void *data = nullptr;
444 error = lock(bufferHandle, usage, bounds, acquireFence, &data, nullptr, nullptr);
445 if (error != NO_ERROR) {
446 return error;
447 }
448
449 android_ycbcr ycbcr;
450
451 ycbcr.y = nullptr;
452 ycbcr.cb = nullptr;
453 ycbcr.cr = nullptr;
454 ycbcr.ystride = 0;
455 ycbcr.cstride = 0;
456 ycbcr.chroma_step = 0;
457
458 for (const auto &planeLayout : planeLayouts) {
459 for (const auto &planeLayoutComponent : planeLayout.components) {
460 if (!gralloc4::isStandardPlaneLayoutComponentType(planeLayoutComponent.type)) {
461 continue;
462 }
463
464 uint8_t *tmpData = static_cast<uint8_t *>(data) + planeLayout.offsetInBytes;
465
466 // Note that `offsetInBits` may not be a multiple of 8 for packed formats (e.g. P010)
467 // but we still want to point to the start of the first byte.
468 tmpData += (planeLayoutComponent.offsetInBits / 8);
469
470 uint64_t sampleIncrementInBytes;
471
472 auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
473 switch (type) {
474 case PlaneLayoutComponentType::Y:
475 if ((ycbcr.y != nullptr) || (planeLayout.sampleIncrementInBits % 8 != 0)) {
476 unlock(bufferHandle);
477 return BAD_VALUE;
478 }
479 ycbcr.y = tmpData;
480 ycbcr.ystride = planeLayout.strideInBytes;
481 break;
482
483 case PlaneLayoutComponentType::CB:
484 case PlaneLayoutComponentType::CR:
485 if (planeLayout.sampleIncrementInBits % 8 != 0) {
486 unlock(bufferHandle);
487 return BAD_VALUE;
488 }
489
490 sampleIncrementInBytes = planeLayout.sampleIncrementInBits / 8;
491 if ((sampleIncrementInBytes != 1) && (sampleIncrementInBytes != 2) &&
492 (sampleIncrementInBytes != 4)) {
493 unlock(bufferHandle);
494 return BAD_VALUE;
495 }
496
497 if (ycbcr.cstride == 0 && ycbcr.chroma_step == 0) {
498 ycbcr.cstride = planeLayout.strideInBytes;
499 ycbcr.chroma_step = sampleIncrementInBytes;
500 } else {
501 if ((static_cast<int64_t>(ycbcr.cstride) != planeLayout.strideInBytes) ||
502 (ycbcr.chroma_step != sampleIncrementInBytes)) {
503 unlock(bufferHandle);
504 return BAD_VALUE;
505 }
506 }
507
508 if (type == PlaneLayoutComponentType::CB) {
509 if (ycbcr.cb != nullptr) {
510 unlock(bufferHandle);
511 return BAD_VALUE;
512 }
513 ycbcr.cb = tmpData;
514 } else {
515 if (ycbcr.cr != nullptr) {
516 unlock(bufferHandle);
517 return BAD_VALUE;
518 }
519 ycbcr.cr = tmpData;
520 }
521 break;
522 default:
523 break;
524 };
525 }
526 }
527
528 *outYcbcr = ycbcr;
529 return OK;
530}
531
532int Gralloc5Mapper::unlock(buffer_handle_t bufferHandle) const {
533 int fence = -1;
534 AIMapper_Error error = mMapper->v5.unlock(bufferHandle, &fence);
535 if (error != AIMAPPER_ERROR_NONE) {
536 ALOGW("unlock failed with error %d", error);
537 }
538 return fence;
539}
540
541status_t Gralloc5Mapper::isSupported(uint32_t width, uint32_t height, PixelFormat format,
542 uint32_t layerCount, uint64_t usage,
543 bool *outSupported) const {
544 auto descriptorInfo = makeDescriptor("", width, height, format, layerCount, usage);
545 if (!descriptorInfo) {
546 *outSupported = false;
547 return OK;
548 }
549 auto status = getInstance().allocator->isSupported(*descriptorInfo, outSupported);
550 if (!status.isOk()) {
551 ALOGW("IAllocator::isSupported error %d (%s)", status.getStatus(), status.getMessage());
552 *outSupported = false;
553 }
554 return OK;
555}
556
557status_t Gralloc5Mapper::getBufferId(buffer_handle_t bufferHandle, uint64_t *outBufferId) const {
558 auto value = getStandardMetadata<StandardMetadataType::BUFFER_ID>(mMapper, bufferHandle);
559 if (value.has_value()) {
560 *outBufferId = *value;
561 return OK;
562 }
563 return UNKNOWN_TRANSACTION;
564}
565
566status_t Gralloc5Mapper::getName(buffer_handle_t bufferHandle, std::string *outName) const {
567 auto value = getStandardMetadata<StandardMetadataType::NAME>(mMapper, bufferHandle);
568 if (value.has_value()) {
569 *outName = *value;
570 return OK;
571 }
572 return UNKNOWN_TRANSACTION;
573}
574
575status_t Gralloc5Mapper::getWidth(buffer_handle_t bufferHandle, uint64_t *outWidth) const {
576 auto value = getStandardMetadata<StandardMetadataType::WIDTH>(mMapper, bufferHandle);
577 if (value.has_value()) {
578 *outWidth = *value;
579 return OK;
580 }
581 return UNKNOWN_TRANSACTION;
582}
583
584status_t Gralloc5Mapper::getHeight(buffer_handle_t bufferHandle, uint64_t *outHeight) const {
585 auto value = getStandardMetadata<StandardMetadataType::HEIGHT>(mMapper, bufferHandle);
586 if (value.has_value()) {
587 *outHeight = *value;
588 return OK;
589 }
590 return UNKNOWN_TRANSACTION;
591}
592
593status_t Gralloc5Mapper::getLayerCount(buffer_handle_t bufferHandle,
594 uint64_t *outLayerCount) const {
595 auto value = getStandardMetadata<StandardMetadataType::LAYER_COUNT>(mMapper, bufferHandle);
596 if (value.has_value()) {
597 *outLayerCount = *value;
598 return OK;
599 }
600 return UNKNOWN_TRANSACTION;
601}
602
603status_t Gralloc5Mapper::getPixelFormatRequested(buffer_handle_t bufferHandle,
604 ui::PixelFormat *outPixelFormatRequested) const {
605 auto value = getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_REQUESTED>(mMapper,
606 bufferHandle);
607 if (value.has_value()) {
608 *outPixelFormatRequested = static_cast<ui::PixelFormat>(*value);
609 return OK;
610 }
611 return UNKNOWN_TRANSACTION;
612}
613
614status_t Gralloc5Mapper::getPixelFormatFourCC(buffer_handle_t bufferHandle,
615 uint32_t *outPixelFormatFourCC) const {
616 auto value =
617 getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_FOURCC>(mMapper, bufferHandle);
618 if (value.has_value()) {
619 *outPixelFormatFourCC = *value;
620 return OK;
621 }
622 return UNKNOWN_TRANSACTION;
623}
624
625status_t Gralloc5Mapper::getPixelFormatModifier(buffer_handle_t bufferHandle,
626 uint64_t *outPixelFormatModifier) const {
627 auto value =
628 getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_MODIFIER>(mMapper, bufferHandle);
629 if (value.has_value()) {
630 *outPixelFormatModifier = *value;
631 return OK;
632 }
633 return UNKNOWN_TRANSACTION;
634}
635
636status_t Gralloc5Mapper::getUsage(buffer_handle_t bufferHandle, uint64_t *outUsage) const {
637 auto value = getStandardMetadata<StandardMetadataType::USAGE>(mMapper, bufferHandle);
638 if (value.has_value()) {
639 *outUsage = static_cast<uint64_t>(*value);
640 return OK;
641 }
642 return UNKNOWN_TRANSACTION;
643}
644
645status_t Gralloc5Mapper::getAllocationSize(buffer_handle_t bufferHandle,
646 uint64_t *outAllocationSize) const {
647 auto value = getStandardMetadata<StandardMetadataType::ALLOCATION_SIZE>(mMapper, bufferHandle);
648 if (value.has_value()) {
649 *outAllocationSize = *value;
650 return OK;
651 }
652 return UNKNOWN_TRANSACTION;
653}
654
655status_t Gralloc5Mapper::getProtectedContent(buffer_handle_t bufferHandle,
656 uint64_t *outProtectedContent) const {
657 auto value =
658 getStandardMetadata<StandardMetadataType::PROTECTED_CONTENT>(mMapper, bufferHandle);
659 if (value.has_value()) {
660 *outProtectedContent = *value;
661 return OK;
662 }
663 return UNKNOWN_TRANSACTION;
664}
665
666status_t Gralloc5Mapper::getCompression(
667 buffer_handle_t bufferHandle,
668 aidl::android::hardware::graphics::common::ExtendableType *outCompression) const {
669 auto value = getStandardMetadata<StandardMetadataType::COMPRESSION>(mMapper, bufferHandle);
670 if (value.has_value()) {
671 *outCompression = *value;
672 return OK;
673 }
674 return UNKNOWN_TRANSACTION;
675}
676
677status_t Gralloc5Mapper::getCompression(buffer_handle_t bufferHandle,
678 ui::Compression *outCompression) const {
679 auto value = getStandardMetadata<StandardMetadataType::COMPRESSION>(mMapper, bufferHandle);
680 if (!value.has_value()) {
681 return UNKNOWN_TRANSACTION;
682 }
683 if (!gralloc4::isStandardCompression(*value)) {
684 return BAD_TYPE;
685 }
686 *outCompression = gralloc4::getStandardCompressionValue(*value);
687 return OK;
688}
689
690status_t Gralloc5Mapper::getInterlaced(
691 buffer_handle_t bufferHandle,
692 aidl::android::hardware::graphics::common::ExtendableType *outInterlaced) const {
693 auto value = getStandardMetadata<StandardMetadataType::INTERLACED>(mMapper, bufferHandle);
694 if (value.has_value()) {
695 *outInterlaced = *value;
696 return OK;
697 }
698 return UNKNOWN_TRANSACTION;
699}
700
701status_t Gralloc5Mapper::getInterlaced(buffer_handle_t bufferHandle,
702 ui::Interlaced *outInterlaced) const {
703 if (!outInterlaced) {
704 return BAD_VALUE;
705 }
706 ExtendableType interlaced;
707 status_t error = getInterlaced(bufferHandle, &interlaced);
708 if (error) {
709 return error;
710 }
711 if (!gralloc4::isStandardInterlaced(interlaced)) {
712 return BAD_TYPE;
713 }
714 *outInterlaced = gralloc4::getStandardInterlacedValue(interlaced);
715 return NO_ERROR;
716}
717
718status_t Gralloc5Mapper::getChromaSiting(
719 buffer_handle_t bufferHandle,
720 aidl::android::hardware::graphics::common::ExtendableType *outChromaSiting) const {
721 auto value = getStandardMetadata<StandardMetadataType::CHROMA_SITING>(mMapper, bufferHandle);
722 if (value.has_value()) {
723 *outChromaSiting = *value;
724 return OK;
725 }
726 return UNKNOWN_TRANSACTION;
727}
728
729status_t Gralloc5Mapper::getChromaSiting(buffer_handle_t bufferHandle,
730 ui::ChromaSiting *outChromaSiting) const {
731 if (!outChromaSiting) {
732 return BAD_VALUE;
733 }
734 ExtendableType chromaSiting;
735 status_t error = getChromaSiting(bufferHandle, &chromaSiting);
736 if (error) {
737 return error;
738 }
739 if (!gralloc4::isStandardChromaSiting(chromaSiting)) {
740 return BAD_TYPE;
741 }
742 *outChromaSiting = gralloc4::getStandardChromaSitingValue(chromaSiting);
743 return NO_ERROR;
744}
745
746status_t Gralloc5Mapper::getPlaneLayouts(buffer_handle_t bufferHandle,
747 std::vector<ui::PlaneLayout> *outPlaneLayouts) const {
748 auto value = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(mMapper, bufferHandle);
749 if (value.has_value()) {
750 *outPlaneLayouts = *value;
751 return OK;
752 }
753 return UNKNOWN_TRANSACTION;
754}
755
756status_t Gralloc5Mapper::getDataspace(buffer_handle_t bufferHandle,
757 ui::Dataspace *outDataspace) const {
758 auto value = getStandardMetadata<StandardMetadataType::DATASPACE>(mMapper, bufferHandle);
759 if (value.has_value()) {
760 *outDataspace = static_cast<ui::Dataspace>(*value);
761 return OK;
762 }
763 return UNKNOWN_TRANSACTION;
764}
765
766status_t Gralloc5Mapper::setDataspace(buffer_handle_t bufferHandle, ui::Dataspace dataspace) const {
767 return setStandardMetadata<StandardMetadataType::DATASPACE>(mMapper, bufferHandle,
768 static_cast<Dataspace>(dataspace));
769}
770
771status_t Gralloc5Mapper::getBlendMode(buffer_handle_t bufferHandle,
772 ui::BlendMode *outBlendMode) const {
773 auto value = getStandardMetadata<StandardMetadataType::BLEND_MODE>(mMapper, bufferHandle);
774 if (value.has_value()) {
775 *outBlendMode = static_cast<ui::BlendMode>(*value);
776 return OK;
777 }
778 return UNKNOWN_TRANSACTION;
779}
780
781status_t Gralloc5Mapper::getSmpte2086(buffer_handle_t bufferHandle,
782 std::optional<ui::Smpte2086> *outSmpte2086) const {
783 auto value = getStandardMetadata<StandardMetadataType::SMPTE2086>(mMapper, bufferHandle);
784 if (value.has_value()) {
785 *outSmpte2086 = *value;
786 return OK;
787 }
788 return UNKNOWN_TRANSACTION;
789}
790
791status_t Gralloc5Mapper::setSmpte2086(buffer_handle_t bufferHandle,
792 std::optional<ui::Smpte2086> smpte2086) const {
793 return setStandardMetadata<StandardMetadataType::SMPTE2086>(mMapper, bufferHandle, smpte2086);
794}
795
796status_t Gralloc5Mapper::getCta861_3(buffer_handle_t bufferHandle,
797 std::optional<ui::Cta861_3> *outCta861_3) const {
798 auto value = getStandardMetadata<StandardMetadataType::CTA861_3>(mMapper, bufferHandle);
799 if (value.has_value()) {
800 *outCta861_3 = *value;
801 return OK;
802 }
803 return UNKNOWN_TRANSACTION;
804}
805
806status_t Gralloc5Mapper::setCta861_3(buffer_handle_t bufferHandle,
807 std::optional<ui::Cta861_3> cta861_3) const {
808 return setStandardMetadata<StandardMetadataType::CTA861_3>(mMapper, bufferHandle, cta861_3);
809}
810
811status_t Gralloc5Mapper::getSmpte2094_40(
812 buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>> *outSmpte2094_40) const {
813 auto value = getStandardMetadata<StandardMetadataType::SMPTE2094_40>(mMapper, bufferHandle);
814 if (value.has_value()) {
815 *outSmpte2094_40 = std::move(*value);
816 return OK;
817 }
818 return UNKNOWN_TRANSACTION;
819}
820
821status_t Gralloc5Mapper::setSmpte2094_40(buffer_handle_t bufferHandle,
822 std::optional<std::vector<uint8_t>> smpte2094_40) const {
823 return setStandardMetadata<StandardMetadataType::SMPTE2094_40>(mMapper, bufferHandle,
824 smpte2094_40);
825}
826
827status_t Gralloc5Mapper::getSmpte2094_10(
828 buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>> *outSmpte2094_10) const {
829 auto value = getStandardMetadata<StandardMetadataType::SMPTE2094_10>(mMapper, bufferHandle);
830 if (value.has_value()) {
831 *outSmpte2094_10 = std::move(*value);
832 return OK;
833 }
834 return UNKNOWN_TRANSACTION;
835}
836
837status_t Gralloc5Mapper::setSmpte2094_10(buffer_handle_t bufferHandle,
838 std::optional<std::vector<uint8_t>> smpte2094_10) const {
839 return setStandardMetadata<StandardMetadataType::SMPTE2094_10>(mMapper, bufferHandle,
840 smpte2094_10);
841}
842
John Reck0ff95c92022-12-08 11:45:29 -0500843} // namespace android