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