OSDN Git Service

0e26156e4bed0e063632a626672f1140657678a4
[android-x86/external-minigbm.git] / cros_gralloc / gralloc4 / CrosGralloc4Mapper.cc
1 /*
2  * Copyright 2020 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 "cros_gralloc/gralloc4/CrosGralloc4Mapper.h"
8
9 #include <aidl/android/hardware/graphics/common/BlendMode.h>
10 #include <aidl/android/hardware/graphics/common/Dataspace.h>
11 #include <aidl/android/hardware/graphics/common/PlaneLayout.h>
12 #include <aidl/android/hardware/graphics/common/Rect.h>
13 #include <cutils/native_handle.h>
14 #include <gralloctypes/Gralloc4.h>
15
16 #include "cros_gralloc/cros_gralloc_helpers.h"
17 #include "cros_gralloc/gralloc4/CrosGralloc4Utils.h"
18
19 #include "helpers.h"
20
21 using aidl::android::hardware::graphics::common::BlendMode;
22 using aidl::android::hardware::graphics::common::Dataspace;
23 using aidl::android::hardware::graphics::common::PlaneLayout;
24 using aidl::android::hardware::graphics::common::Rect;
25 using android::hardware::hidl_handle;
26 using android::hardware::hidl_vec;
27 using android::hardware::Return;
28 using android::hardware::Void;
29 using android::hardware::graphics::common::V1_2::BufferUsage;
30 using android::hardware::graphics::common::V1_2::PixelFormat;
31 using android::hardware::graphics::mapper::V4_0::Error;
32 using android::hardware::graphics::mapper::V4_0::IMapper;
33
34 CrosGralloc4Mapper::CrosGralloc4Mapper() : mDriver(std::make_unique<cros_gralloc_driver>()) {
35     if (mDriver->init()) {
36         drv_log("Failed to initialize driver.\n");
37         mDriver = nullptr;
38     }
39 }
40
41 Return<void> CrosGralloc4Mapper::createDescriptor(const BufferDescriptorInfo& description,
42                                                   createDescriptor_cb hidlCb) {
43     hidl_vec<uint8_t> descriptor;
44
45     if (description.width == 0) {
46         drv_log("Failed to createDescriptor. Bad width: %d.\n", description.width);
47         hidlCb(Error::BAD_VALUE, descriptor);
48         return Void();
49     }
50
51     if (description.height == 0) {
52         drv_log("Failed to createDescriptor. Bad height: %d.\n", description.height);
53         hidlCb(Error::BAD_VALUE, descriptor);
54         return Void();
55     }
56
57     if (description.layerCount == 0) {
58         drv_log("Failed to createDescriptor. Bad layer count: %d.\n", description.layerCount);
59         hidlCb(Error::BAD_VALUE, descriptor);
60         return Void();
61     }
62
63     int ret = android::gralloc4::encodeBufferDescriptorInfo(description, &descriptor);
64     if (ret) {
65         drv_log("Failed to createDescriptor. Failed to encode: %d.\n", ret);
66         hidlCb(Error::BAD_VALUE, descriptor);
67         return Void();
68     }
69
70     hidlCb(Error::NONE, descriptor);
71     return Void();
72 }
73
74 Return<void> CrosGralloc4Mapper::importBuffer(const hidl_handle& handle, importBuffer_cb hidlCb) {
75     if (!mDriver) {
76         drv_log("Failed to import buffer. Driver is uninitialized.\n");
77         hidlCb(Error::NO_RESOURCES, nullptr);
78         return Void();
79     }
80
81     const native_handle_t* bufferHandle = handle.getNativeHandle();
82     if (!bufferHandle || bufferHandle->numFds == 0) {
83         drv_log("Failed to importBuffer. Bad handle.\n");
84         hidlCb(Error::BAD_BUFFER, nullptr);
85         return Void();
86     }
87
88     native_handle_t* importedBufferHandle = native_handle_clone(bufferHandle);
89     if (!importedBufferHandle) {
90         drv_log("Failed to importBuffer. Handle clone failed: %s.\n", strerror(errno));
91         hidlCb(Error::NO_RESOURCES, nullptr);
92         return Void();
93     }
94
95     int ret = mDriver->retain(importedBufferHandle);
96     if (ret) {
97         native_handle_close(importedBufferHandle);
98         native_handle_delete(importedBufferHandle);
99         hidlCb(Error::NO_RESOURCES, nullptr);
100         return Void();
101     }
102
103     hidlCb(Error::NONE, importedBufferHandle);
104     return Void();
105 }
106
107 Return<Error> CrosGralloc4Mapper::freeBuffer(void* rawHandle) {
108     if (!mDriver) {
109         drv_log("Failed to freeBuffer. Driver is uninitialized.\n");
110         return Error::NO_RESOURCES;
111     }
112
113     native_handle_t* bufferHandle = reinterpret_cast<native_handle_t*>(rawHandle);
114     if (!bufferHandle) {
115         drv_log("Failed to freeBuffer. Empty handle.\n");
116         return Error::BAD_BUFFER;
117     }
118
119     int ret = mDriver->release(bufferHandle);
120     if (ret) {
121         return Error::BAD_BUFFER;
122     }
123
124     native_handle_close(bufferHandle);
125     native_handle_delete(bufferHandle);
126     return Error::NONE;
127 }
128
129 Return<Error> CrosGralloc4Mapper::validateBufferSize(void* rawHandle,
130                                                      const BufferDescriptorInfo& descriptor,
131                                                      uint32_t stride) {
132     if (!mDriver) {
133         drv_log("Failed to validateBufferSize. Driver is uninitialized.\n");
134         return Error::NO_RESOURCES;
135     }
136
137     native_handle_t* bufferHandle = reinterpret_cast<native_handle_t*>(rawHandle);
138     if (!bufferHandle) {
139         drv_log("Failed to validateBufferSize. Empty handle.\n");
140         return Error::BAD_BUFFER;
141     }
142
143     cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
144     if (!crosHandle) {
145         drv_log("Failed to validateBufferSize. Invalid handle.\n");
146         return Error::BAD_BUFFER;
147     }
148
149     PixelFormat crosHandleFormat = static_cast<PixelFormat>(crosHandle->droid_format);
150     if (descriptor.format != crosHandleFormat) {
151         drv_log("Failed to validateBufferSize. Format mismatch.\n");
152         return Error::BAD_BUFFER;
153     }
154
155     if (descriptor.width != crosHandle->width) {
156         drv_log("Failed to validateBufferSize. Width mismatch (%d vs %d).\n", descriptor.width,
157                 crosHandle->width);
158         return Error::BAD_VALUE;
159     }
160
161     if (descriptor.height != crosHandle->height) {
162         drv_log("Failed to validateBufferSize. Height mismatch (%d vs %d).\n", descriptor.height,
163                 crosHandle->height);
164         return Error::BAD_VALUE;
165     }
166
167     if (stride != crosHandle->pixel_stride) {
168         drv_log("Failed to validateBufferSize. Stride mismatch (%d vs %d).\n", stride,
169                 crosHandle->pixel_stride);
170         return Error::BAD_VALUE;
171     }
172
173     return Error::NONE;
174 }
175
176 Return<void> CrosGralloc4Mapper::getTransportSize(void* rawHandle, getTransportSize_cb hidlCb) {
177     if (!mDriver) {
178         drv_log("Failed to getTransportSize. Driver is uninitialized.\n");
179         hidlCb(Error::BAD_BUFFER, 0, 0);
180         return Void();
181     }
182
183     native_handle_t* bufferHandle = reinterpret_cast<native_handle_t*>(rawHandle);
184     if (!bufferHandle) {
185         drv_log("Failed to getTransportSize. Bad handle.\n");
186         hidlCb(Error::BAD_BUFFER, 0, 0);
187         return Void();
188     }
189
190     // No local process data is currently stored on the native handle.
191     hidlCb(Error::NONE, bufferHandle->numFds, bufferHandle->numInts);
192     return Void();
193 }
194
195 Return<void> CrosGralloc4Mapper::lock(void* rawBuffer, uint64_t cpuUsage, const Rect& region,
196                                       const hidl_handle& acquireFence, lock_cb hidlCb) {
197     if (!mDriver) {
198         drv_log("Failed to lock. Driver is uninitialized.\n");
199         hidlCb(Error::NO_RESOURCES, nullptr);
200         return Void();
201     }
202
203     buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawBuffer);
204     if (!bufferHandle) {
205         drv_log("Failed to lock. Empty handle.\n");
206         hidlCb(Error::BAD_BUFFER, nullptr);
207         return Void();
208     }
209
210     if (cpuUsage == 0) {
211         drv_log("Failed to lock. Bad cpu usage: %" PRIu64 ".\n", cpuUsage);
212         hidlCb(Error::BAD_VALUE, nullptr);
213         return Void();
214     }
215
216     uint32_t mapUsage = 0;
217     int ret = convertToMapUsage(cpuUsage, &mapUsage);
218     if (ret) {
219         drv_log("Failed to lock. Convert usage failed.\n");
220         hidlCb(Error::BAD_VALUE, nullptr);
221         return Void();
222     }
223
224     cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
225     if (crosHandle == nullptr) {
226         drv_log("Failed to lock. Invalid handle.\n");
227         hidlCb(Error::BAD_VALUE, nullptr);
228         return Void();
229     }
230
231     if (region.left < 0) {
232         drv_log("Failed to lock. Invalid region: negative left value %d.\n", region.left);
233         hidlCb(Error::BAD_VALUE, nullptr);
234         return Void();
235     }
236
237     if (region.top < 0) {
238         drv_log("Failed to lock. Invalid region: negative top value %d.\n", region.top);
239         hidlCb(Error::BAD_VALUE, nullptr);
240         return Void();
241     }
242
243     if (region.width < 0) {
244         drv_log("Failed to lock. Invalid region: negative width value %d.\n", region.width);
245         hidlCb(Error::BAD_VALUE, nullptr);
246         return Void();
247     }
248
249     if (region.height < 0) {
250         drv_log("Failed to lock. Invalid region: negative height value %d.\n", region.height);
251         hidlCb(Error::BAD_VALUE, nullptr);
252         return Void();
253     }
254
255     if (region.width > crosHandle->width) {
256         drv_log("Failed to lock. Invalid region: width greater than buffer width (%d vs %d).\n",
257                 region.width, crosHandle->width);
258         hidlCb(Error::BAD_VALUE, nullptr);
259         return Void();
260     }
261
262     if (region.height > crosHandle->height) {
263         drv_log("Failed to lock. Invalid region: height greater than buffer height (%d vs %d).\n",
264                 region.height, crosHandle->height);
265         hidlCb(Error::BAD_VALUE, nullptr);
266         return Void();
267     }
268
269     struct rectangle rect = {static_cast<uint32_t>(region.left), static_cast<uint32_t>(region.top),
270                              static_cast<uint32_t>(region.width),
271                              static_cast<uint32_t>(region.height)};
272
273     // An access region of all zeros means the entire buffer.
274     if (rect.x == 0 && rect.y == 0 && rect.width == 0 && rect.height == 0) {
275         rect.width = crosHandle->width;
276         rect.height = crosHandle->height;
277     }
278
279     int acquireFenceFd = -1;
280     ret = convertToFenceFd(acquireFence, &acquireFenceFd);
281     if (ret) {
282         drv_log("Failed to lock. Bad acquire fence.\n");
283         hidlCb(Error::BAD_VALUE, nullptr);
284         return Void();
285     }
286
287     uint8_t* addr[DRV_MAX_PLANES];
288     ret = mDriver->lock(bufferHandle, acquireFenceFd, /*close_acquire_fence=*/false, &rect,
289                         mapUsage, addr);
290     if (ret) {
291         hidlCb(Error::BAD_VALUE, nullptr);
292         return Void();
293     }
294
295     hidlCb(Error::NONE, addr[0]);
296     return Void();
297 }
298
299 Return<void> CrosGralloc4Mapper::unlock(void* rawHandle, unlock_cb hidlCb) {
300     if (!mDriver) {
301         drv_log("Failed to unlock. Driver is uninitialized.\n");
302         hidlCb(Error::BAD_BUFFER, nullptr);
303         return Void();
304     }
305
306     buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
307     if (!bufferHandle) {
308         drv_log("Failed to unlock. Empty handle.\n");
309         hidlCb(Error::BAD_BUFFER, nullptr);
310         return Void();
311     }
312
313     int releaseFenceFd = -1;
314     int ret = mDriver->unlock(bufferHandle, &releaseFenceFd);
315     if (ret) {
316         drv_log("Failed to unlock.\n");
317         hidlCb(Error::BAD_BUFFER, nullptr);
318         return Void();
319     }
320
321     hidl_handle releaseFenceHandle;
322     ret = convertToFenceHandle(releaseFenceFd, &releaseFenceHandle);
323     if (ret) {
324         drv_log("Failed to unlock. Failed to convert release fence to handle.\n");
325         hidlCb(Error::BAD_BUFFER, nullptr);
326         return Void();
327     }
328
329     hidlCb(Error::NONE, releaseFenceHandle);
330     return Void();
331 }
332
333 Return<void> CrosGralloc4Mapper::flushLockedBuffer(void* rawHandle, flushLockedBuffer_cb hidlCb) {
334     if (!mDriver) {
335         drv_log("Failed to flushLockedBuffer. Driver is uninitialized.\n");
336         hidlCb(Error::NO_RESOURCES, nullptr);
337         return Void();
338     }
339
340     buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
341     if (!bufferHandle) {
342         drv_log("Failed to flushLockedBuffer. Empty handle.\n");
343         hidlCb(Error::BAD_BUFFER, nullptr);
344         return Void();
345     }
346
347     int releaseFenceFd = -1;
348     int ret = mDriver->flush(bufferHandle, &releaseFenceFd);
349     if (ret) {
350         drv_log("Failed to flushLockedBuffer. Flush failed.\n");
351         hidlCb(Error::BAD_BUFFER, nullptr);
352         return Void();
353     }
354
355     hidl_handle releaseFenceHandle;
356     ret = convertToFenceHandle(releaseFenceFd, &releaseFenceHandle);
357     if (ret) {
358         drv_log("Failed to flushLockedBuffer. Failed to convert release fence to handle.\n");
359         hidlCb(Error::BAD_BUFFER, nullptr);
360         return Void();
361     }
362
363     hidlCb(Error::NONE, releaseFenceHandle);
364     return Void();
365 }
366
367 Return<Error> CrosGralloc4Mapper::rereadLockedBuffer(void* rawHandle) {
368     if (!mDriver) {
369         drv_log("Failed to rereadLockedBuffer. Driver is uninitialized.\n");
370         return Error::NO_RESOURCES;
371     }
372
373     buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
374     if (!bufferHandle) {
375         drv_log("Failed to rereadLockedBuffer. Empty handle.\n");
376         return Error::BAD_BUFFER;
377     }
378
379     int ret = mDriver->invalidate(bufferHandle);
380     if (ret) {
381         drv_log("Failed to rereadLockedBuffer. Failed to invalidate.\n");
382         return Error::BAD_BUFFER;
383     }
384
385     return Error::NONE;
386 }
387
388 Return<void> CrosGralloc4Mapper::isSupported(const BufferDescriptorInfo& descriptor,
389                                              isSupported_cb hidlCb) {
390     if (!mDriver) {
391         drv_log("Failed to isSupported. Driver is uninitialized.\n");
392         hidlCb(Error::BAD_VALUE, false);
393         return Void();
394     }
395
396     struct cros_gralloc_buffer_descriptor crosDescriptor;
397     if (convertToCrosDescriptor(descriptor, &crosDescriptor)) {
398         hidlCb(Error::NONE, false);
399         return Void();
400     }
401
402     bool supported = mDriver->is_supported(&crosDescriptor);
403     if (!supported) {
404         crosDescriptor.use_flags &= ~BO_USE_SCANOUT;
405         supported = mDriver->is_supported(&crosDescriptor);
406     }
407
408     hidlCb(Error::NONE, supported);
409     return Void();
410 }
411
412 Return<void> CrosGralloc4Mapper::get(void* rawHandle, const MetadataType& metadataType,
413                                      get_cb hidlCb) {
414     hidl_vec<uint8_t> encodedMetadata;
415
416     if (!mDriver) {
417         drv_log("Failed to get. Driver is uninitialized.\n");
418         hidlCb(Error::NO_RESOURCES, encodedMetadata);
419         return Void();
420     }
421
422     buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
423     if (!bufferHandle) {
424         drv_log("Failed to get. Empty handle.\n");
425         hidlCb(Error::BAD_BUFFER, encodedMetadata);
426         return Void();
427     }
428
429     cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
430     if (!crosHandle) {
431         drv_log("Failed to get. Invalid handle.\n");
432         hidlCb(Error::BAD_BUFFER, encodedMetadata);
433         return Void();
434     }
435
436     get(crosHandle, metadataType, hidlCb);
437     return Void();
438 }
439
440 Return<void> CrosGralloc4Mapper::get(cros_gralloc_handle_t crosHandle,
441                                      const MetadataType& metadataType, get_cb hidlCb) {
442     hidl_vec<uint8_t> encodedMetadata;
443
444     if (!mDriver) {
445         drv_log("Failed to get. Driver is uninitialized.\n");
446         hidlCb(Error::NO_RESOURCES, encodedMetadata);
447         return Void();
448     }
449
450     if (!crosHandle) {
451         drv_log("Failed to get. Invalid handle.\n");
452         hidlCb(Error::BAD_BUFFER, encodedMetadata);
453         return Void();
454     }
455
456     android::status_t status = android::NO_ERROR;
457     if (metadataType == android::gralloc4::MetadataType_BufferId) {
458         status = android::gralloc4::encodeBufferId(crosHandle->id, &encodedMetadata);
459     } else if (metadataType == android::gralloc4::MetadataType_Name) {
460         const char* name = (const char*)(&crosHandle->base.data[crosHandle->name_offset]);
461         status = android::gralloc4::encodeName(name, &encodedMetadata);
462     } else if (metadataType == android::gralloc4::MetadataType_Width) {
463         status = android::gralloc4::encodeWidth(crosHandle->width, &encodedMetadata);
464     } else if (metadataType == android::gralloc4::MetadataType_Height) {
465         status = android::gralloc4::encodeHeight(crosHandle->height, &encodedMetadata);
466     } else if (metadataType == android::gralloc4::MetadataType_LayerCount) {
467         status = android::gralloc4::encodeLayerCount(1, &encodedMetadata);
468     } else if (metadataType == android::gralloc4::MetadataType_PixelFormatRequested) {
469         PixelFormat pixelFormat = static_cast<PixelFormat>(crosHandle->droid_format);
470         status = android::gralloc4::encodePixelFormatRequested(pixelFormat, &encodedMetadata);
471     } else if (metadataType == android::gralloc4::MetadataType_PixelFormatFourCC) {
472         uint32_t format = crosHandle->format;
473         // Map internal fourcc codes back to standard fourcc codes.
474         if (format == DRM_FORMAT_YVU420_ANDROID) {
475             format = DRM_FORMAT_YVU420;
476         }
477         status = android::gralloc4::encodePixelFormatFourCC(format, &encodedMetadata);
478     } else if (metadataType == android::gralloc4::MetadataType_PixelFormatModifier) {
479         status = android::gralloc4::encodePixelFormatModifier(crosHandle->format_modifier,
480                                                               &encodedMetadata);
481     } else if (metadataType == android::gralloc4::MetadataType_Usage) {
482         uint64_t usage = static_cast<uint64_t>(crosHandle->usage);
483         status = android::gralloc4::encodeUsage(usage, &encodedMetadata);
484     } else if (metadataType == android::gralloc4::MetadataType_AllocationSize) {
485         status = android::gralloc4::encodeAllocationSize(crosHandle->total_size, &encodedMetadata);
486     } else if (metadataType == android::gralloc4::MetadataType_ProtectedContent) {
487         uint64_t hasProtectedContent = crosHandle->usage & BufferUsage::PROTECTED ? 1 : 0;
488         status = android::gralloc4::encodeProtectedContent(hasProtectedContent, &encodedMetadata);
489     } else if (metadataType == android::gralloc4::MetadataType_Compression) {
490         status = android::gralloc4::encodeCompression(android::gralloc4::Compression_None,
491                                                       &encodedMetadata);
492     } else if (metadataType == android::gralloc4::MetadataType_Interlaced) {
493         status = android::gralloc4::encodeInterlaced(android::gralloc4::Interlaced_None,
494                                                      &encodedMetadata);
495     } else if (metadataType == android::gralloc4::MetadataType_ChromaSiting) {
496         status = android::gralloc4::encodeChromaSiting(android::gralloc4::ChromaSiting_None,
497                                                        &encodedMetadata);
498     } else if (metadataType == android::gralloc4::MetadataType_PlaneLayouts) {
499         std::vector<PlaneLayout> planeLayouts;
500         getPlaneLayouts(crosHandle->format, &planeLayouts);
501
502         for (size_t plane = 0; plane < planeLayouts.size(); plane++) {
503             PlaneLayout& planeLayout = planeLayouts[plane];
504             planeLayout.offsetInBytes = crosHandle->offsets[plane];
505             planeLayout.strideInBytes = crosHandle->strides[plane];
506             planeLayout.totalSizeInBytes = crosHandle->sizes[plane];
507             planeLayout.widthInSamples = crosHandle->width / planeLayout.horizontalSubsampling;
508             planeLayout.heightInSamples = crosHandle->height / planeLayout.verticalSubsampling;
509         }
510
511         status = android::gralloc4::encodePlaneLayouts(planeLayouts, &encodedMetadata);
512     } else if (metadataType == android::gralloc4::MetadataType_Crop) {
513         std::vector<aidl::android::hardware::graphics::common::Rect> crops;
514         for (size_t plane = 0; plane < crosHandle->num_planes; plane++) {
515             aidl::android::hardware::graphics::common::Rect crop;
516             crop.left = 0;
517             crop.top = 0;
518             crop.right = crosHandle->width;
519             crop.bottom = crosHandle->height;
520             crops.push_back(crop);
521         }
522
523         status = android::gralloc4::encodeCrop(crops, &encodedMetadata);
524     } else if (metadataType == android::gralloc4::MetadataType_Dataspace) {
525         status = android::gralloc4::encodeDataspace(Dataspace::UNKNOWN, &encodedMetadata);
526     } else if (metadataType == android::gralloc4::MetadataType_BlendMode) {
527         status = android::gralloc4::encodeBlendMode(BlendMode::INVALID, &encodedMetadata);
528     } else if (metadataType == android::gralloc4::MetadataType_Smpte2086) {
529         status = android::gralloc4::encodeSmpte2086(std::nullopt, &encodedMetadata);
530     } else if (metadataType == android::gralloc4::MetadataType_Cta861_3) {
531         status = android::gralloc4::encodeCta861_3(std::nullopt, &encodedMetadata);
532     } else if (metadataType == android::gralloc4::MetadataType_Smpte2094_40) {
533         status = android::gralloc4::encodeSmpte2094_40(std::nullopt, &encodedMetadata);
534     } else {
535         hidlCb(Error::UNSUPPORTED, encodedMetadata);
536         return Void();
537     }
538
539     if (status != android::NO_ERROR) {
540         hidlCb(Error::NO_RESOURCES, encodedMetadata);
541         drv_log("Failed to get. Failed to encode metadata.\n");
542         return Void();
543     }
544
545     hidlCb(Error::NONE, encodedMetadata);
546     return Void();
547 }
548
549 Return<Error> CrosGralloc4Mapper::set(void* rawHandle, const MetadataType& metadataType,
550                                       const hidl_vec<uint8_t>& /*metadata*/) {
551     if (!mDriver) {
552         drv_log("Failed to set. Driver is uninitialized.\n");
553         return Error::NO_RESOURCES;
554     }
555
556     buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
557     if (!bufferHandle) {
558         drv_log("Failed to set. Empty handle.\n");
559         return Error::BAD_BUFFER;
560     }
561
562     cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
563     if (!crosHandle) {
564         drv_log("Failed to set. Invalid handle.\n");
565         return Error::BAD_BUFFER;
566     }
567
568     if (metadataType == android::gralloc4::MetadataType_BufferId) {
569         return Error::BAD_VALUE;
570     } else if (metadataType == android::gralloc4::MetadataType_Name) {
571         return Error::BAD_VALUE;
572     } else if (metadataType == android::gralloc4::MetadataType_Width) {
573         return Error::BAD_VALUE;
574     } else if (metadataType == android::gralloc4::MetadataType_Height) {
575         return Error::BAD_VALUE;
576     } else if (metadataType == android::gralloc4::MetadataType_LayerCount) {
577         return Error::BAD_VALUE;
578     } else if (metadataType == android::gralloc4::MetadataType_PixelFormatRequested) {
579         return Error::BAD_VALUE;
580     } else if (metadataType == android::gralloc4::MetadataType_Usage) {
581         return Error::BAD_VALUE;
582     }
583
584     return Error::UNSUPPORTED;
585 }
586
587 int CrosGralloc4Mapper::getResolvedDrmFormat(PixelFormat pixelFormat, uint64_t bufferUsage,
588                                              uint32_t* outDrmFormat) {
589     uint32_t drmFormat;
590     if (convertToDrmFormat(pixelFormat, &drmFormat)) {
591         std::string pixelFormatString = getPixelFormatString(pixelFormat);
592         drv_log("Failed to getResolvedDrmFormat. Failed to convert format %s\n",
593                 pixelFormatString.c_str());
594         return -1;
595     }
596
597     uint64_t usage;
598     if (convertToBufferUsage(bufferUsage, &usage)) {
599         std::string usageString = getUsageString(bufferUsage);
600         drv_log("Failed to getResolvedDrmFormat. Failed to convert usage %s\n",
601                 usageString.c_str());
602         return -1;
603     }
604
605     uint32_t resolvedDrmFormat = mDriver->get_resolved_drm_format(drmFormat, usage);
606     if (resolvedDrmFormat == DRM_FORMAT_INVALID) {
607         std::string drmFormatString = get_drm_format_string(drmFormat);
608         drv_log("Failed to getResolvedDrmFormat. Failed to resolve drm format %s\n",
609                 drmFormatString.c_str());
610         return -1;
611     }
612
613     *outDrmFormat = resolvedDrmFormat;
614
615     return 0;
616 }
617
618 Return<void> CrosGralloc4Mapper::getFromBufferDescriptorInfo(
619         const BufferDescriptorInfo& descriptor, const MetadataType& metadataType,
620         getFromBufferDescriptorInfo_cb hidlCb) {
621     hidl_vec<uint8_t> encodedMetadata;
622
623     if (!mDriver) {
624         drv_log("Failed to getFromBufferDescriptorInfo. Driver is uninitialized.\n");
625         hidlCb(Error::NO_RESOURCES, encodedMetadata);
626         return Void();
627     }
628
629     android::status_t status = android::NO_ERROR;
630     if (metadataType == android::gralloc4::MetadataType_Name) {
631         status = android::gralloc4::encodeName(descriptor.name, &encodedMetadata);
632     } else if (metadataType == android::gralloc4::MetadataType_Width) {
633         status = android::gralloc4::encodeWidth(descriptor.width, &encodedMetadata);
634     } else if (metadataType == android::gralloc4::MetadataType_Height) {
635         status = android::gralloc4::encodeHeight(descriptor.height, &encodedMetadata);
636     } else if (metadataType == android::gralloc4::MetadataType_LayerCount) {
637         status = android::gralloc4::encodeLayerCount(1, &encodedMetadata);
638     } else if (metadataType == android::gralloc4::MetadataType_PixelFormatRequested) {
639         status = android::gralloc4::encodePixelFormatRequested(descriptor.format, &encodedMetadata);
640     } else if (metadataType == android::gralloc4::MetadataType_PixelFormatFourCC) {
641         uint32_t drmFormat;
642         if (getResolvedDrmFormat(descriptor.format, descriptor.usage, &drmFormat)) {
643             hidlCb(Error::BAD_VALUE, encodedMetadata);
644             return Void();
645         }
646         status = android::gralloc4::encodePixelFormatFourCC(drmFormat, &encodedMetadata);
647     } else if (metadataType == android::gralloc4::MetadataType_Usage) {
648         status = android::gralloc4::encodeUsage(descriptor.usage, &encodedMetadata);
649     } else if (metadataType == android::gralloc4::MetadataType_ProtectedContent) {
650         uint64_t hasProtectedContent = descriptor.usage & BufferUsage::PROTECTED ? 1 : 0;
651         status = android::gralloc4::encodeProtectedContent(hasProtectedContent, &encodedMetadata);
652     } else if (metadataType == android::gralloc4::MetadataType_Compression) {
653         status = android::gralloc4::encodeCompression(android::gralloc4::Compression_None,
654                                                       &encodedMetadata);
655     } else if (metadataType == android::gralloc4::MetadataType_Interlaced) {
656         status = android::gralloc4::encodeInterlaced(android::gralloc4::Interlaced_None,
657                                                      &encodedMetadata);
658     } else if (metadataType == android::gralloc4::MetadataType_ChromaSiting) {
659         status = android::gralloc4::encodeChromaSiting(android::gralloc4::ChromaSiting_None,
660                                                        &encodedMetadata);
661     } else if (metadataType == android::gralloc4::MetadataType_Crop) {
662         uint32_t drmFormat;
663         if (getResolvedDrmFormat(descriptor.format, descriptor.usage, &drmFormat)) {
664             hidlCb(Error::BAD_VALUE, encodedMetadata);
665             return Void();
666         }
667
668         size_t numPlanes = drv_num_planes_from_format(drmFormat);
669
670         std::vector<aidl::android::hardware::graphics::common::Rect> crops;
671         for (size_t plane = 0; plane < numPlanes; plane++) {
672             aidl::android::hardware::graphics::common::Rect crop;
673             crop.left = 0;
674             crop.top = 0;
675             crop.right = descriptor.width;
676             crop.bottom = descriptor.height;
677             crops.push_back(crop);
678         }
679         status = android::gralloc4::encodeCrop(crops, &encodedMetadata);
680     } else if (metadataType == android::gralloc4::MetadataType_Dataspace) {
681         status = android::gralloc4::encodeDataspace(Dataspace::UNKNOWN, &encodedMetadata);
682     } else if (metadataType == android::gralloc4::MetadataType_BlendMode) {
683         status = android::gralloc4::encodeBlendMode(BlendMode::INVALID, &encodedMetadata);
684     } else if (metadataType == android::gralloc4::MetadataType_Smpte2086) {
685         status = android::gralloc4::encodeSmpte2086(std::nullopt, &encodedMetadata);
686     } else if (metadataType == android::gralloc4::MetadataType_Cta861_3) {
687         status = android::gralloc4::encodeCta861_3(std::nullopt, &encodedMetadata);
688     } else if (metadataType == android::gralloc4::MetadataType_Smpte2094_40) {
689         status = android::gralloc4::encodeSmpte2094_40(std::nullopt, &encodedMetadata);
690     } else {
691         hidlCb(Error::UNSUPPORTED, encodedMetadata);
692         return Void();
693     }
694
695     if (status != android::NO_ERROR) {
696         hidlCb(Error::NO_RESOURCES, encodedMetadata);
697         return Void();
698     }
699
700     hidlCb(Error::NONE, encodedMetadata);
701     return Void();
702 }
703
704 Return<void> CrosGralloc4Mapper::listSupportedMetadataTypes(listSupportedMetadataTypes_cb hidlCb) {
705     hidl_vec<MetadataTypeDescription> supported;
706
707     if (!mDriver) {
708         drv_log("Failed to listSupportedMetadataTypes. Driver is uninitialized.\n");
709         hidlCb(Error::NO_RESOURCES, supported);
710         return Void();
711     }
712
713     supported = hidl_vec<IMapper::MetadataTypeDescription>({
714             {
715                     android::gralloc4::MetadataType_BufferId,
716                     "",
717                     /*isGettable=*/true,
718                     /*isSettable=*/false,
719             },
720             {
721                     android::gralloc4::MetadataType_Name,
722                     "",
723                     /*isGettable=*/true,
724                     /*isSettable=*/false,
725             },
726             {
727                     android::gralloc4::MetadataType_Width,
728                     "",
729                     /*isGettable=*/true,
730                     /*isSettable=*/false,
731             },
732             {
733                     android::gralloc4::MetadataType_Height,
734                     "",
735                     /*isGettable=*/true,
736                     /*isSettable=*/false,
737             },
738             {
739                     android::gralloc4::MetadataType_LayerCount,
740                     "",
741                     /*isGettable=*/true,
742                     /*isSettable=*/false,
743             },
744             {
745                     android::gralloc4::MetadataType_PixelFormatRequested,
746                     "",
747                     /*isGettable=*/true,
748                     /*isSettable=*/false,
749             },
750             {
751                     android::gralloc4::MetadataType_PixelFormatFourCC,
752                     "",
753                     /*isGettable=*/true,
754                     /*isSettable=*/false,
755             },
756             {
757                     android::gralloc4::MetadataType_PixelFormatModifier,
758                     "",
759                     /*isGettable=*/true,
760                     /*isSettable=*/false,
761             },
762             {
763                     android::gralloc4::MetadataType_Usage,
764                     "",
765                     /*isGettable=*/true,
766                     /*isSettable=*/false,
767             },
768             {
769                     android::gralloc4::MetadataType_AllocationSize,
770                     "",
771                     /*isGettable=*/true,
772                     /*isSettable=*/false,
773             },
774             {
775                     android::gralloc4::MetadataType_ProtectedContent,
776                     "",
777                     /*isGettable=*/true,
778                     /*isSettable=*/false,
779             },
780             {
781                     android::gralloc4::MetadataType_Compression,
782                     "",
783                     /*isGettable=*/true,
784                     /*isSettable=*/false,
785             },
786             {
787                     android::gralloc4::MetadataType_Interlaced,
788                     "",
789                     /*isGettable=*/true,
790                     /*isSettable=*/false,
791             },
792             {
793                     android::gralloc4::MetadataType_ChromaSiting,
794                     "",
795                     /*isGettable=*/true,
796                     /*isSettable=*/false,
797             },
798             {
799                     android::gralloc4::MetadataType_PlaneLayouts,
800                     "",
801                     /*isGettable=*/true,
802                     /*isSettable=*/false,
803             },
804             {
805                     android::gralloc4::MetadataType_Dataspace,
806                     "",
807                     /*isGettable=*/true,
808                     /*isSettable=*/false,
809             },
810             {
811                     android::gralloc4::MetadataType_BlendMode,
812                     "",
813                     /*isGettable=*/true,
814                     /*isSettable=*/false,
815             },
816             {
817                     android::gralloc4::MetadataType_Smpte2086,
818                     "",
819                     /*isGettable=*/true,
820                     /*isSettable=*/false,
821             },
822             {
823                     android::gralloc4::MetadataType_Cta861_3,
824                     "",
825                     /*isGettable=*/true,
826                     /*isSettable=*/false,
827             },
828             {
829                     android::gralloc4::MetadataType_Smpte2094_40,
830                     "",
831                     /*isGettable=*/true,
832                     /*isSettable=*/false,
833             },
834     });
835
836     hidlCb(Error::NONE, supported);
837     return Void();
838 }
839
840 Return<void> CrosGralloc4Mapper::dumpBuffer(void* rawHandle, dumpBuffer_cb hidlCb) {
841     BufferDump bufferDump;
842
843     if (!mDriver) {
844         drv_log("Failed to dumpBuffer. Driver is uninitialized.\n");
845         hidlCb(Error::NO_RESOURCES, bufferDump);
846         return Void();
847     }
848
849     buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
850     if (!bufferHandle) {
851         drv_log("Failed to dumpBuffer. Empty handle.\n");
852         hidlCb(Error::BAD_BUFFER, bufferDump);
853         return Void();
854     }
855
856     cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
857     if (!crosHandle) {
858         drv_log("Failed to dumpBuffer. Invalid handle.\n");
859         hidlCb(Error::BAD_BUFFER, bufferDump);
860         return Void();
861     }
862
863     return dumpBuffer(crosHandle, hidlCb);
864 }
865
866 Return<void> CrosGralloc4Mapper::dumpBuffer(cros_gralloc_handle_t crosHandle,
867                                             dumpBuffer_cb hidlCb) {
868     BufferDump bufferDump;
869
870     if (!mDriver) {
871         drv_log("Failed to dumpBuffer. Driver is uninitialized.\n");
872         hidlCb(Error::NO_RESOURCES, bufferDump);
873         return Void();
874     }
875
876     if (!crosHandle) {
877         drv_log("Failed to dumpBuffer. Invalid handle.\n");
878         hidlCb(Error::BAD_BUFFER, bufferDump);
879         return Void();
880     }
881
882     std::vector<MetadataDump> metadataDumps;
883
884     MetadataType metadataType = android::gralloc4::MetadataType_BufferId;
885     auto metadata_get_callback = [&](Error, hidl_vec<uint8_t> metadata) {
886         MetadataDump metadataDump;
887         metadataDump.metadataType = metadataType;
888         metadataDump.metadata = metadata;
889         metadataDumps.push_back(metadataDump);
890     };
891
892     metadataType = android::gralloc4::MetadataType_BufferId;
893     get(crosHandle, metadataType, metadata_get_callback);
894
895     metadataType = android::gralloc4::MetadataType_Name;
896     get(crosHandle, metadataType, metadata_get_callback);
897
898     metadataType = android::gralloc4::MetadataType_Width;
899     get(crosHandle, metadataType, metadata_get_callback);
900
901     metadataType = android::gralloc4::MetadataType_Height;
902     get(crosHandle, metadataType, metadata_get_callback);
903
904     metadataType = android::gralloc4::MetadataType_LayerCount;
905     get(crosHandle, metadataType, metadata_get_callback);
906
907     metadataType = android::gralloc4::MetadataType_PixelFormatRequested;
908     get(crosHandle, metadataType, metadata_get_callback);
909
910     metadataType = android::gralloc4::MetadataType_PixelFormatFourCC;
911     get(crosHandle, metadataType, metadata_get_callback);
912
913     metadataType = android::gralloc4::MetadataType_PixelFormatModifier;
914     get(crosHandle, metadataType, metadata_get_callback);
915
916     metadataType = android::gralloc4::MetadataType_Usage;
917     get(crosHandle, metadataType, metadata_get_callback);
918
919     metadataType = android::gralloc4::MetadataType_AllocationSize;
920     get(crosHandle, metadataType, metadata_get_callback);
921
922     metadataType = android::gralloc4::MetadataType_ProtectedContent;
923     get(crosHandle, metadataType, metadata_get_callback);
924
925     metadataType = android::gralloc4::MetadataType_Compression;
926     get(crosHandle, metadataType, metadata_get_callback);
927
928     metadataType = android::gralloc4::MetadataType_Interlaced;
929     get(crosHandle, metadataType, metadata_get_callback);
930
931     metadataType = android::gralloc4::MetadataType_ChromaSiting;
932     get(crosHandle, metadataType, metadata_get_callback);
933
934     metadataType = android::gralloc4::MetadataType_PlaneLayouts;
935     get(crosHandle, metadataType, metadata_get_callback);
936
937     metadataType = android::gralloc4::MetadataType_Dataspace;
938     get(crosHandle, metadataType, metadata_get_callback);
939
940     metadataType = android::gralloc4::MetadataType_BlendMode;
941     get(crosHandle, metadataType, metadata_get_callback);
942
943     bufferDump.metadataDump = metadataDumps;
944     hidlCb(Error::NONE, bufferDump);
945     return Void();
946 }
947
948 Return<void> CrosGralloc4Mapper::dumpBuffers(dumpBuffers_cb hidlCb) {
949     std::vector<BufferDump> bufferDumps;
950
951     if (!mDriver) {
952         drv_log("Failed to dumpBuffers. Driver is uninitialized.\n");
953         hidlCb(Error::NO_RESOURCES, bufferDumps);
954         return Void();
955     }
956
957     Error error = Error::NONE;
958
959     auto handleCallback = [&](cros_gralloc_handle_t crosHandle) {
960         auto dumpBufferCallback = [&](Error err, BufferDump bufferDump) {
961             error = err;
962             if (error == Error::NONE) {
963                 bufferDumps.push_back(bufferDump);
964             }
965         };
966
967         dumpBuffer(crosHandle, dumpBufferCallback);
968     };
969     mDriver->for_each_handle(handleCallback);
970
971     hidlCb(error, bufferDumps);
972     return Void();
973 }
974
975 Return<void> CrosGralloc4Mapper::getReservedRegion(void* rawHandle, getReservedRegion_cb hidlCb) {
976     if (!mDriver) {
977         drv_log("Failed to getReservedRegion. Driver is uninitialized.\n");
978         hidlCb(Error::NO_RESOURCES, nullptr, 0);
979         return Void();
980     }
981
982     buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
983     if (!bufferHandle) {
984         drv_log("Failed to getReservedRegion. Empty handle.\n");
985         hidlCb(Error::BAD_BUFFER, nullptr, 0);
986         return Void();
987     }
988
989     cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
990     if (!crosHandle) {
991         drv_log("Failed to getReservedRegion. Invalid handle.\n");
992         hidlCb(Error::BAD_BUFFER, nullptr, 0);
993         return Void();
994     }
995
996     void* reservedRegionAddr = nullptr;
997     uint64_t reservedRegionSize = 0;
998     int ret = mDriver->get_reserved_region(bufferHandle, &reservedRegionAddr, &reservedRegionSize);
999     if (ret) {
1000         drv_log("Failed to getReservedRegion.\n");
1001         hidlCb(Error::BAD_BUFFER, nullptr, 0);
1002         return Void();
1003     }
1004
1005     hidlCb(Error::NONE, reservedRegionAddr, reservedRegionSize);
1006     return Void();
1007 }
1008
1009 android::hardware::graphics::mapper::V4_0::IMapper* HIDL_FETCH_IMapper(const char* /*name*/) {
1010     return static_cast<android::hardware::graphics::mapper::V4_0::IMapper*>(new CrosGralloc4Mapper);
1011 }