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