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