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