blob: 303043a35ad9633a58882736a1a2e72ed529a27e [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>
Justin Yun404dbf22024-03-19 13:01:43 +090025#include <android/llndk-versioning.h>
John Reck0ff95c92022-12-08 11:45:29 -050026#include <binder/IPCThreadState.h>
27#include <dlfcn.h>
28#include <ui/FatVector.h>
29#include <vndksupport/linker.h>
30
31using namespace aidl::android::hardware::graphics::allocator;
32using namespace aidl::android::hardware::graphics::common;
33using namespace ::android::hardware::graphics::mapper;
34
John Reckedcd8852023-07-25 16:03:44 -040035using ADataspace = aidl::android::hardware::graphics::common::Dataspace;
36using APixelFormat = aidl::android::hardware::graphics::common::PixelFormat;
37
John Reck0ff95c92022-12-08 11:45:29 -050038namespace android {
39
40static const auto kIAllocatorServiceName = IAllocator::descriptor + std::string("/default");
41static const auto kIAllocatorMinimumVersion = 2;
John Reckedcd8852023-07-25 16:03:44 -040042constexpr const char* kStandardMetadataName =
43 "android.hardware.graphics.common.StandardMetadataType";
John Reck0ff95c92022-12-08 11:45:29 -050044
45// TODO(b/72323293, b/72703005): Remove these invalid bits from callers
46static constexpr uint64_t kRemovedUsageBits = static_cast<uint64_t>((1 << 10) | (1 << 13));
47
48typedef AIMapper_Error (*AIMapper_loadIMapperFn)(AIMapper *_Nullable *_Nonnull outImplementation);
49
50struct Gralloc5 {
51 std::shared_ptr<IAllocator> allocator;
52 AIMapper *mapper = nullptr;
53};
54
55static std::shared_ptr<IAllocator> waitForAllocator() {
56 if (__builtin_available(android 31, *)) {
57 if (!AServiceManager_isDeclared(kIAllocatorServiceName.c_str())) {
58 return nullptr;
59 }
60 auto allocator = IAllocator::fromBinder(
61 ndk::SpAIBinder(AServiceManager_waitForService(kIAllocatorServiceName.c_str())));
62 if (!allocator) {
63 ALOGE("AIDL IAllocator declared but failed to get service");
64 return nullptr;
65 }
66
67 int32_t version = 0;
68 if (!allocator->getInterfaceVersion(&version).isOk()) {
69 ALOGE("Failed to query interface version");
70 return nullptr;
71 }
72 if (version < kIAllocatorMinimumVersion) {
73 return nullptr;
74 }
75 return allocator;
76 } else {
77 // TODO: LOG_ALWAYS_FATAL("libui is not backwards compatible");
78 return nullptr;
79 }
80}
81
82static void *loadIMapperLibrary() {
83 static void *imapperLibrary = []() -> void * {
84 auto allocator = waitForAllocator();
85 std::string mapperSuffix;
86 auto status = allocator->getIMapperLibrarySuffix(&mapperSuffix);
87 if (!status.isOk()) {
88 ALOGE("Failed to get IMapper library suffix");
89 return nullptr;
90 }
91
Jooyung Han75fc06f2024-02-03 03:56:59 +090092 void* so = nullptr;
93 // TODO(b/322384429) switch this to __ANDROID_API_V__ when V is finalized
Justin Yun404dbf22024-03-19 13:01:43 +090094 if API_LEVEL_AT_LEAST(__ANDROID_API_FUTURE__, 202404) {
Jooyung Han75fc06f2024-02-03 03:56:59 +090095 so = AServiceManager_openDeclaredPassthroughHal("mapper", mapperSuffix.c_str(),
96 RTLD_LOCAL | RTLD_NOW);
97 } else {
98 std::string lib_name = "mapper." + mapperSuffix + ".so";
99 so = android_load_sphal_library(lib_name.c_str(), RTLD_LOCAL | RTLD_NOW);
100 }
John Reck0ff95c92022-12-08 11:45:29 -0500101 if (!so) {
Jooyung Han75fc06f2024-02-03 03:56:59 +0900102 ALOGE("Failed to load mapper.%s.so", mapperSuffix.c_str());
John Reck0ff95c92022-12-08 11:45:29 -0500103 }
104 return so;
105 }();
106 return imapperLibrary;
107}
108
109static const Gralloc5 &getInstance() {
110 static Gralloc5 instance = []() {
111 auto allocator = waitForAllocator();
112 if (!allocator) {
113 return Gralloc5{};
114 }
115 void *so = loadIMapperLibrary();
116 if (!so) {
117 return Gralloc5{};
118 }
119 auto loadIMapper = (AIMapper_loadIMapperFn)dlsym(so, "AIMapper_loadIMapper");
120 AIMapper *mapper = nullptr;
121 AIMapper_Error error = loadIMapper(&mapper);
122 if (error != AIMAPPER_ERROR_NONE) {
123 ALOGE("AIMapper_loadIMapper failed %d", error);
124 return Gralloc5{};
125 }
126 return Gralloc5{std::move(allocator), mapper};
127 }();
128 return instance;
129}
130
131template <StandardMetadataType T>
132static auto getStandardMetadata(AIMapper *mapper, buffer_handle_t bufferHandle)
133 -> decltype(StandardMetadata<T>::value::decode(nullptr, 0)) {
134 using Value = typename StandardMetadata<T>::value;
135 // TODO: Tune for common-case better
136 FatVector<uint8_t, 128> buffer;
137 int32_t sizeRequired = mapper->v5.getStandardMetadata(bufferHandle, static_cast<int64_t>(T),
138 buffer.data(), buffer.size());
139 if (sizeRequired < 0) {
140 ALOGW_IF(-AIMAPPER_ERROR_UNSUPPORTED != sizeRequired,
141 "Unexpected error %d from valid getStandardMetadata call", -sizeRequired);
142 return std::nullopt;
143 }
144 if ((size_t)sizeRequired > buffer.size()) {
145 buffer.resize(sizeRequired);
146 sizeRequired = mapper->v5.getStandardMetadata(bufferHandle, static_cast<int64_t>(T),
147 buffer.data(), buffer.size());
148 }
149 if (sizeRequired < 0 || (size_t)sizeRequired > buffer.size()) {
150 ALOGW("getStandardMetadata failed, received %d with buffer size %zd", sizeRequired,
151 buffer.size());
152 // Generate a fail type
153 return std::nullopt;
154 }
155 return Value::decode(buffer.data(), sizeRequired);
156}
157
158template <StandardMetadataType T>
159static AIMapper_Error setStandardMetadata(AIMapper *mapper, buffer_handle_t bufferHandle,
160 const typename StandardMetadata<T>::value_type &value) {
161 using Value = typename StandardMetadata<T>::value;
162 int32_t sizeRequired = Value::encode(value, nullptr, 0);
163 if (sizeRequired < 0) {
164 ALOGW("Failed to calculate required size");
165 return static_cast<AIMapper_Error>(-sizeRequired);
166 }
167 FatVector<uint8_t, 128> buffer;
168 buffer.resize(sizeRequired);
169 sizeRequired = Value::encode(value, buffer.data(), buffer.size());
170 if (sizeRequired < 0 || (size_t)sizeRequired > buffer.size()) {
171 ALOGW("Failed to encode with calculated size %d; buffer size %zd", sizeRequired,
172 buffer.size());
173 return static_cast<AIMapper_Error>(-sizeRequired);
174 }
175 return mapper->v5.setStandardMetadata(bufferHandle, static_cast<int64_t>(T), buffer.data(),
176 sizeRequired);
177}
178
179Gralloc5Allocator::Gralloc5Allocator(const Gralloc5Mapper &mapper) : mMapper(mapper) {
180 mAllocator = getInstance().allocator;
181}
182
183bool Gralloc5Allocator::isLoaded() const {
184 return mAllocator != nullptr;
185}
186
187static uint64_t getValidUsageBits() {
188 static const uint64_t validUsageBits = []() -> uint64_t {
189 uint64_t bits = 0;
190 for (const auto bit : ndk::enum_range<BufferUsage>{}) {
191 bits |= static_cast<int64_t>(bit);
192 }
193 return bits;
194 }();
195 return validUsageBits | kRemovedUsageBits;
196}
197
198static std::optional<BufferDescriptorInfo> makeDescriptor(std::string requestorName, uint32_t width,
199 uint32_t height, PixelFormat format,
200 uint32_t layerCount, uint64_t usage) {
201 uint64_t validUsageBits = getValidUsageBits();
202 if (usage & ~validUsageBits) {
203 ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64, usage & ~validUsageBits);
204 return std::nullopt;
205 }
206
207 BufferDescriptorInfo descriptorInfo{
208 .width = static_cast<int32_t>(width),
209 .height = static_cast<int32_t>(height),
210 .layerCount = static_cast<int32_t>(layerCount),
211 .format = static_cast<::aidl::android::hardware::graphics::common::PixelFormat>(format),
212 .usage = static_cast<BufferUsage>(usage),
213 };
214 auto nameLength = std::min(requestorName.length(), descriptorInfo.name.size() - 1);
215 memcpy(descriptorInfo.name.data(), requestorName.data(), nameLength);
216 requestorName.data()[nameLength] = 0;
217 return descriptorInfo;
218}
219
220std::string Gralloc5Allocator::dumpDebugInfo(bool less) const {
221 return mMapper.dumpBuffers(less);
222}
223
224status_t Gralloc5Allocator::allocate(std::string requestorName, uint32_t width, uint32_t height,
225 android::PixelFormat format, uint32_t layerCount,
226 uint64_t usage, uint32_t bufferCount, uint32_t *outStride,
227 buffer_handle_t *outBufferHandles, bool importBuffers) const {
228 auto descriptorInfo = makeDescriptor(requestorName, width, height, format, layerCount, usage);
229 if (!descriptorInfo) {
230 return BAD_VALUE;
231 }
232
233 AllocationResult result;
234 auto status = mAllocator->allocate2(*descriptorInfo, bufferCount, &result);
235 if (!status.isOk()) {
236 auto error = status.getExceptionCode();
237 if (error == EX_SERVICE_SPECIFIC) {
238 error = status.getServiceSpecificError();
239 }
240 if (error == OK) {
241 error = UNKNOWN_ERROR;
242 }
243 return error;
244 }
245
246 if (importBuffers) {
247 for (uint32_t i = 0; i < bufferCount; i++) {
248 auto handle = makeFromAidl(result.buffers[i]);
249 auto error = mMapper.importBuffer(handle, &outBufferHandles[i]);
250 native_handle_delete(handle);
251 if (error != NO_ERROR) {
252 for (uint32_t j = 0; j < i; j++) {
253 mMapper.freeBuffer(outBufferHandles[j]);
254 outBufferHandles[j] = nullptr;
255 }
256 return error;
257 }
258 }
259 } else {
260 for (uint32_t i = 0; i < bufferCount; i++) {
261 outBufferHandles[i] = dupFromAidl(result.buffers[i]);
262 if (!outBufferHandles[i]) {
263 for (uint32_t j = 0; j < i; j++) {
264 auto buffer = const_cast<native_handle_t *>(outBufferHandles[j]);
265 native_handle_close(buffer);
266 native_handle_delete(buffer);
267 outBufferHandles[j] = nullptr;
268 }
269 return NO_MEMORY;
270 }
271 }
272 }
273
274 *outStride = result.stride;
275
276 // Release all the resources held by AllocationResult (specifically any remaining FDs)
277 result = {};
278 // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
279 // TODO: Re-enable this at some point if it's necessary. We can't do it now because libui
280 // is marked apex_available (b/214400477) and libbinder isn't (which of course is correct)
281 // IPCThreadState::self()->flushCommands();
282
283 return OK;
284}
285
286void Gralloc5Mapper::preload() {
287 // TODO(b/261858155): Implement. We can't bounce off of IAllocator for this because zygote can't
288 // use binder. So when an alternate strategy of retrieving the library prefix is available,
289 // use that here.
290}
291
292Gralloc5Mapper::Gralloc5Mapper() {
293 mMapper = getInstance().mapper;
294}
295
296bool Gralloc5Mapper::isLoaded() const {
297 return mMapper != nullptr && mMapper->version >= AIMAPPER_VERSION_5;
298}
299
John Reckedcd8852023-07-25 16:03:44 -0400300static bool isStandardMetadata(AIMapper_MetadataType metadataType) {
301 return strcmp(kStandardMetadataName, metadataType.name) == 0;
302}
303
304struct DumpBufferResult {
305 uint64_t bufferId;
306 std::string name;
307 uint64_t width;
308 uint64_t height;
309 uint64_t layerCount;
310 APixelFormat pixelFormatRequested;
311 uint32_t pixelFormatFourCC;
312 uint64_t pixelFormatModifier;
313 BufferUsage usage;
314 ADataspace dataspace;
315 uint64_t allocationSize;
316 uint64_t protectedContent;
317 ExtendableType compression;
318 ExtendableType interlaced;
319 ExtendableType chromaSiting;
320 std::vector<ui::PlaneLayout> planeLayouts;
321};
322
323#define DECODE_TO(name, output) \
324 case StandardMetadataType::name: \
325 output = StandardMetadata<StandardMetadataType::name>::value ::decode(value, valueSize) \
326 .value(); \
327 break
328
329static void dumpBufferCommon(DumpBufferResult* outResult, AIMapper_MetadataType metadataType,
330 const void* value, size_t valueSize) {
331 if (!isStandardMetadata(metadataType)) {
332 return;
333 }
334 StandardMetadataType type = (StandardMetadataType)metadataType.value;
335 switch (type) {
336 DECODE_TO(BUFFER_ID, outResult->bufferId);
337 DECODE_TO(NAME, outResult->name);
338 DECODE_TO(WIDTH, outResult->width);
339 DECODE_TO(HEIGHT, outResult->height);
340 DECODE_TO(LAYER_COUNT, outResult->layerCount);
341 DECODE_TO(PIXEL_FORMAT_REQUESTED, outResult->pixelFormatRequested);
342 DECODE_TO(PIXEL_FORMAT_FOURCC, outResult->pixelFormatFourCC);
343 DECODE_TO(PIXEL_FORMAT_MODIFIER, outResult->pixelFormatModifier);
344 DECODE_TO(USAGE, outResult->usage);
345 DECODE_TO(DATASPACE, outResult->dataspace);
346 DECODE_TO(ALLOCATION_SIZE, outResult->allocationSize);
347 DECODE_TO(PROTECTED_CONTENT, outResult->protectedContent);
348 DECODE_TO(COMPRESSION, outResult->compression);
349 DECODE_TO(INTERLACED, outResult->interlaced);
350 DECODE_TO(CHROMA_SITING, outResult->chromaSiting);
351 DECODE_TO(PLANE_LAYOUTS, outResult->planeLayouts);
352 default:
353 break;
354 }
355}
356
357#undef DECODE_TO
358
359template <typename EnumT, typename = std::enable_if_t<std::is_enum<EnumT>{}>>
360constexpr std::underlying_type_t<EnumT> to_underlying(EnumT e) noexcept {
361 return static_cast<std::underlying_type_t<EnumT>>(e);
362}
363
364static void writeDumpToStream(const DumpBufferResult& bufferDump, std::ostream& outDump,
365 bool less) {
366 double allocationSizeKiB = static_cast<double>(bufferDump.allocationSize) / 1024;
367
368 outDump << "+ name:" << bufferDump.name << ", id:" << bufferDump.bufferId
369 << ", size:" << std::fixed << allocationSizeKiB << "KiB, w/h:" << bufferDump.width
370 << "x" << bufferDump.height << ", usage: 0x" << std::hex
371 << to_underlying(bufferDump.usage) << std::dec
372 << ", req fmt:" << to_underlying(bufferDump.pixelFormatRequested)
373 << ", fourcc/mod:" << bufferDump.pixelFormatFourCC << "/"
374 << bufferDump.pixelFormatModifier << ", dataspace: 0x" << std::hex
375 << to_underlying(bufferDump.dataspace) << std::dec << ", compressed: ";
376
377 if (less) {
378 bool isCompressed = !gralloc4::isStandardCompression(bufferDump.compression) ||
379 (gralloc4::getStandardCompressionValue(bufferDump.compression) !=
380 ui::Compression::NONE);
381 outDump << std::boolalpha << isCompressed << "\n";
382 } else {
383 outDump << gralloc4::getCompressionName(bufferDump.compression) << "\n";
384 }
385
386 if (!less) {
387 bool firstPlane = true;
388 for (const auto& planeLayout : bufferDump.planeLayouts) {
389 if (firstPlane) {
390 firstPlane = false;
391 outDump << "\tplanes: ";
392 } else {
393 outDump << "\t ";
394 }
395
396 for (size_t i = 0; i < planeLayout.components.size(); i++) {
397 const auto& planeLayoutComponent = planeLayout.components[i];
398 outDump << gralloc4::getPlaneLayoutComponentTypeName(planeLayoutComponent.type);
399 if (i < planeLayout.components.size() - 1) {
400 outDump << "/";
401 } else {
402 outDump << ":\t";
403 }
404 }
405 outDump << " w/h:" << planeLayout.widthInSamples << "x" << planeLayout.heightInSamples
406 << ", stride:" << planeLayout.strideInBytes
407 << " bytes, size:" << planeLayout.totalSizeInBytes;
408 outDump << ", inc:" << planeLayout.sampleIncrementInBits
409 << " bits, subsampling w/h:" << planeLayout.horizontalSubsampling << "x"
410 << planeLayout.verticalSubsampling;
411 outDump << "\n";
412 }
413
414 outDump << "\tlayer cnt: " << bufferDump.layerCount
415 << ", protected content: " << bufferDump.protectedContent
416 << ", interlaced: " << gralloc4::getInterlacedName(bufferDump.interlaced)
417 << ", chroma siting:" << gralloc4::getChromaSitingName(bufferDump.chromaSiting)
418 << "\n";
419 }
420}
421
John Reck0ff95c92022-12-08 11:45:29 -0500422std::string Gralloc5Mapper::dumpBuffer(buffer_handle_t bufferHandle, bool less) const {
John Reckedcd8852023-07-25 16:03:44 -0400423 DumpBufferResult bufferInfo;
424 AIMapper_DumpBufferCallback dumpBuffer = [](void* contextPtr,
425 AIMapper_MetadataType metadataType,
426 const void* _Nonnull value, size_t valueSize) {
427 DumpBufferResult* context = reinterpret_cast<DumpBufferResult*>(contextPtr);
428 dumpBufferCommon(context, metadataType, value, valueSize);
429 };
430 AIMapper_Error error = mMapper->v5.dumpBuffer(bufferHandle, dumpBuffer, &bufferInfo);
431 if (error != AIMAPPER_ERROR_NONE) {
432 ALOGE("Error dumping buffer: %d", error);
433 return std::string{};
434 }
435 std::ostringstream stream;
436 stream.precision(2);
437 writeDumpToStream(bufferInfo, stream, less);
438 return stream.str();
John Reck0ff95c92022-12-08 11:45:29 -0500439}
440
441std::string Gralloc5Mapper::dumpBuffers(bool less) const {
John Reckedcd8852023-07-25 16:03:44 -0400442 class DumpAllBuffersContext {
443 private:
444 bool mHasPending = false;
445 DumpBufferResult mPending;
446 std::vector<DumpBufferResult> mResults;
447
448 public:
449 DumpAllBuffersContext() { mResults.reserve(10); }
450
451 void commit() {
452 if (mHasPending) {
453 mResults.push_back(mPending);
454 mHasPending = false;
455 }
456 }
457
458 DumpBufferResult* write() {
459 mHasPending = true;
460 return &mPending;
461 }
462
463 const std::vector<DumpBufferResult>& results() {
464 commit();
465 return mResults;
466 }
467 } context;
468
469 AIMapper_BeginDumpBufferCallback beginCallback = [](void* contextPtr) {
470 DumpAllBuffersContext* context = reinterpret_cast<DumpAllBuffersContext*>(contextPtr);
471 context->commit();
472 };
473
474 AIMapper_DumpBufferCallback dumpBuffer = [](void* contextPtr,
475 AIMapper_MetadataType metadataType,
476 const void* _Nonnull value, size_t valueSize) {
477 DumpAllBuffersContext* context = reinterpret_cast<DumpAllBuffersContext*>(contextPtr);
478 dumpBufferCommon(context->write(), metadataType, value, valueSize);
479 };
480
481 AIMapper_Error error = mMapper->v5.dumpAllBuffers(beginCallback, dumpBuffer, &context);
482 if (error != AIMAPPER_ERROR_NONE) {
483 ALOGE("Error dumping buffers: %d", error);
484 return std::string{};
485 }
486 uint64_t totalAllocationSize = 0;
487 std::ostringstream stream;
488 stream.precision(2);
489 stream << "Imported gralloc buffers:\n";
490
491 for (const auto& bufferDump : context.results()) {
492 writeDumpToStream(bufferDump, stream, less);
493 totalAllocationSize += bufferDump.allocationSize;
494 }
495
496 double totalAllocationSizeKiB = static_cast<double>(totalAllocationSize) / 1024;
497 stream << "Total imported by gralloc: " << totalAllocationSizeKiB << "KiB\n";
498 return stream.str();
John Reck0ff95c92022-12-08 11:45:29 -0500499}
500
501status_t Gralloc5Mapper::importBuffer(const native_handle_t *rawHandle,
502 buffer_handle_t *outBufferHandle) const {
503 return mMapper->v5.importBuffer(rawHandle, outBufferHandle);
504}
505
506void Gralloc5Mapper::freeBuffer(buffer_handle_t bufferHandle) const {
507 mMapper->v5.freeBuffer(bufferHandle);
508}
509
510status_t Gralloc5Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
511 uint32_t height, PixelFormat format,
512 uint32_t layerCount, uint64_t usage,
513 uint32_t stride) const {
514 {
515 auto value = getStandardMetadata<StandardMetadataType::WIDTH>(mMapper, bufferHandle);
516 if (width != value) {
517 ALOGW("Width didn't match, expected %d got %" PRId64, width, value.value_or(-1));
518 return BAD_VALUE;
519 }
520 }
521 {
522 auto value = getStandardMetadata<StandardMetadataType::HEIGHT>(mMapper, bufferHandle);
523 if (height != value) {
524 ALOGW("Height didn't match, expected %d got %" PRId64, height, value.value_or(-1));
525 return BAD_VALUE;
526 }
527 }
528 {
John Reck54a98142023-11-21 11:13:40 -0500529 auto expected = static_cast<APixelFormat>(format);
530 if (expected != APixelFormat::IMPLEMENTATION_DEFINED) {
531 auto value =
532 getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_REQUESTED>(mMapper,
533 bufferHandle);
534 if (expected != value) {
535 ALOGW("Format didn't match, expected %d got %s", format,
536 value.has_value() ? toString(*value).c_str() : "<null>");
537 return BAD_VALUE;
538 }
John Reck0ff95c92022-12-08 11:45:29 -0500539 }
540 }
541 {
542 auto value = getStandardMetadata<StandardMetadataType::LAYER_COUNT>(mMapper, bufferHandle);
543 if (layerCount != value) {
544 ALOGW("Layer count didn't match, expected %d got %" PRId64, layerCount,
545 value.value_or(-1));
546 return BAD_VALUE;
547 }
548 }
John Reck47390ec2023-05-24 13:46:37 -0400549 // TODO: This can false-positive fail if the allocator adjusted the USAGE bits internally
550 // Investigate further & re-enable or remove, but for now ignoring usage should be OK
551 (void)usage;
552 // {
553 // auto value = getStandardMetadata<StandardMetadataType::USAGE>(mMapper, bufferHandle);
554 // if (static_cast<BufferUsage>(usage) != value) {
555 // ALOGW("Usage didn't match, expected %" PRIu64 " got %" PRId64, usage,
556 // static_cast<int64_t>(value.value_or(BufferUsage::CPU_READ_NEVER)));
557 // return BAD_VALUE;
558 // }
559 // }
John Reck0ff95c92022-12-08 11:45:29 -0500560 {
John Recke225b282023-03-24 16:15:17 -0400561 auto value = getStandardMetadata<StandardMetadataType::STRIDE>(mMapper, bufferHandle);
562 if (stride != value) {
563 ALOGW("Stride didn't match, expected %" PRIu32 " got %" PRId32, stride,
564 value.value_or(-1));
565 return BAD_VALUE;
566 }
John Reck0ff95c92022-12-08 11:45:29 -0500567 }
568 return OK;
569}
570
571void Gralloc5Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t *outNumFds,
572 uint32_t *outNumInts) const {
573 mMapper->v5.getTransportSize(bufferHandle, outNumFds, outNumInts);
574}
575
576status_t Gralloc5Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect &bounds,
577 int acquireFence, void **outData, int32_t *outBytesPerPixel,
578 int32_t *outBytesPerStride) const {
579 std::vector<ui::PlaneLayout> planeLayouts;
580 status_t err = getPlaneLayouts(bufferHandle, &planeLayouts);
581
582 if (err == NO_ERROR && !planeLayouts.empty()) {
583 if (outBytesPerPixel) {
584 int32_t bitsPerPixel = planeLayouts.front().sampleIncrementInBits;
585 for (const auto &planeLayout : planeLayouts) {
586 if (bitsPerPixel != planeLayout.sampleIncrementInBits) {
587 bitsPerPixel = -1;
588 }
589 }
590 if (bitsPerPixel >= 0 && bitsPerPixel % 8 == 0) {
591 *outBytesPerPixel = bitsPerPixel / 8;
592 } else {
593 *outBytesPerPixel = -1;
594 }
595 }
596 if (outBytesPerStride) {
597 int32_t bytesPerStride = planeLayouts.front().strideInBytes;
598 for (const auto &planeLayout : planeLayouts) {
599 if (bytesPerStride != planeLayout.strideInBytes) {
600 bytesPerStride = -1;
601 }
602 }
603 if (bytesPerStride >= 0) {
604 *outBytesPerStride = bytesPerStride;
605 } else {
606 *outBytesPerStride = -1;
607 }
608 }
609 }
610
611 auto status = mMapper->v5.lock(bufferHandle, usage, bounds, acquireFence, outData);
612
613 ALOGW_IF(status != AIMAPPER_ERROR_NONE, "lock(%p, ...) failed: %d", bufferHandle, status);
614 return static_cast<status_t>(status);
615}
616
617status_t Gralloc5Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect &bounds,
618 int acquireFence, android_ycbcr *outYcbcr) const {
619 if (!outYcbcr) {
620 return BAD_VALUE;
621 }
622
623 // TODO(b/262279301): Change the return type of ::unlock to unique_fd instead of int so that
624 // ignoring the return value "just works" instead
625 auto unlock = [this](buffer_handle_t bufferHandle) {
626 int fence = this->unlock(bufferHandle);
627 if (fence != -1) {
628 ::close(fence);
629 }
630 };
631
632 std::vector<ui::PlaneLayout> planeLayouts;
633 status_t error = getPlaneLayouts(bufferHandle, &planeLayouts);
634 if (error != NO_ERROR) {
635 return error;
636 }
637
638 void *data = nullptr;
639 error = lock(bufferHandle, usage, bounds, acquireFence, &data, nullptr, nullptr);
640 if (error != NO_ERROR) {
641 return error;
642 }
643
644 android_ycbcr ycbcr;
645
646 ycbcr.y = nullptr;
647 ycbcr.cb = nullptr;
648 ycbcr.cr = nullptr;
649 ycbcr.ystride = 0;
650 ycbcr.cstride = 0;
651 ycbcr.chroma_step = 0;
652
653 for (const auto &planeLayout : planeLayouts) {
654 for (const auto &planeLayoutComponent : planeLayout.components) {
655 if (!gralloc4::isStandardPlaneLayoutComponentType(planeLayoutComponent.type)) {
656 continue;
657 }
658
659 uint8_t *tmpData = static_cast<uint8_t *>(data) + planeLayout.offsetInBytes;
660
661 // Note that `offsetInBits` may not be a multiple of 8 for packed formats (e.g. P010)
662 // but we still want to point to the start of the first byte.
663 tmpData += (planeLayoutComponent.offsetInBits / 8);
664
665 uint64_t sampleIncrementInBytes;
666
667 auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
668 switch (type) {
669 case PlaneLayoutComponentType::Y:
670 if ((ycbcr.y != nullptr) || (planeLayout.sampleIncrementInBits % 8 != 0)) {
671 unlock(bufferHandle);
672 return BAD_VALUE;
673 }
674 ycbcr.y = tmpData;
675 ycbcr.ystride = planeLayout.strideInBytes;
676 break;
677
678 case PlaneLayoutComponentType::CB:
679 case PlaneLayoutComponentType::CR:
680 if (planeLayout.sampleIncrementInBits % 8 != 0) {
681 unlock(bufferHandle);
682 return BAD_VALUE;
683 }
684
685 sampleIncrementInBytes = planeLayout.sampleIncrementInBits / 8;
686 if ((sampleIncrementInBytes != 1) && (sampleIncrementInBytes != 2) &&
687 (sampleIncrementInBytes != 4)) {
688 unlock(bufferHandle);
689 return BAD_VALUE;
690 }
691
692 if (ycbcr.cstride == 0 && ycbcr.chroma_step == 0) {
693 ycbcr.cstride = planeLayout.strideInBytes;
694 ycbcr.chroma_step = sampleIncrementInBytes;
695 } else {
696 if ((static_cast<int64_t>(ycbcr.cstride) != planeLayout.strideInBytes) ||
697 (ycbcr.chroma_step != sampleIncrementInBytes)) {
698 unlock(bufferHandle);
699 return BAD_VALUE;
700 }
701 }
702
703 if (type == PlaneLayoutComponentType::CB) {
704 if (ycbcr.cb != nullptr) {
705 unlock(bufferHandle);
706 return BAD_VALUE;
707 }
708 ycbcr.cb = tmpData;
709 } else {
710 if (ycbcr.cr != nullptr) {
711 unlock(bufferHandle);
712 return BAD_VALUE;
713 }
714 ycbcr.cr = tmpData;
715 }
716 break;
717 default:
718 break;
719 };
720 }
721 }
722
723 *outYcbcr = ycbcr;
724 return OK;
725}
726
727int Gralloc5Mapper::unlock(buffer_handle_t bufferHandle) const {
728 int fence = -1;
729 AIMapper_Error error = mMapper->v5.unlock(bufferHandle, &fence);
730 if (error != AIMAPPER_ERROR_NONE) {
731 ALOGW("unlock failed with error %d", error);
732 }
733 return fence;
734}
735
736status_t Gralloc5Mapper::isSupported(uint32_t width, uint32_t height, PixelFormat format,
737 uint32_t layerCount, uint64_t usage,
738 bool *outSupported) const {
739 auto descriptorInfo = makeDescriptor("", width, height, format, layerCount, usage);
740 if (!descriptorInfo) {
741 *outSupported = false;
742 return OK;
743 }
744 auto status = getInstance().allocator->isSupported(*descriptorInfo, outSupported);
745 if (!status.isOk()) {
746 ALOGW("IAllocator::isSupported error %d (%s)", status.getStatus(), status.getMessage());
747 *outSupported = false;
748 }
749 return OK;
750}
751
752status_t Gralloc5Mapper::getBufferId(buffer_handle_t bufferHandle, uint64_t *outBufferId) const {
753 auto value = getStandardMetadata<StandardMetadataType::BUFFER_ID>(mMapper, bufferHandle);
754 if (value.has_value()) {
755 *outBufferId = *value;
756 return OK;
757 }
758 return UNKNOWN_TRANSACTION;
759}
760
761status_t Gralloc5Mapper::getName(buffer_handle_t bufferHandle, std::string *outName) const {
762 auto value = getStandardMetadata<StandardMetadataType::NAME>(mMapper, bufferHandle);
763 if (value.has_value()) {
764 *outName = *value;
765 return OK;
766 }
767 return UNKNOWN_TRANSACTION;
768}
769
770status_t Gralloc5Mapper::getWidth(buffer_handle_t bufferHandle, uint64_t *outWidth) const {
771 auto value = getStandardMetadata<StandardMetadataType::WIDTH>(mMapper, bufferHandle);
772 if (value.has_value()) {
773 *outWidth = *value;
774 return OK;
775 }
776 return UNKNOWN_TRANSACTION;
777}
778
779status_t Gralloc5Mapper::getHeight(buffer_handle_t bufferHandle, uint64_t *outHeight) const {
780 auto value = getStandardMetadata<StandardMetadataType::HEIGHT>(mMapper, bufferHandle);
781 if (value.has_value()) {
782 *outHeight = *value;
783 return OK;
784 }
785 return UNKNOWN_TRANSACTION;
786}
787
788status_t Gralloc5Mapper::getLayerCount(buffer_handle_t bufferHandle,
789 uint64_t *outLayerCount) const {
790 auto value = getStandardMetadata<StandardMetadataType::LAYER_COUNT>(mMapper, bufferHandle);
791 if (value.has_value()) {
792 *outLayerCount = *value;
793 return OK;
794 }
795 return UNKNOWN_TRANSACTION;
796}
797
798status_t Gralloc5Mapper::getPixelFormatRequested(buffer_handle_t bufferHandle,
799 ui::PixelFormat *outPixelFormatRequested) const {
800 auto value = getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_REQUESTED>(mMapper,
801 bufferHandle);
802 if (value.has_value()) {
803 *outPixelFormatRequested = static_cast<ui::PixelFormat>(*value);
804 return OK;
805 }
806 return UNKNOWN_TRANSACTION;
807}
808
809status_t Gralloc5Mapper::getPixelFormatFourCC(buffer_handle_t bufferHandle,
810 uint32_t *outPixelFormatFourCC) const {
811 auto value =
812 getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_FOURCC>(mMapper, bufferHandle);
813 if (value.has_value()) {
814 *outPixelFormatFourCC = *value;
815 return OK;
816 }
817 return UNKNOWN_TRANSACTION;
818}
819
820status_t Gralloc5Mapper::getPixelFormatModifier(buffer_handle_t bufferHandle,
821 uint64_t *outPixelFormatModifier) const {
822 auto value =
823 getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_MODIFIER>(mMapper, bufferHandle);
824 if (value.has_value()) {
825 *outPixelFormatModifier = *value;
826 return OK;
827 }
828 return UNKNOWN_TRANSACTION;
829}
830
831status_t Gralloc5Mapper::getUsage(buffer_handle_t bufferHandle, uint64_t *outUsage) const {
832 auto value = getStandardMetadata<StandardMetadataType::USAGE>(mMapper, bufferHandle);
833 if (value.has_value()) {
834 *outUsage = static_cast<uint64_t>(*value);
835 return OK;
836 }
837 return UNKNOWN_TRANSACTION;
838}
839
840status_t Gralloc5Mapper::getAllocationSize(buffer_handle_t bufferHandle,
841 uint64_t *outAllocationSize) const {
842 auto value = getStandardMetadata<StandardMetadataType::ALLOCATION_SIZE>(mMapper, bufferHandle);
843 if (value.has_value()) {
844 *outAllocationSize = *value;
845 return OK;
846 }
847 return UNKNOWN_TRANSACTION;
848}
849
850status_t Gralloc5Mapper::getProtectedContent(buffer_handle_t bufferHandle,
851 uint64_t *outProtectedContent) const {
852 auto value =
853 getStandardMetadata<StandardMetadataType::PROTECTED_CONTENT>(mMapper, bufferHandle);
854 if (value.has_value()) {
855 *outProtectedContent = *value;
856 return OK;
857 }
858 return UNKNOWN_TRANSACTION;
859}
860
861status_t Gralloc5Mapper::getCompression(
862 buffer_handle_t bufferHandle,
863 aidl::android::hardware::graphics::common::ExtendableType *outCompression) const {
864 auto value = getStandardMetadata<StandardMetadataType::COMPRESSION>(mMapper, bufferHandle);
865 if (value.has_value()) {
866 *outCompression = *value;
867 return OK;
868 }
869 return UNKNOWN_TRANSACTION;
870}
871
872status_t Gralloc5Mapper::getCompression(buffer_handle_t bufferHandle,
873 ui::Compression *outCompression) const {
874 auto value = getStandardMetadata<StandardMetadataType::COMPRESSION>(mMapper, bufferHandle);
875 if (!value.has_value()) {
876 return UNKNOWN_TRANSACTION;
877 }
878 if (!gralloc4::isStandardCompression(*value)) {
879 return BAD_TYPE;
880 }
881 *outCompression = gralloc4::getStandardCompressionValue(*value);
882 return OK;
883}
884
885status_t Gralloc5Mapper::getInterlaced(
886 buffer_handle_t bufferHandle,
887 aidl::android::hardware::graphics::common::ExtendableType *outInterlaced) const {
888 auto value = getStandardMetadata<StandardMetadataType::INTERLACED>(mMapper, bufferHandle);
889 if (value.has_value()) {
890 *outInterlaced = *value;
891 return OK;
892 }
893 return UNKNOWN_TRANSACTION;
894}
895
896status_t Gralloc5Mapper::getInterlaced(buffer_handle_t bufferHandle,
897 ui::Interlaced *outInterlaced) const {
898 if (!outInterlaced) {
899 return BAD_VALUE;
900 }
901 ExtendableType interlaced;
902 status_t error = getInterlaced(bufferHandle, &interlaced);
903 if (error) {
904 return error;
905 }
906 if (!gralloc4::isStandardInterlaced(interlaced)) {
907 return BAD_TYPE;
908 }
909 *outInterlaced = gralloc4::getStandardInterlacedValue(interlaced);
910 return NO_ERROR;
911}
912
913status_t Gralloc5Mapper::getChromaSiting(
914 buffer_handle_t bufferHandle,
915 aidl::android::hardware::graphics::common::ExtendableType *outChromaSiting) const {
916 auto value = getStandardMetadata<StandardMetadataType::CHROMA_SITING>(mMapper, bufferHandle);
917 if (value.has_value()) {
918 *outChromaSiting = *value;
919 return OK;
920 }
921 return UNKNOWN_TRANSACTION;
922}
923
924status_t Gralloc5Mapper::getChromaSiting(buffer_handle_t bufferHandle,
925 ui::ChromaSiting *outChromaSiting) const {
926 if (!outChromaSiting) {
927 return BAD_VALUE;
928 }
929 ExtendableType chromaSiting;
930 status_t error = getChromaSiting(bufferHandle, &chromaSiting);
931 if (error) {
932 return error;
933 }
934 if (!gralloc4::isStandardChromaSiting(chromaSiting)) {
935 return BAD_TYPE;
936 }
937 *outChromaSiting = gralloc4::getStandardChromaSitingValue(chromaSiting);
938 return NO_ERROR;
939}
940
941status_t Gralloc5Mapper::getPlaneLayouts(buffer_handle_t bufferHandle,
942 std::vector<ui::PlaneLayout> *outPlaneLayouts) const {
943 auto value = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(mMapper, bufferHandle);
944 if (value.has_value()) {
945 *outPlaneLayouts = *value;
946 return OK;
947 }
948 return UNKNOWN_TRANSACTION;
949}
950
951status_t Gralloc5Mapper::getDataspace(buffer_handle_t bufferHandle,
952 ui::Dataspace *outDataspace) const {
953 auto value = getStandardMetadata<StandardMetadataType::DATASPACE>(mMapper, bufferHandle);
954 if (value.has_value()) {
955 *outDataspace = static_cast<ui::Dataspace>(*value);
956 return OK;
957 }
958 return UNKNOWN_TRANSACTION;
959}
960
961status_t Gralloc5Mapper::setDataspace(buffer_handle_t bufferHandle, ui::Dataspace dataspace) const {
962 return setStandardMetadata<StandardMetadataType::DATASPACE>(mMapper, bufferHandle,
963 static_cast<Dataspace>(dataspace));
964}
965
966status_t Gralloc5Mapper::getBlendMode(buffer_handle_t bufferHandle,
967 ui::BlendMode *outBlendMode) const {
968 auto value = getStandardMetadata<StandardMetadataType::BLEND_MODE>(mMapper, bufferHandle);
969 if (value.has_value()) {
970 *outBlendMode = static_cast<ui::BlendMode>(*value);
971 return OK;
972 }
973 return UNKNOWN_TRANSACTION;
974}
975
976status_t Gralloc5Mapper::getSmpte2086(buffer_handle_t bufferHandle,
977 std::optional<ui::Smpte2086> *outSmpte2086) const {
978 auto value = getStandardMetadata<StandardMetadataType::SMPTE2086>(mMapper, bufferHandle);
979 if (value.has_value()) {
980 *outSmpte2086 = *value;
981 return OK;
982 }
983 return UNKNOWN_TRANSACTION;
984}
985
986status_t Gralloc5Mapper::setSmpte2086(buffer_handle_t bufferHandle,
987 std::optional<ui::Smpte2086> smpte2086) const {
988 return setStandardMetadata<StandardMetadataType::SMPTE2086>(mMapper, bufferHandle, smpte2086);
989}
990
991status_t Gralloc5Mapper::getCta861_3(buffer_handle_t bufferHandle,
992 std::optional<ui::Cta861_3> *outCta861_3) const {
993 auto value = getStandardMetadata<StandardMetadataType::CTA861_3>(mMapper, bufferHandle);
994 if (value.has_value()) {
995 *outCta861_3 = *value;
996 return OK;
997 }
998 return UNKNOWN_TRANSACTION;
999}
1000
1001status_t Gralloc5Mapper::setCta861_3(buffer_handle_t bufferHandle,
1002 std::optional<ui::Cta861_3> cta861_3) const {
1003 return setStandardMetadata<StandardMetadataType::CTA861_3>(mMapper, bufferHandle, cta861_3);
1004}
1005
1006status_t Gralloc5Mapper::getSmpte2094_40(
1007 buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>> *outSmpte2094_40) const {
1008 auto value = getStandardMetadata<StandardMetadataType::SMPTE2094_40>(mMapper, bufferHandle);
1009 if (value.has_value()) {
1010 *outSmpte2094_40 = std::move(*value);
1011 return OK;
1012 }
1013 return UNKNOWN_TRANSACTION;
1014}
1015
1016status_t Gralloc5Mapper::setSmpte2094_40(buffer_handle_t bufferHandle,
1017 std::optional<std::vector<uint8_t>> smpte2094_40) const {
1018 return setStandardMetadata<StandardMetadataType::SMPTE2094_40>(mMapper, bufferHandle,
1019 smpte2094_40);
1020}
1021
1022status_t Gralloc5Mapper::getSmpte2094_10(
1023 buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>> *outSmpte2094_10) const {
1024 auto value = getStandardMetadata<StandardMetadataType::SMPTE2094_10>(mMapper, bufferHandle);
1025 if (value.has_value()) {
1026 *outSmpte2094_10 = std::move(*value);
1027 return OK;
1028 }
1029 return UNKNOWN_TRANSACTION;
1030}
1031
1032status_t Gralloc5Mapper::setSmpte2094_10(buffer_handle_t bufferHandle,
1033 std::optional<std::vector<uint8_t>> smpte2094_10) const {
1034 return setStandardMetadata<StandardMetadataType::SMPTE2094_10>(mMapper, bufferHandle,
1035 smpte2094_10);
1036}
1037
John Reck0ff95c92022-12-08 11:45:29 -05001038} // namespace android