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