blob: b1082a00748bc4b4fa3ac8c59d6832f84b5d05fc [file] [log] [blame]
Jason Macnak1de7f662020-01-24 15:05:57 -08001/*
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/gralloc3/CrosGralloc3Mapper.h"
8
9#include <cutils/native_handle.h>
10
Gurchetan Singh2d482e02020-10-05 17:17:13 -070011#include "cros_gralloc/cros_gralloc_helpers.h"
Jason Macnak1de7f662020-01-24 15:05:57 -080012#include "cros_gralloc/gralloc3/CrosGralloc3Utils.h"
Gurchetan Singh2d482e02020-10-05 17:17:13 -070013
Jason Macnak1de7f662020-01-24 15:05:57 -080014#include "helpers.h"
15
16using android::hardware::hidl_handle;
17using android::hardware::hidl_vec;
18using android::hardware::Return;
19using android::hardware::Void;
20using android::hardware::graphics::common::V1_2::BufferUsage;
21using android::hardware::graphics::common::V1_2::PixelFormat;
22using android::hardware::graphics::mapper::V3_0::Error;
23using android::hardware::graphics::mapper::V3_0::IMapper;
24using android::hardware::graphics::mapper::V3_0::YCbCrLayout;
25
26CrosGralloc3Mapper::CrosGralloc3Mapper() : mDriver(std::make_unique<cros_gralloc_driver>()) {
27 if (mDriver->init()) {
28 drv_log("Failed to initialize driver.\n");
29 mDriver = nullptr;
30 }
31}
32
33Return<void> CrosGralloc3Mapper::createDescriptor(const BufferDescriptorInfo& description,
34 createDescriptor_cb hidlCb) {
35 hidl_vec<uint32_t> descriptor;
36
37 if (description.width == 0) {
38 drv_log("Failed to createDescriptor. Bad width: %d.\n", description.width);
39 hidlCb(Error::BAD_VALUE, descriptor);
40 return Void();
41 }
42
43 if (description.height == 0) {
44 drv_log("Failed to createDescriptor. Bad height: %d.\n", description.height);
45 hidlCb(Error::BAD_VALUE, descriptor);
46 return Void();
47 }
48
49 if (description.layerCount == 0) {
50 drv_log("Failed to createDescriptor. Bad layer count: %d.\n", description.layerCount);
51 hidlCb(Error::BAD_VALUE, descriptor);
52 return Void();
53 }
54
55 auto descriptor_opt = encodeBufferDescriptorInfo(description);
56 if (!descriptor_opt) {
57 drv_log("Failed to createDescriptor. Failed to encodeBufferDescriptorInfo\n");
58 hidlCb(Error::BAD_VALUE, descriptor);
59 return Void();
60 }
61
62 descriptor = *descriptor_opt;
63 hidlCb(Error::NONE, descriptor);
64 return Void();
65}
66
67Return<void> CrosGralloc3Mapper::importBuffer(const hidl_handle& handle, importBuffer_cb hidlCb) {
68 if (!mDriver) {
69 drv_log("Failed to import buffer. Driver is uninitialized.\n");
70 hidlCb(Error::NO_RESOURCES, nullptr);
71 return Void();
72 }
73
74 const native_handle_t* bufferHandle = handle.getNativeHandle();
75 if (!bufferHandle || bufferHandle->numFds == 0) {
76 drv_log("Failed to importBuffer. Bad handle.\n");
77 hidlCb(Error::BAD_BUFFER, nullptr);
78 return Void();
79 }
80
81 native_handle_t* importedBufferHandle = native_handle_clone(bufferHandle);
82 if (!importedBufferHandle) {
83 drv_log("Failed to importBuffer. Handle clone failed.\n");
84 hidlCb(Error::NO_RESOURCES, nullptr);
85 return Void();
86 }
87
88 int ret = mDriver->retain(importedBufferHandle);
89 if (ret) {
90 native_handle_close(importedBufferHandle);
91 native_handle_delete(importedBufferHandle);
92 hidlCb(Error::NO_RESOURCES, nullptr);
93 return Void();
94 }
95
96 hidlCb(Error::NONE, importedBufferHandle);
97 return Void();
98}
99
100Return<Error> CrosGralloc3Mapper::freeBuffer(void* rawHandle) {
101 if (!mDriver) {
102 drv_log("Failed to freeBuffer. Driver is uninitialized.\n");
103 return Error::NO_RESOURCES;
104 }
105
106 native_handle_t* bufferHandle = reinterpret_cast<native_handle_t*>(rawHandle);
107 if (!bufferHandle) {
108 drv_log("Failed to freeBuffer. Empty handle.\n");
109 return Error::BAD_BUFFER;
110 }
111
112 int ret = mDriver->release(bufferHandle);
113 if (ret) {
114 drv_log("Failed to freeBuffer.\n");
115 return Error::BAD_BUFFER;
116 }
117
118 native_handle_close(bufferHandle);
119 native_handle_delete(bufferHandle);
120 return Error::NONE;
121}
122
123Return<Error> CrosGralloc3Mapper::validateBufferSize(void* rawHandle,
124 const BufferDescriptorInfo& descriptor,
125 uint32_t stride) {
126 if (!mDriver) {
127 drv_log("Failed to validateBufferSize. Driver is uninitialized.\n");
128 return Error::NO_RESOURCES;
129 }
130
131 native_handle_t* bufferHandle = reinterpret_cast<native_handle_t*>(rawHandle);
132 if (!bufferHandle) {
133 drv_log("Failed to validateBufferSize. Empty handle.\n");
134 return Error::BAD_BUFFER;
135 }
136
137 cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
138 if (!crosHandle) {
139 drv_log("Failed to validateBufferSize. Invalid handle.\n");
140 return Error::BAD_BUFFER;
141 }
142
143 PixelFormat crosHandleFormat = static_cast<PixelFormat>(crosHandle->droid_format);
144 if (descriptor.format != crosHandleFormat) {
145 drv_log("Failed to validateBufferSize. Format mismatch.\n");
146 return Error::BAD_BUFFER;
147 }
148
149 if (descriptor.width != crosHandle->width) {
150 drv_log("Failed to validateBufferSize. Width mismatch (%d vs %d).\n", descriptor.width,
151 crosHandle->width);
152 return Error::BAD_VALUE;
153 }
154
155 if (descriptor.height != crosHandle->height) {
156 drv_log("Failed to validateBufferSize. Height mismatch (%d vs %d).\n", descriptor.height,
157 crosHandle->height);
158 return Error::BAD_VALUE;
159 }
160
161 if (stride != crosHandle->pixel_stride) {
162 drv_log("Failed to validateBufferSize. Stride mismatch (%d vs %d).\n", stride,
163 crosHandle->pixel_stride);
164 return Error::BAD_VALUE;
165 }
166
167 return Error::NONE;
168}
169
170Return<void> CrosGralloc3Mapper::getTransportSize(void* rawHandle, getTransportSize_cb hidlCb) {
171 if (!mDriver) {
172 drv_log("Failed to getTransportSize. Driver is uninitialized.\n");
173 hidlCb(Error::BAD_BUFFER, 0, 0);
174 return Void();
175 }
176
177 native_handle_t* bufferHandle = reinterpret_cast<native_handle_t*>(rawHandle);
178 if (!bufferHandle) {
179 drv_log("Failed to getTransportSize. Bad handle.\n");
180 hidlCb(Error::BAD_BUFFER, 0, 0);
181 return Void();
182 }
183
184 // No local process data is currently stored on the native handle.
185 hidlCb(Error::NONE, bufferHandle->numFds, bufferHandle->numInts);
186 return Void();
187}
188
189Return<void> CrosGralloc3Mapper::lock(void* rawHandle, uint64_t cpuUsage, const Rect& accessRegion,
190 const hidl_handle& acquireFence, lock_cb hidlCb) {
191 if (!mDriver) {
192 drv_log("Failed to lock. Driver is uninitialized.\n");
193 hidlCb(Error::NO_RESOURCES, nullptr, 0, 0);
194 return Void();
195 }
196
197 buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
198 if (!bufferHandle) {
199 drv_log("Failed to lock. Empty handle.\n");
200 hidlCb(Error::BAD_BUFFER, nullptr, 0, 0);
201 return Void();
202 }
203
204 cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
205 if (crosHandle == nullptr) {
206 drv_log("Failed to lock. Invalid handle.\n");
207 hidlCb(Error::BAD_BUFFER, nullptr, 0, 0);
208 return Void();
209 }
210
211 LockResult result = lockInternal(crosHandle, cpuUsage, accessRegion, acquireFence);
212 if (result.error != Error::NONE) {
213 drv_log("Failed to lock. Failed to lockInternal.\n");
214 hidlCb(result.error, nullptr, 0, 0);
215 return Void();
216 }
217
218 int32_t bytesPerPixel = drv_bytes_per_pixel_from_format(crosHandle->format, 0);
219 int32_t bytesPerStride = static_cast<int32_t>(crosHandle->strides[0]);
220
221 hidlCb(Error::NONE, result.mapped[0], bytesPerPixel, bytesPerStride);
222 return Void();
223}
224
225Return<void> CrosGralloc3Mapper::lockYCbCr(void* rawHandle, uint64_t cpuUsage,
226 const Rect& accessRegion,
227 const android::hardware::hidl_handle& acquireFence,
228 lockYCbCr_cb hidlCb) {
229 YCbCrLayout ycbcr = {};
230
231 if (!mDriver) {
232 drv_log("Failed to lock. Driver is uninitialized.\n");
233 hidlCb(Error::NO_RESOURCES, ycbcr);
234 return Void();
235 }
236
237 buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
238 if (!bufferHandle) {
239 drv_log("Failed to lockYCbCr. Empty handle.\n");
240 hidlCb(Error::BAD_BUFFER, ycbcr);
241 return Void();
242 }
243
244 cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
245 if (crosHandle == nullptr) {
246 drv_log("Failed to lockYCbCr. Invalid handle.\n");
247 hidlCb(Error::BAD_BUFFER, ycbcr);
248 return Void();
249 }
250
251 LockResult result = lockInternal(crosHandle, cpuUsage, accessRegion, acquireFence);
252 if (result.error != Error::NONE) {
253 drv_log("Failed to lockYCbCr. Failed to lockInternal.\n");
254 hidlCb(result.error, ycbcr);
255 return Void();
256 }
257
258 switch (crosHandle->format) {
259 case DRM_FORMAT_NV12: {
260 ycbcr.y = result.mapped[0] + crosHandle->offsets[0];
261 ycbcr.cb = result.mapped[0] + crosHandle->offsets[1];
262 ycbcr.cr = result.mapped[0] + crosHandle->offsets[1] + 1;
263 ycbcr.yStride = crosHandle->strides[0];
264 ycbcr.cStride = crosHandle->strides[1];
265 ycbcr.chromaStep = 2;
266 break;
267 }
268 case DRM_FORMAT_NV21: {
269 ycbcr.y = result.mapped[0] + crosHandle->offsets[0];
270 ycbcr.cb = result.mapped[0] + crosHandle->offsets[1] + 1;
271 ycbcr.cr = result.mapped[0] + crosHandle->offsets[1];
272 ycbcr.yStride = crosHandle->strides[0];
273 ycbcr.cStride = crosHandle->strides[1];
274 ycbcr.chromaStep = 2;
275 break;
276 }
277 case DRM_FORMAT_YVU420: {
278 ycbcr.y = result.mapped[0] + crosHandle->offsets[0];
279 ycbcr.cb = result.mapped[0] + crosHandle->offsets[1];
280 ycbcr.cr = result.mapped[0] + crosHandle->offsets[2];
281 ycbcr.yStride = crosHandle->strides[0];
282 ycbcr.cStride = crosHandle->strides[1];
283 ycbcr.chromaStep = 1;
284 break;
285 }
286 case DRM_FORMAT_YVU420_ANDROID: {
287 ycbcr.y = result.mapped[0] + crosHandle->offsets[0];
288 ycbcr.cb = result.mapped[0] + crosHandle->offsets[2];
289 ycbcr.cr = result.mapped[0] + crosHandle->offsets[1];
290 ycbcr.yStride = crosHandle->strides[0];
291 ycbcr.cStride = crosHandle->strides[1];
292 ycbcr.chromaStep = 1;
293 break;
294 }
295 default: {
Gurchetan Singh2d482e02020-10-05 17:17:13 -0700296 std::string format = get_drm_format_string(crosHandle->format);
Jason Macnak1de7f662020-01-24 15:05:57 -0800297 drv_log("Failed to lockYCbCr. Unhandled format: %s\n", format.c_str());
298 hidlCb(Error::BAD_BUFFER, ycbcr);
299 return Void();
300 }
301 }
302
303 hidlCb(Error::NONE, ycbcr);
304 return Void();
305}
306
307CrosGralloc3Mapper::LockResult CrosGralloc3Mapper::lockInternal(
308 cros_gralloc_handle_t crosHandle, uint64_t cpuUsage, const Rect& region,
309 const android::hardware::hidl_handle& acquireFence) {
310 LockResult result = {};
311
312 if (!mDriver) {
313 drv_log("Failed to lock. Driver is uninitialized.\n");
314 result.error = Error::NO_RESOURCES;
315 return result;
316 }
317
318 if (cpuUsage == 0) {
319 drv_log("Failed to lock. Bad cpu usage: %" PRIu64 ".\n", cpuUsage);
320 result.error = Error::BAD_VALUE;
321 return result;
322 }
323
324 uint32_t mapUsage = 0;
325 int ret = convertToMapUsage(cpuUsage, &mapUsage);
326 if (ret) {
327 drv_log("Failed to lock. Convert usage failed.\n");
328 result.error = Error::BAD_VALUE;
329 return result;
330 }
331
332 if (region.left < 0) {
333 drv_log("Failed to lock. Invalid region: negative left value %d.\n", region.left);
334 result.error = Error::BAD_VALUE;
335 return result;
336 }
337
338 if (region.top < 0) {
339 drv_log("Failed to lock. Invalid region: negative top value %d.\n", region.top);
340 result.error = Error::BAD_VALUE;
341 return result;
342 }
343
344 if (region.width < 0) {
345 drv_log("Failed to lock. Invalid region: negative width value %d.\n", region.width);
346 result.error = Error::BAD_VALUE;
347 return result;
348 }
349
350 if (region.height < 0) {
351 drv_log("Failed to lock. Invalid region: negative height value %d.\n", region.height);
352 result.error = Error::BAD_VALUE;
353 return result;
354 }
355
356 if (region.width > crosHandle->width) {
357 drv_log("Failed to lock. Invalid region: width greater than buffer width (%d vs %d).\n",
358 region.width, crosHandle->width);
359 result.error = Error::BAD_VALUE;
360 return result;
361 }
362
363 if (region.height > crosHandle->height) {
364 drv_log("Failed to lock. Invalid region: height greater than buffer height (%d vs %d).\n",
365 region.height, crosHandle->height);
366 result.error = Error::BAD_VALUE;
367 return result;
368 }
369
370 struct rectangle rect = {static_cast<uint32_t>(region.left), static_cast<uint32_t>(region.top),
371 static_cast<uint32_t>(region.width),
372 static_cast<uint32_t>(region.height)};
373
374 // An access region of all zeros means the entire buffer.
375 if (rect.x == 0 && rect.y == 0 && rect.width == 0 && rect.height == 0) {
376 rect.width = crosHandle->width;
377 rect.height = crosHandle->height;
378 }
379
380 int acquireFenceFd = -1;
381 ret = convertToFenceFd(acquireFence, &acquireFenceFd);
382 if (ret) {
383 drv_log("Failed to lock. Bad acquire fence.\n");
384 result.error = Error::BAD_VALUE;
385 return result;
386 }
387
388 buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(crosHandle);
389 ret = mDriver->lock(bufferHandle, acquireFenceFd, false, &rect, mapUsage, result.mapped);
390 if (ret) {
391 result.error = Error::BAD_VALUE;
392 return result;
393 }
394
395 result.error = Error::NONE;
396 return result;
397}
398
399Return<void> CrosGralloc3Mapper::unlock(void* rawHandle, unlock_cb hidlCb) {
400 if (!mDriver) {
401 drv_log("Failed to unlock. Driver is uninitialized.\n");
402 hidlCb(Error::BAD_BUFFER, nullptr);
403 return Void();
404 }
405
406 buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
407 if (!bufferHandle) {
408 drv_log("Failed to unlock. Empty handle.\n");
409 hidlCb(Error::BAD_BUFFER, nullptr);
410 return Void();
411 }
412
413 int releaseFenceFd = -1;
414 int ret = mDriver->unlock(bufferHandle, &releaseFenceFd);
415 if (ret) {
416 drv_log("Failed to unlock.\n");
417 hidlCb(Error::BAD_BUFFER, nullptr);
418 return Void();
419 }
420
421 hidl_handle releaseFenceHandle;
422 ret = convertToFenceHandle(releaseFenceFd, &releaseFenceHandle);
423 if (ret) {
424 drv_log("Failed to unlock. Failed to convert release fence to handle.\n");
425 hidlCb(Error::BAD_BUFFER, nullptr);
426 return Void();
427 }
428
429 hidlCb(Error::NONE, releaseFenceHandle);
430 return Void();
431}
432
433Return<void> CrosGralloc3Mapper::isSupported(const BufferDescriptorInfo& descriptor,
434 isSupported_cb hidlCb) {
435 if (!mDriver) {
436 drv_log("Failed to isSupported. Driver is uninitialized.\n");
437 hidlCb(Error::BAD_VALUE, false);
438 return Void();
439 }
440
441 struct cros_gralloc_buffer_descriptor crosDescriptor;
442 if (convertToCrosDescriptor(descriptor, &crosDescriptor)) {
443 hidlCb(Error::NONE, false);
444 return Void();
445 }
446
447 bool supported = mDriver->is_supported(&crosDescriptor);
448 if (!supported) {
449 crosDescriptor.use_flags &= ~BO_USE_SCANOUT;
450 supported = mDriver->is_supported(&crosDescriptor);
451 }
452
453 hidlCb(Error::NONE, supported);
454 return Void();
455}
456
457int CrosGralloc3Mapper::getResolvedDrmFormat(PixelFormat pixelFormat, uint64_t bufferUsage,
458 uint32_t* outDrmFormat) {
459 uint32_t drmFormat;
460 if (convertToDrmFormat(pixelFormat, &drmFormat)) {
461 std::string pixelFormatString = getPixelFormatString(pixelFormat);
462 drv_log("Failed to getResolvedDrmFormat. Failed to convert format %s\n",
463 pixelFormatString.c_str());
464 return -1;
465 }
466
467 uint64_t usage;
468 if (convertToBufferUsage(bufferUsage, &usage)) {
469 std::string usageString = getUsageString(bufferUsage);
470 drv_log("Failed to getResolvedDrmFormat. Failed to convert usage %s\n",
471 usageString.c_str());
472 return -1;
473 }
474
475 uint32_t resolvedDrmFormat = mDriver->get_resolved_drm_format(drmFormat, usage);
476 if (resolvedDrmFormat == DRM_FORMAT_INVALID) {
Gurchetan Singh2d482e02020-10-05 17:17:13 -0700477 std::string drmFormatString = get_drm_format_string(drmFormat);
Jason Macnak1de7f662020-01-24 15:05:57 -0800478 drv_log("Failed to getResolvedDrmFormat. Failed to resolve drm format %s\n",
479 drmFormatString.c_str());
480 return -1;
481 }
482
483 *outDrmFormat = resolvedDrmFormat;
484
485 return 0;
486}
487
488android::hardware::graphics::mapper::V3_0::IMapper* HIDL_FETCH_IMapper(const char* /*name*/) {
489 return static_cast<android::hardware::graphics::mapper::V3_0::IMapper*>(new CrosGralloc3Mapper);
490}