• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 The Chromium OS Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6 
7 #include <aidl/android/hardware/graphics/allocator/BufferDescriptorInfo.h>
8 #include <aidl/android/hardware/graphics/common/BufferUsage.h>
9 #include <aidl/android/hardware/graphics/common/PixelFormat.h>
10 #include <aidl/android/hardware/graphics/common/StandardMetadataType.h>
11 #include <android-base/unique_fd.h>
12 #include <android/hardware/graphics/mapper/IMapper.h>
13 #include <android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h>
14 #include <android/hardware/graphics/mapper/utils/IMapperProvider.h>
15 #include <cutils/native_handle.h>
16 #include <gralloctypes/Gralloc4.h>
17 
18 #include "cros_gralloc/cros_gralloc_driver.h"
19 #include "cros_gralloc/cros_gralloc_handle.h"
20 #include "cros_gralloc/gralloc4/CrosGralloc4Metadata.h"
21 #include "cros_gralloc/gralloc4/CrosGralloc4Utils.h"
22 
23 using namespace ::aidl::android::hardware::graphics::common;
24 using namespace ::android::hardware::graphics::mapper;
25 using ::aidl::android::hardware::graphics::allocator::BufferDescriptorInfo;
26 using ::android::base::unique_fd;
27 
28 #define REQUIRE_DRIVER()                                           \
29     if (!mDriver) {                                                \
30         ALOGE("Failed to %s. Driver is uninitialized.", __func__); \
31         return AIMAPPER_ERROR_NO_RESOURCES;                        \
32     }
33 
34 #define VALIDATE_BUFFER_HANDLE(bufferHandle)                    \
35     if (!(bufferHandle)) {                                      \
36         ALOGE("Failed to %s. Null buffer_handle_t.", __func__); \
37         return AIMAPPER_ERROR_BAD_BUFFER;                       \
38     }
39 
40 #define VALIDATE_DRIVER_AND_BUFFER_HANDLE(bufferHandle) \
41     REQUIRE_DRIVER()                                    \
42     VALIDATE_BUFFER_HANDLE(bufferHandle)
43 
44 static_assert(CROS_GRALLOC4_METADATA_MAX_NAME_SIZE >=
45                       decltype(std::declval<BufferDescriptorInfo>().name){}.size(),
46               "Metadata name storage too small to fit a BufferDescriptorInfo::name");
47 
48 constexpr const char* STANDARD_METADATA_NAME =
49         "android.hardware.graphics.common.StandardMetadataType";
50 
isStandardMetadata(AIMapper_MetadataType metadataType)51 static bool isStandardMetadata(AIMapper_MetadataType metadataType) {
52     return strcmp(STANDARD_METADATA_NAME, metadataType.name) == 0;
53 }
54 
55 class CrosGrallocMapperV5 final : public vendor::mapper::IMapperV5Impl {
56   private:
57     cros_gralloc_driver* mDriver = cros_gralloc_driver::get_instance();
58 
59   public:
60     explicit CrosGrallocMapperV5() = default;
61     ~CrosGrallocMapperV5() override = default;
62 
63     AIMapper_Error importBuffer(const native_handle_t* _Nonnull handle,
64                                 buffer_handle_t _Nullable* _Nonnull outBufferHandle) override;
65 
66     AIMapper_Error freeBuffer(buffer_handle_t _Nonnull buffer) override;
67 
68     AIMapper_Error getTransportSize(buffer_handle_t _Nonnull buffer, uint32_t* _Nonnull outNumFds,
69                                     uint32_t* _Nonnull outNumInts) override;
70 
71     AIMapper_Error lock(buffer_handle_t _Nonnull buffer, uint64_t cpuUsage, ARect accessRegion,
72                         int acquireFence, void* _Nullable* _Nonnull outData) override;
73 
74     AIMapper_Error unlock(buffer_handle_t _Nonnull buffer, int* _Nonnull releaseFence) override;
75 
76     AIMapper_Error flushLockedBuffer(buffer_handle_t _Nonnull buffer) override;
77 
78     AIMapper_Error rereadLockedBuffer(buffer_handle_t _Nonnull buffer) override;
79 
80     int32_t getMetadata(buffer_handle_t _Nonnull buffer, AIMapper_MetadataType metadataType,
81                         void* _Nonnull outData, size_t outDataSize) override;
82 
83     int32_t getStandardMetadata(buffer_handle_t _Nonnull buffer, int64_t standardMetadataType,
84                                 void* _Nonnull outData, size_t outDataSize) override;
85 
86     AIMapper_Error setMetadata(buffer_handle_t _Nonnull buffer, AIMapper_MetadataType metadataType,
87                                const void* _Nonnull metadata, size_t metadataSize) override;
88 
89     AIMapper_Error setStandardMetadata(buffer_handle_t _Nonnull buffer,
90                                        int64_t standardMetadataType, const void* _Nonnull metadata,
91                                        size_t metadataSize) override;
92 
93     AIMapper_Error listSupportedMetadataTypes(
94             const AIMapper_MetadataTypeDescription* _Nullable* _Nonnull outDescriptionList,
95             size_t* _Nonnull outNumberOfDescriptions) override;
96 
97     AIMapper_Error dumpBuffer(buffer_handle_t _Nonnull bufferHandle,
98                               AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
99                               void* _Null_unspecified context) override;
100 
101     AIMapper_Error dumpAllBuffers(AIMapper_BeginDumpBufferCallback _Nonnull beginDumpBufferCallback,
102                                   AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
103                                   void* _Null_unspecified context) override;
104 
105     AIMapper_Error getReservedRegion(buffer_handle_t _Nonnull buffer,
106                                      void* _Nullable* _Nonnull outReservedRegion,
107                                      uint64_t* _Nonnull outReservedSize) override;
108 
109   private:
110     enum class ReservedRegionArea {
111         /* CrosGralloc4Metadata */
112         MAPPER4_METADATA,
113 
114         /* External user metadata */
115         USER_METADATA,
116     };
117 
118     AIMapper_Error getReservedRegionArea(const cros_gralloc_buffer* crosBuffer,
119                                          ReservedRegionArea area, void** outAddr,
120                                          uint64_t* outSize);
121 
122     AIMapper_Error getCrosMetadata(const cros_gralloc_buffer* crosBuffer,
123                                    const CrosGralloc4Metadata** outMetadata);
124 
125     AIMapper_Error getMutableCrosMetadata(cros_gralloc_buffer* crosBuffer,
126                                           CrosGralloc4Metadata** outMetadata);
127 
128     template <typename F, StandardMetadataType TYPE>
129     int32_t getStandardMetadata(const cros_gralloc_buffer* crosBuffer, F&& provide,
130                                 StandardMetadata<TYPE>);
131 
132     template <StandardMetadataType TYPE>
133     AIMapper_Error setStandardMetadata(CrosGralloc4Metadata* crosMetadata,
134                                        typename StandardMetadata<TYPE>::value_type&& value);
135 
136     void dumpBuffer(
137             const cros_gralloc_buffer* crosBuffer,
138             std::function<void(AIMapper_MetadataType, const std::vector<uint8_t>&)> callback);
139 };
140 
importBuffer(const native_handle_t * _Nonnull bufferHandle,buffer_handle_t _Nullable * _Nonnull outBufferHandle)141 AIMapper_Error CrosGrallocMapperV5::importBuffer(
142         const native_handle_t* _Nonnull bufferHandle,
143         buffer_handle_t _Nullable* _Nonnull outBufferHandle) {
144     REQUIRE_DRIVER()
145 
146     if (!bufferHandle || bufferHandle->numFds == 0) {
147         ALOGE("Failed to importBuffer. Bad handle.");
148         return AIMAPPER_ERROR_BAD_BUFFER;
149     }
150 
151     native_handle_t* importedBufferHandle = native_handle_clone(bufferHandle);
152     if (!importedBufferHandle) {
153         ALOGE("Failed to importBuffer. Handle clone failed: %s.", strerror(errno));
154         return AIMAPPER_ERROR_NO_RESOURCES;
155     }
156 
157     int ret = mDriver->retain(importedBufferHandle);
158     if (ret) {
159         native_handle_close(importedBufferHandle);
160         native_handle_delete(importedBufferHandle);
161         return AIMAPPER_ERROR_NO_RESOURCES;
162     }
163 
164     *outBufferHandle = importedBufferHandle;
165     return AIMAPPER_ERROR_NONE;
166 }
167 
freeBuffer(buffer_handle_t _Nonnull buffer)168 AIMapper_Error CrosGrallocMapperV5::freeBuffer(buffer_handle_t _Nonnull buffer) {
169     VALIDATE_DRIVER_AND_BUFFER_HANDLE(buffer)
170 
171     int ret = mDriver->release(buffer);
172     if (ret) {
173         return AIMAPPER_ERROR_BAD_BUFFER;
174     }
175 
176     native_handle_close(buffer);
177     native_handle_delete(const_cast<native_handle_t*>(buffer));
178     return AIMAPPER_ERROR_NONE;
179 }
180 
getTransportSize(buffer_handle_t _Nonnull bufferHandle,uint32_t * _Nonnull outNumFds,uint32_t * _Nonnull outNumInts)181 AIMapper_Error CrosGrallocMapperV5::getTransportSize(buffer_handle_t _Nonnull bufferHandle,
182                                                      uint32_t* _Nonnull outNumFds,
183                                                      uint32_t* _Nonnull outNumInts) {
184     VALIDATE_DRIVER_AND_BUFFER_HANDLE(bufferHandle)
185 
186     // No local process data is currently stored on the native handle.
187     *outNumFds = bufferHandle->numFds;
188     *outNumInts = bufferHandle->numInts;
189     return AIMAPPER_ERROR_NONE;
190 }
191 
lock(buffer_handle_t _Nonnull bufferHandle,uint64_t cpuUsage,ARect region,int acquireFenceRawFd,void * _Nullable * _Nonnull outData)192 AIMapper_Error CrosGrallocMapperV5::lock(buffer_handle_t _Nonnull bufferHandle, uint64_t cpuUsage,
193                                          ARect region, int acquireFenceRawFd,
194                                          void* _Nullable* _Nonnull outData) {
195     // We take ownership of the FD in all cases, even for errors
196     unique_fd acquireFence(acquireFenceRawFd);
197     VALIDATE_DRIVER_AND_BUFFER_HANDLE(bufferHandle)
198     if (cpuUsage == 0) {
199         ALOGE("Failed to lock. Bad cpu usage: %" PRIu64 ".", cpuUsage);
200         return AIMAPPER_ERROR_BAD_VALUE;
201     }
202 
203     uint32_t mapUsage = cros_gralloc_convert_map_usage(cpuUsage);
204 
205     cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
206     if (crosHandle == nullptr) {
207         ALOGE("Failed to lock. Invalid handle.");
208         return AIMAPPER_ERROR_BAD_VALUE;
209     }
210 
211     struct rectangle rect;
212 
213     // An access region of all zeros means the entire buffer.
214     if (region.left == 0 && region.top == 0 && region.right == 0 && region.bottom == 0) {
215         rect = {0, 0, crosHandle->width, crosHandle->height};
216     } else {
217         if (region.left < 0 || region.top < 0 || region.right <= region.left ||
218             region.bottom <= region.top) {
219             ALOGE("Failed to lock. Invalid accessRegion: [%d, %d, %d, %d]", region.left, region.top,
220                   region.right, region.bottom);
221             return AIMAPPER_ERROR_BAD_VALUE;
222         }
223 
224         if (region.right > crosHandle->width) {
225             ALOGE("Failed to lock. Invalid region: width greater than buffer width (%d vs %d).",
226                   region.right, crosHandle->width);
227             return AIMAPPER_ERROR_BAD_VALUE;
228         }
229 
230         if (region.bottom > crosHandle->height) {
231             ALOGE("Failed to lock. Invalid region: height greater than buffer height (%d vs "
232                   "%d).",
233                   region.bottom, crosHandle->height);
234             return AIMAPPER_ERROR_BAD_VALUE;
235         }
236 
237         rect = {static_cast<uint32_t>(region.left), static_cast<uint32_t>(region.top),
238                 static_cast<uint32_t>(region.right - region.left),
239                 static_cast<uint32_t>(region.bottom - region.top)};
240     }
241 
242     uint8_t* addr[DRV_MAX_PLANES];
243     int32_t status = mDriver->lock(bufferHandle, acquireFence.get(),
244                                    /*close_acquire_fence=*/false, &rect, mapUsage, addr);
245     if (status) {
246         return AIMAPPER_ERROR_BAD_VALUE;
247     }
248 
249     *outData = addr[0];
250     return AIMAPPER_ERROR_NONE;
251 }
252 
unlock(buffer_handle_t _Nonnull buffer,int * _Nonnull releaseFence)253 AIMapper_Error CrosGrallocMapperV5::unlock(buffer_handle_t _Nonnull buffer,
254                                            int* _Nonnull releaseFence) {
255     VALIDATE_DRIVER_AND_BUFFER_HANDLE(buffer)
256     int ret = mDriver->unlock(buffer, releaseFence);
257     if (ret) {
258         ALOGE("Failed to unlock.");
259         return AIMAPPER_ERROR_BAD_BUFFER;
260     }
261     return AIMAPPER_ERROR_NONE;
262 }
263 
flushLockedBuffer(buffer_handle_t _Nonnull buffer)264 AIMapper_Error CrosGrallocMapperV5::flushLockedBuffer(buffer_handle_t _Nonnull buffer) {
265     VALIDATE_DRIVER_AND_BUFFER_HANDLE(buffer)
266     int ret = mDriver->flush(buffer);
267     if (ret) {
268         ALOGE("Failed to flushLockedBuffer. Flush failed.");
269         return AIMAPPER_ERROR_BAD_BUFFER;
270     }
271     return AIMAPPER_ERROR_NONE;
272 }
273 
rereadLockedBuffer(buffer_handle_t _Nonnull buffer)274 AIMapper_Error CrosGrallocMapperV5::rereadLockedBuffer(buffer_handle_t _Nonnull buffer) {
275     VALIDATE_DRIVER_AND_BUFFER_HANDLE(buffer)
276     int ret = mDriver->invalidate(buffer);
277     if (ret) {
278         ALOGE("Failed to rereadLockedBuffer. Failed to invalidate.");
279         return AIMAPPER_ERROR_BAD_BUFFER;
280     }
281 
282     return AIMAPPER_ERROR_NONE;
283 }
284 
getMetadata(buffer_handle_t _Nonnull buffer,AIMapper_MetadataType metadataType,void * _Nonnull outData,size_t outDataSize)285 int32_t CrosGrallocMapperV5::getMetadata(buffer_handle_t _Nonnull buffer,
286                                          AIMapper_MetadataType metadataType, void* _Nonnull outData,
287                                          size_t outDataSize) {
288     // We don't have any vendor-specific metadata, so divert to getStandardMetadata after validating
289     // that this is a standard metadata request
290     if (isStandardMetadata(metadataType)) {
291         return getStandardMetadata(buffer, metadataType.value, outData, outDataSize);
292     }
293     return -AIMAPPER_ERROR_UNSUPPORTED;
294 }
295 
getStandardMetadata(buffer_handle_t _Nonnull bufferHandle,int64_t standardType,void * _Nonnull outData,size_t outDataSize)296 int32_t CrosGrallocMapperV5::getStandardMetadata(buffer_handle_t _Nonnull bufferHandle,
297                                                  int64_t standardType, void* _Nonnull outData,
298                                                  size_t outDataSize) {
299     // Can't use VALIDATE_DRIVER_AND_BUFFER_HANDLE because we need to negate the error
300     // for this call
301     if (!mDriver) {
302         ALOGE("Failed to %s. Driver is uninitialized.", __func__);
303         return -AIMAPPER_ERROR_NO_RESOURCES;
304     }
305     if (!(bufferHandle)) {
306         ALOGE("Failed to %s. Null buffer_handle_t.", __func__);
307         return -AIMAPPER_ERROR_BAD_BUFFER;
308     }
309 
310     cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
311     if (!crosHandle) {
312         ALOGE("Failed to get. Invalid handle.");
313         return -AIMAPPER_ERROR_BAD_BUFFER;
314     }
315 
316     int32_t retValue = -AIMAPPER_ERROR_UNSUPPORTED;
317     mDriver->with_buffer(crosHandle, [&](cros_gralloc_buffer* crosBuffer) {
318         auto provider = [&]<StandardMetadataType T>(auto&& provide) -> int32_t {
319             return getStandardMetadata(crosBuffer, provide, StandardMetadata<T>{});
320         };
321         retValue = provideStandardMetadata(static_cast<StandardMetadataType>(standardType), outData,
322                                            outDataSize, provider);
323     });
324     return retValue;
325 }
326 
327 template <typename F, StandardMetadataType metadataType>
getStandardMetadata(const cros_gralloc_buffer * crosBuffer,F && provide,StandardMetadata<metadataType>)328 int32_t CrosGrallocMapperV5::getStandardMetadata(const cros_gralloc_buffer* crosBuffer, F&& provide,
329                                                  StandardMetadata<metadataType>) {
330     const CrosGralloc4Metadata* crosMetadata = nullptr;
331     if constexpr (metadataType == StandardMetadataType::BLEND_MODE ||
332                   metadataType == StandardMetadataType::CTA861_3 ||
333                   metadataType == StandardMetadataType::DATASPACE ||
334                   metadataType == StandardMetadataType::NAME ||
335                   metadataType == StandardMetadataType::SMPTE2086) {
336         AIMapper_Error error = getCrosMetadata(crosBuffer, &crosMetadata);
337         if (error != AIMAPPER_ERROR_NONE) {
338             ALOGE("Failed to get. Failed to get buffer metadata.");
339             return -AIMAPPER_ERROR_NO_RESOURCES;
340         }
341     }
342     if constexpr (metadataType == StandardMetadataType::BUFFER_ID) {
343         return provide(crosBuffer->get_id());
344     }
345     if constexpr (metadataType == StandardMetadataType::NAME) {
346         return provide(crosMetadata->name);
347     }
348     if constexpr (metadataType == StandardMetadataType::WIDTH) {
349         return provide(crosBuffer->get_width());
350     }
351     if constexpr (metadataType == StandardMetadataType::STRIDE) {
352         return provide(crosBuffer->get_pixel_stride());
353     }
354     if constexpr (metadataType == StandardMetadataType::HEIGHT) {
355         return provide(crosBuffer->get_height());
356     }
357     if constexpr (metadataType == StandardMetadataType::LAYER_COUNT) {
358         return provide(1);
359     }
360     if constexpr (metadataType == StandardMetadataType::PIXEL_FORMAT_REQUESTED) {
361         return provide(static_cast<PixelFormat>(crosBuffer->get_android_format()));
362     }
363     if constexpr (metadataType == StandardMetadataType::PIXEL_FORMAT_FOURCC) {
364         return provide(drv_get_standard_fourcc(crosBuffer->get_format()));
365     }
366     if constexpr (metadataType == StandardMetadataType::PIXEL_FORMAT_MODIFIER) {
367         return provide(crosBuffer->get_format_modifier());
368     }
369     if constexpr (metadataType == StandardMetadataType::USAGE) {
370         return provide(static_cast<BufferUsage>(crosBuffer->get_android_usage()));
371     }
372     if constexpr (metadataType == StandardMetadataType::ALLOCATION_SIZE) {
373         return provide(crosBuffer->get_total_size());
374     }
375     if constexpr (metadataType == StandardMetadataType::PROTECTED_CONTENT) {
376         uint64_t hasProtectedContent =
377                 crosBuffer->get_android_usage() & static_cast<int64_t>(BufferUsage::PROTECTED) ? 1
378                                                                                                : 0;
379         return provide(hasProtectedContent);
380     }
381     if constexpr (metadataType == StandardMetadataType::COMPRESSION) {
382         return provide(android::gralloc4::Compression_None);
383     }
384     if constexpr (metadataType == StandardMetadataType::INTERLACED) {
385         return provide(android::gralloc4::Interlaced_None);
386     }
387     if constexpr (metadataType == StandardMetadataType::CHROMA_SITING) {
388         return provide(android::gralloc4::ChromaSiting_None);
389     }
390     if constexpr (metadataType == StandardMetadataType::PLANE_LAYOUTS) {
391         std::vector<PlaneLayout> planeLayouts;
392         getPlaneLayouts(crosBuffer->get_format(), &planeLayouts);
393 
394         for (size_t plane = 0; plane < planeLayouts.size(); plane++) {
395             PlaneLayout& planeLayout = planeLayouts[plane];
396             planeLayout.offsetInBytes = crosBuffer->get_plane_offset(plane);
397             planeLayout.strideInBytes = crosBuffer->get_plane_stride(plane);
398             planeLayout.totalSizeInBytes = crosBuffer->get_plane_size(plane);
399             planeLayout.widthInSamples =
400                     crosBuffer->get_width() / planeLayout.horizontalSubsampling;
401             planeLayout.heightInSamples =
402                     crosBuffer->get_height() / planeLayout.verticalSubsampling;
403         }
404 
405         return provide(planeLayouts);
406     }
407     if constexpr (metadataType == StandardMetadataType::CROP) {
408         const uint32_t numPlanes = crosBuffer->get_num_planes();
409         const uint32_t w = crosBuffer->get_width();
410         const uint32_t h = crosBuffer->get_height();
411         std::vector<aidl::android::hardware::graphics::common::Rect> crops;
412         for (uint32_t plane = 0; plane < numPlanes; plane++) {
413             aidl::android::hardware::graphics::common::Rect crop;
414             crop.left = 0;
415             crop.top = 0;
416             crop.right = w;
417             crop.bottom = h;
418             crops.push_back(crop);
419         }
420 
421         return provide(crops);
422     }
423     if constexpr (metadataType == StandardMetadataType::DATASPACE) {
424         return provide(crosMetadata->dataspace);
425     }
426     if constexpr (metadataType == StandardMetadataType::BLEND_MODE) {
427         return provide(crosMetadata->blendMode);
428     }
429     if constexpr (metadataType == StandardMetadataType::SMPTE2086) {
430         return crosMetadata->smpte2086 ? provide(*crosMetadata->smpte2086) : 0;
431     }
432     if constexpr (metadataType == StandardMetadataType::CTA861_3) {
433         return crosMetadata->cta861_3 ? provide(*crosMetadata->cta861_3) : 0;
434     }
435     return -AIMAPPER_ERROR_UNSUPPORTED;
436 }
437 
setMetadata(buffer_handle_t _Nonnull buffer,AIMapper_MetadataType metadataType,const void * _Nonnull metadata,size_t metadataSize)438 AIMapper_Error CrosGrallocMapperV5::setMetadata(buffer_handle_t _Nonnull buffer,
439                                                 AIMapper_MetadataType metadataType,
440                                                 const void* _Nonnull metadata,
441                                                 size_t metadataSize) {
442     // We don't have any vendor-specific metadata, so divert to setStandardMetadata after validating
443     // that this is a standard metadata request
444     if (isStandardMetadata(metadataType)) {
445         return setStandardMetadata(buffer, metadataType.value, metadata, metadataSize);
446     }
447     return AIMAPPER_ERROR_UNSUPPORTED;
448 }
449 
setStandardMetadata(buffer_handle_t _Nonnull bufferHandle,int64_t standardTypeRaw,const void * _Nonnull metadata,size_t metadataSize)450 AIMapper_Error CrosGrallocMapperV5::setStandardMetadata(buffer_handle_t _Nonnull bufferHandle,
451                                                         int64_t standardTypeRaw,
452                                                         const void* _Nonnull metadata,
453                                                         size_t metadataSize) {
454     VALIDATE_DRIVER_AND_BUFFER_HANDLE(bufferHandle)
455 
456     cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
457     if (!crosHandle) {
458         ALOGE("Failed to get. Invalid handle.");
459         return AIMAPPER_ERROR_BAD_BUFFER;
460     }
461 
462     auto standardType = static_cast<StandardMetadataType>(standardTypeRaw);
463 
464     switch (standardType) {
465         // Read-only values
466         case StandardMetadataType::BUFFER_ID:
467         case StandardMetadataType::NAME:
468         case StandardMetadataType::WIDTH:
469         case StandardMetadataType::HEIGHT:
470         case StandardMetadataType::LAYER_COUNT:
471         case StandardMetadataType::PIXEL_FORMAT_REQUESTED:
472         case StandardMetadataType::USAGE:
473             return AIMAPPER_ERROR_BAD_VALUE;
474 
475         // Supported to set
476         case StandardMetadataType::BLEND_MODE:
477         case StandardMetadataType::CTA861_3:
478         case StandardMetadataType::DATASPACE:
479         case StandardMetadataType::SMPTE2086:
480             break;
481 
482         // Everything else unsupported
483         default:
484             return AIMAPPER_ERROR_UNSUPPORTED;
485     }
486 
487     AIMapper_Error status = AIMAPPER_ERROR_UNSUPPORTED;
488     mDriver->with_buffer(crosHandle, [&](cros_gralloc_buffer* crosBuffer) {
489         CrosGralloc4Metadata* crosMetadata = nullptr;
490         status = getMutableCrosMetadata(crosBuffer, &crosMetadata);
491         if (status != AIMAPPER_ERROR_NONE) {
492             return;
493         }
494 
495         auto applier = [&]<StandardMetadataType T>(auto&& value) -> AIMapper_Error {
496             return setStandardMetadata<T>(crosMetadata, std::forward<decltype(value)>(value));
497         };
498 
499         status = applyStandardMetadata(standardType, metadata, metadataSize, applier);
500     });
501     return status;
502 }
503 
504 template <StandardMetadataType TYPE>
setStandardMetadata(CrosGralloc4Metadata * crosMetadata,typename StandardMetadata<TYPE>::value_type && value)505 AIMapper_Error CrosGrallocMapperV5::setStandardMetadata(
506         CrosGralloc4Metadata* crosMetadata, typename StandardMetadata<TYPE>::value_type&& value) {
507     if constexpr (TYPE == StandardMetadataType::BLEND_MODE) {
508         crosMetadata->blendMode = value;
509     }
510     if constexpr (TYPE == StandardMetadataType::CTA861_3) {
511         crosMetadata->cta861_3 = value;
512     }
513     if constexpr (TYPE == StandardMetadataType::DATASPACE) {
514         crosMetadata->dataspace = value;
515     }
516     if constexpr (TYPE == StandardMetadataType::SMPTE2086) {
517         crosMetadata->smpte2086 = value;
518     }
519     // Unsupported metadatas were already filtered before we reached this point
520     return AIMAPPER_ERROR_NONE;
521 }
522 
describeStandard(StandardMetadataType type,bool isGettable,bool isSettable)523 constexpr AIMapper_MetadataTypeDescription describeStandard(StandardMetadataType type,
524                                                             bool isGettable, bool isSettable) {
525     return {{STANDARD_METADATA_NAME, static_cast<int64_t>(type)},
526             nullptr,
527             isGettable,
528             isSettable,
529             {0}};
530 }
531 
listSupportedMetadataTypes(const AIMapper_MetadataTypeDescription * _Nullable * _Nonnull outDescriptionList,size_t * _Nonnull outNumberOfDescriptions)532 AIMapper_Error CrosGrallocMapperV5::listSupportedMetadataTypes(
533         const AIMapper_MetadataTypeDescription* _Nullable* _Nonnull outDescriptionList,
534         size_t* _Nonnull outNumberOfDescriptions) {
535     static constexpr std::array<AIMapper_MetadataTypeDescription, 22> sSupportedMetadaTypes{
536             describeStandard(StandardMetadataType::BUFFER_ID, true, false),
537             describeStandard(StandardMetadataType::NAME, true, false),
538             describeStandard(StandardMetadataType::WIDTH, true, false),
539             describeStandard(StandardMetadataType::HEIGHT, true, false),
540             describeStandard(StandardMetadataType::LAYER_COUNT, true, false),
541             describeStandard(StandardMetadataType::PIXEL_FORMAT_REQUESTED, true, false),
542             describeStandard(StandardMetadataType::PIXEL_FORMAT_FOURCC, true, false),
543             describeStandard(StandardMetadataType::PIXEL_FORMAT_MODIFIER, true, false),
544             describeStandard(StandardMetadataType::USAGE, true, false),
545             describeStandard(StandardMetadataType::ALLOCATION_SIZE, true, false),
546             describeStandard(StandardMetadataType::PROTECTED_CONTENT, true, false),
547             describeStandard(StandardMetadataType::COMPRESSION, true, false),
548             describeStandard(StandardMetadataType::INTERLACED, true, false),
549             describeStandard(StandardMetadataType::CHROMA_SITING, true, false),
550             describeStandard(StandardMetadataType::PLANE_LAYOUTS, true, false),
551             describeStandard(StandardMetadataType::CROP, true, false),
552             describeStandard(StandardMetadataType::DATASPACE, true, true),
553             describeStandard(StandardMetadataType::COMPRESSION, true, false),
554             describeStandard(StandardMetadataType::BLEND_MODE, true, true),
555             describeStandard(StandardMetadataType::SMPTE2086, true, true),
556             describeStandard(StandardMetadataType::CTA861_3, true, true),
557             describeStandard(StandardMetadataType::STRIDE, true, false),
558     };
559     *outDescriptionList = sSupportedMetadaTypes.data();
560     *outNumberOfDescriptions = sSupportedMetadaTypes.size();
561     return AIMAPPER_ERROR_NONE;
562 }
563 
dumpBuffer(const cros_gralloc_buffer * crosBuffer,std::function<void (AIMapper_MetadataType,const std::vector<uint8_t> &)> callback)564 void CrosGrallocMapperV5::dumpBuffer(
565         const cros_gralloc_buffer* crosBuffer,
566         std::function<void(AIMapper_MetadataType, const std::vector<uint8_t>&)> callback) {
567     // Temp buffer of ~10kb, should be large enough for any of the metadata we want to dump
568     std::vector<uint8_t> tempBuffer;
569     tempBuffer.resize(10000);
570     AIMapper_MetadataType metadataType;
571     metadataType.name = STANDARD_METADATA_NAME;
572 
573     // Take an instance of the empty StandardMetadat<T> class just to allow auto-deduction
574     // to happen as explicit template invocation on lambdas is ugly
575     auto dump = [&]<StandardMetadataType T>(StandardMetadata<T>) {
576         // Nested templated lambdas! Woo! But the cleanness of the result is worth it
577         // The outer lambda exists basically just to capture the StandardMetadataType that's
578         // being dumped, as the `provider` parameter of getStandardMetadata only knows
579         // the value_type that the enum maps to but not the enum value itself, which we need to
580         // construct the `AIMapper_MetadataType` to pass to the dump callback
581         auto dumpInner = [&](const typename StandardMetadata<T>::value_type& value) -> int32_t {
582             int32_t size =
583                     StandardMetadata<T>::value::encode(value, tempBuffer.data(), tempBuffer.size());
584             // The initial size should always be large enough, but just in case...
585             if (size > tempBuffer.size()) {
586                 tempBuffer.resize(size * 2);
587                 size = StandardMetadata<T>::value::encode(value, tempBuffer.data(),
588                                                           tempBuffer.size());
589             }
590             // If the first resize failed _somehow_, just give up. Also don't notify if any
591             // errors occurred during encoding.
592             if (size >= 0 && size <= tempBuffer.size()) {
593                 metadataType.value = static_cast<int64_t>(T);
594                 callback(metadataType, tempBuffer);
595             }
596             // We don't actually care about the return value in this case, but why not use the
597             // real value anyway
598             return size;
599         };
600         getStandardMetadata(crosBuffer, dumpInner, StandardMetadata<T>{});
601     };
602 
603     // So clean. So pretty.
604     dump(StandardMetadata<StandardMetadataType::BUFFER_ID>{});
605     dump(StandardMetadata<StandardMetadataType::NAME>{});
606     dump(StandardMetadata<StandardMetadataType::WIDTH>{});
607     dump(StandardMetadata<StandardMetadataType::HEIGHT>{});
608     dump(StandardMetadata<StandardMetadataType::LAYER_COUNT>{});
609     dump(StandardMetadata<StandardMetadataType::PIXEL_FORMAT_REQUESTED>{});
610     dump(StandardMetadata<StandardMetadataType::PIXEL_FORMAT_FOURCC>{});
611     dump(StandardMetadata<StandardMetadataType::PIXEL_FORMAT_MODIFIER>{});
612     dump(StandardMetadata<StandardMetadataType::USAGE>{});
613     dump(StandardMetadata<StandardMetadataType::ALLOCATION_SIZE>{});
614     dump(StandardMetadata<StandardMetadataType::PROTECTED_CONTENT>{});
615     dump(StandardMetadata<StandardMetadataType::COMPRESSION>{});
616     dump(StandardMetadata<StandardMetadataType::INTERLACED>{});
617     dump(StandardMetadata<StandardMetadataType::CHROMA_SITING>{});
618     dump(StandardMetadata<StandardMetadataType::PLANE_LAYOUTS>{});
619     dump(StandardMetadata<StandardMetadataType::DATASPACE>{});
620     dump(StandardMetadata<StandardMetadataType::BLEND_MODE>{});
621 }
622 
dumpBuffer(buffer_handle_t _Nonnull bufferHandle,AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,void * _Null_unspecified context)623 AIMapper_Error CrosGrallocMapperV5::dumpBuffer(
624         buffer_handle_t _Nonnull bufferHandle,
625         AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback, void* _Null_unspecified context) {
626     VALIDATE_DRIVER_AND_BUFFER_HANDLE(bufferHandle)
627     cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
628     if (!crosHandle) {
629         ALOGE("Failed to get. Invalid handle.");
630         return AIMAPPER_ERROR_BAD_BUFFER;
631     }
632     auto callback = [&](AIMapper_MetadataType type, const std::vector<uint8_t>& buffer) {
633         dumpBufferCallback(context, type, buffer.data(), buffer.size());
634     };
635     mDriver->with_buffer(
636             crosHandle, [&](cros_gralloc_buffer* crosBuffer) { dumpBuffer(crosBuffer, callback); });
637     return AIMAPPER_ERROR_NONE;
638 }
639 
dumpAllBuffers(AIMapper_BeginDumpBufferCallback _Nonnull beginDumpBufferCallback,AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,void * _Null_unspecified context)640 AIMapper_Error CrosGrallocMapperV5::dumpAllBuffers(
641         AIMapper_BeginDumpBufferCallback _Nonnull beginDumpBufferCallback,
642         AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback, void* _Null_unspecified context) {
643     REQUIRE_DRIVER()
644     auto callback = [&](AIMapper_MetadataType type, const std::vector<uint8_t>& buffer) {
645         dumpBufferCallback(context, type, buffer.data(), buffer.size());
646     };
647     mDriver->with_each_buffer([&](cros_gralloc_buffer* crosBuffer) {
648         beginDumpBufferCallback(context);
649         dumpBuffer(crosBuffer, callback);
650     });
651     return AIMAPPER_ERROR_NONE;
652 }
653 
getReservedRegion(buffer_handle_t _Nonnull buffer,void * _Nullable * _Nonnull outReservedRegion,uint64_t * _Nonnull outReservedSize)654 AIMapper_Error CrosGrallocMapperV5::getReservedRegion(buffer_handle_t _Nonnull buffer,
655                                                       void* _Nullable* _Nonnull outReservedRegion,
656                                                       uint64_t* _Nonnull outReservedSize) {
657     VALIDATE_DRIVER_AND_BUFFER_HANDLE(buffer)
658     cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(buffer);
659     if (!crosHandle) {
660         ALOGE("Failed to getReservedRegion. Invalid handle.");
661         return AIMAPPER_ERROR_BAD_BUFFER;
662     }
663 
664     void* reservedRegionAddr = nullptr;
665     uint64_t reservedRegionSize = 0;
666 
667     AIMapper_Error error = AIMAPPER_ERROR_NONE;
668     mDriver->with_buffer(crosHandle, [&, this](cros_gralloc_buffer* crosBuffer) {
669         error = getReservedRegionArea(crosBuffer, ReservedRegionArea::USER_METADATA,
670                                       &reservedRegionAddr, &reservedRegionSize);
671     });
672 
673     if (error != AIMAPPER_ERROR_NONE) {
674         ALOGE("Failed to getReservedRegion. Failed to getReservedRegionArea.");
675         return AIMAPPER_ERROR_BAD_BUFFER;
676     }
677 
678     return AIMAPPER_ERROR_NONE;
679 }
680 
getReservedRegionArea(const cros_gralloc_buffer * crosBuffer,ReservedRegionArea area,void ** outAddr,uint64_t * outSize)681 AIMapper_Error CrosGrallocMapperV5::getReservedRegionArea(const cros_gralloc_buffer* crosBuffer,
682                                                           ReservedRegionArea area, void** outAddr,
683                                                           uint64_t* outSize) {
684     int ret = crosBuffer->get_reserved_region(outAddr, outSize);
685     if (ret) {
686         ALOGE("Failed to getReservedRegionArea.");
687         *outAddr = nullptr;
688         *outSize = 0;
689         return AIMAPPER_ERROR_NO_RESOURCES;
690     }
691 
692     switch (area) {
693         case ReservedRegionArea::MAPPER4_METADATA: {
694             // CrosGralloc4Metadata resides at the beginning reserved region.
695             *outSize = sizeof(CrosGralloc4Metadata);
696             break;
697         }
698         case ReservedRegionArea::USER_METADATA: {
699             // User metadata resides after the CrosGralloc4Metadata.
700             *outAddr = reinterpret_cast<void*>(reinterpret_cast<char*>(*outAddr) +
701                                                sizeof(CrosGralloc4Metadata));
702             *outSize = *outSize - sizeof(CrosGralloc4Metadata);
703             break;
704         }
705     }
706 
707     return AIMAPPER_ERROR_NONE;
708 }
709 
getCrosMetadata(const cros_gralloc_buffer * crosBuffer,const CrosGralloc4Metadata ** outMetadata)710 AIMapper_Error CrosGrallocMapperV5::getCrosMetadata(const cros_gralloc_buffer* crosBuffer,
711                                                     const CrosGralloc4Metadata** outMetadata) {
712     void* addr = nullptr;
713     uint64_t size;
714 
715     auto error =
716             getReservedRegionArea(crosBuffer, ReservedRegionArea::MAPPER4_METADATA, &addr, &size);
717     if (error != AIMAPPER_ERROR_NONE) {
718         return error;
719     }
720 
721     *outMetadata = reinterpret_cast<const CrosGralloc4Metadata*>(addr);
722     return AIMAPPER_ERROR_NONE;
723 }
724 
getMutableCrosMetadata(cros_gralloc_buffer * crosBuffer,CrosGralloc4Metadata ** outMetadata)725 AIMapper_Error CrosGrallocMapperV5::getMutableCrosMetadata(cros_gralloc_buffer* crosBuffer,
726                                                            CrosGralloc4Metadata** outMetadata) {
727     void* addr = nullptr;
728     uint64_t size;
729 
730     auto error =
731             getReservedRegionArea(crosBuffer, ReservedRegionArea::MAPPER4_METADATA, &addr, &size);
732     if (error != AIMAPPER_ERROR_NONE) {
733         return error;
734     }
735 
736     *outMetadata = reinterpret_cast<CrosGralloc4Metadata*>(addr);
737     return AIMAPPER_ERROR_NONE;
738 }
739 
740 extern "C" uint32_t ANDROID_HAL_MAPPER_VERSION = AIMAPPER_VERSION_5;
741 
AIMapper_loadIMapper(AIMapper * _Nullable * _Nonnull outImplementation)742 extern "C" AIMapper_Error AIMapper_loadIMapper(AIMapper* _Nullable* _Nonnull outImplementation) {
743     static vendor::mapper::IMapperProvider<CrosGrallocMapperV5> provider;
744     return provider.load(outImplementation);
745 }