blob: 1f3d3f6551b5b2692496a48a80bc8266322519e9 [file] [log] [blame]
Sam Protsenkoce268502023-09-08 19:45:36 -05001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <limits.h>
18#include <errno.h>
19#include <pthread.h>
20#include <unistd.h>
21#include <string.h>
22
23#include <sys/mman.h>
24#include <sys/stat.h>
25#include <sys/types.h>
26
27#include <log/log.h>
28#include <cutils/atomic.h>
29
30#include <hardware/hardware.h>
31#include <hardware/gralloc.h>
32#include <inttypes.h>
33#include <sync/sync.h>
34
35#include <hardware/exynos/ion.h>
36#include <linux/ion.h>
37#include <exynos_ion.h>
38#include "gralloc_priv.h"
39#include "exynos_format.h"
40
41#include "VendorVideoAPI.h"
42#define INT_TO_PTR(var) ((void *)(unsigned long)var)
43#define MSCL_EXT_SIZE 512
44#define MSCL_ALIGN 128
45
46#define PRIV_SIZE sizeof(ExynosVideoMeta)
47
48#include "format_chooser.h"
49
50/*****************************************************************************/
51int getIonFd(gralloc_module_t const *module)
52{
53 private_module_t* m = const_cast<private_module_t*>(reinterpret_cast<const private_module_t*>(module));
54 if (m->ionfd == -1)
55 m->ionfd = exynos_ion_open();
56 return m->ionfd;
57}
58
59static int gralloc_map(gralloc_module_t const* module, buffer_handle_t handle)
60{
61 void *privAddress;
62
63 private_handle_t *hnd = (private_handle_t*)handle;
64 hnd->base = hnd->base1 = hnd->base2 = 0;
65
66 switch (hnd->format) {
67 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B:
68 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV:
69 privAddress = mmap(0, hnd->size2, PROT_READ|PROT_WRITE, MAP_SHARED, hnd->fd2, 0);
70 if (privAddress == MAP_FAILED) {
71 ALOGE("%s: could not mmap %s", __func__, strerror(errno));
72 } else {
73 hnd->base2 = (uint64_t)privAddress;
74 exynos_ion_sync_fd(getIonFd(module), hnd->fd2);
75 }
76 break;
77 default:
78 break;
79 }
80
81 if ((hnd->flags & GRALLOC_USAGE_PROTECTED) &&
82 !(hnd->flags & GRALLOC_USAGE_PRIVATE_NONSECURE)) {
83 return 0;
84 }
85
86 if (!(hnd->flags & GRALLOC_USAGE_PROTECTED) && !(hnd->flags & GRALLOC_USAGE_NOZEROED)) {
87 void* mappedAddress = mmap(0, hnd->size, PROT_READ|PROT_WRITE, MAP_SHARED,
88 hnd->fd, 0);
89 if (mappedAddress == MAP_FAILED) {
90 ALOGE("%s: could not mmap %s", __func__, strerror(errno));
91 return -errno;
92 }
93 hnd->base = (uint64_t)mappedAddress;
94 exynos_ion_sync_fd(getIonFd(module), hnd->fd);
95
96 if (hnd->fd1 >= 0) {
97 void *mappedAddress1 = (void*)mmap(0, hnd->size1, PROT_READ|PROT_WRITE,
98 MAP_SHARED, hnd->fd1, 0);
99 if (mappedAddress1 == MAP_FAILED) {
100 ALOGE("%s: could not mmap %s", __func__, strerror(errno));
101 return -errno;
102 }
103 hnd->base1 = (uint64_t)mappedAddress1;
104 exynos_ion_sync_fd(getIonFd(module), hnd->fd1);
105 }
106 if (hnd->fd2 >= 0) {
107 if ((hnd->format != HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV) &&
108 (hnd->format != HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B)) {
109 void *mappedAddress2 = (void*)mmap(0, hnd->size2, PROT_READ|PROT_WRITE, MAP_SHARED, hnd->fd2, 0);
110 if (mappedAddress2 == MAP_FAILED) {
111 ALOGE("%s: could not mmap %s", __func__, strerror(errno));
112 return -errno;
113 }
114 hnd->base2 = (uint64_t)mappedAddress2;
115 exynos_ion_sync_fd(getIonFd(module), hnd->fd2);
116 }
117 }
118 }
119
120 return 0;
121}
122
123static int gralloc_unmap(buffer_handle_t handle)
124{
125 private_handle_t* hnd = (private_handle_t*)handle;
126
127 switch (hnd->format) {
128 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B:
129 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV:
130 if (munmap(INT_TO_PTR(hnd->base2), hnd->size2) < 0) {
131 ALOGE("%s :could not unmap %s %#" PRIx64 " %d", __func__, strerror(errno), hnd->base2, hnd->size2);
132 }
133 hnd->base2 = 0;
134 break;
135 default:
136 break;
137 }
138
139 if (!hnd->base)
140 return 0;
141
142 if (munmap(INT_TO_PTR(hnd->base), hnd->size) < 0) {
143 ALOGE("%s :could not unmap %s %#" PRIx64 " %d", __func__, strerror(errno), hnd->base, hnd->size);
144 }
145 hnd->base = 0;
146
147 if (hnd->fd1 >= 0) {
148 if (!hnd->base1)
149 return 0;
150 if (munmap(INT_TO_PTR(hnd->base1), hnd->size1) < 0) {
151 ALOGE("%s :could not unmap %s %#" PRIx64 " %d", __func__, strerror(errno), hnd->base1, hnd->size1);
152 }
153 hnd->base1 = 0;
154 }
155 if (hnd->fd2 >= 0) {
156 if (!hnd->base2)
157 return 0;
158 if (munmap(INT_TO_PTR(hnd->base2), hnd->size2) < 0) {
159 ALOGE("%s :could not unmap %s %#" PRIx64 " %d", __func__, strerror(errno), hnd->base2, hnd->size2);
160 }
161 hnd->base2 = 0;
162 }
163 return 0;
164}
165
166/*****************************************************************************/
167
168int grallocMap(gralloc_module_t const* module, private_handle_t *hnd)
169{
170 return gralloc_map(module, hnd);
171}
172
173int grallocUnmap(private_handle_t *hnd)
174{
175 return gralloc_unmap(hnd);
176}
177
178/*****************************************************************************/
179
180int gralloc_register_buffer(gralloc_module_t const* module,
181 buffer_handle_t handle)
182{
183 int err;
184 if (private_handle_t::validate(handle) < 0)
185 return -EINVAL;
186
187 err = gralloc_map(module, handle);
188
189 private_handle_t* hnd = (private_handle_t*)handle;
190 ALOGV("%s: base %#" PRIx64 " %d %d %d %d\n", __func__, hnd->base, hnd->size,
191 hnd->width, hnd->height, hnd->stride);
192
193 int ret;
194 ret = exynos_ion_import_handle(getIonFd(module), hnd->fd, &hnd->handle);
195 if (ret)
196 ALOGE("error importing handle %d %x\n", hnd->fd, hnd->format);
197 if (hnd->fd1 >= 0) {
198 ret = exynos_ion_import_handle(getIonFd(module), hnd->fd1, &hnd->handle1);
199 if (ret)
200 ALOGE("error importing handle1 %d %x\n", hnd->fd1, hnd->format);
201 }
202 if (hnd->fd2 >= 0) {
203 ret = exynos_ion_import_handle(getIonFd(module), hnd->fd2, &hnd->handle2);
204 if (ret)
205 ALOGE("error importing handle2 %d %x\n", hnd->fd2, hnd->format);
206 }
207
208 return err;
209}
210
211int gralloc_unregister_buffer(gralloc_module_t const* module,
212 buffer_handle_t handle)
213{
214 if (private_handle_t::validate(handle) < 0)
215 return -EINVAL;
216
217 private_handle_t* hnd = (private_handle_t*)handle;
218 ALOGV("%s: base %#" PRIx64 " %d %d %d %d\n", __func__, hnd->base, hnd->size,
219 hnd->width, hnd->height, hnd->stride);
220
221 gralloc_unmap(handle);
222
223 if (hnd->handle)
224 exynos_ion_free_handle(getIonFd(module), hnd->handle);
225 if (hnd->handle1)
226 exynos_ion_free_handle(getIonFd(module), hnd->handle1);
227 if (hnd->handle2)
228 exynos_ion_free_handle(getIonFd(module), hnd->handle2);
229
230 return 0;
231}
232
233int gralloc_lock(gralloc_module_t const* module,
234 buffer_handle_t handle, int usage,
235 int l, int t, int w, int h,
236 void** vaddr)
237{
238 // this is called when a buffer is being locked for software
239 // access. in thin implementation we have nothing to do since
240 // not synchronization with the h/w is needed.
241 // typically this is used to wait for the h/w to finish with
242 // this buffer if relevant. the data cache may need to be
243 // flushed or invalidated depending on the usage bits and the
244 // hardware.
245
246 if (private_handle_t::validate(handle) < 0)
247 {
248 ALOGE("handle is not valid. usage(%x), l,t,w,h(%d, %d, %d, %d)\n", usage, l, t, w, h);
249 return -EINVAL;
250 }
251
252 private_handle_t* hnd = (private_handle_t*)handle;
253
254 if (hnd->frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
255 ALOGE("gralloc_lock can't be used with YCbCr_420_888 format");
256 return -EINVAL;
257 }
258
259 switch(hnd->format)
260 {
261 case HAL_PIXEL_FORMAT_EXYNOS_ARGB_8888:
262 case HAL_PIXEL_FORMAT_RGBA_8888:
263 case HAL_PIXEL_FORMAT_RGBX_8888:
264 case HAL_PIXEL_FORMAT_BGRA_8888:
265 case HAL_PIXEL_FORMAT_RGB_888:
266 case HAL_PIXEL_FORMAT_RGB_565:
267 case HAL_PIXEL_FORMAT_RAW16:
268 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
269 case HAL_PIXEL_FORMAT_BLOB:
270 case HAL_PIXEL_FORMAT_YCbCr_422_I:
271 case HAL_PIXEL_FORMAT_Y8:
272 case HAL_PIXEL_FORMAT_Y16:
273 case HAL_PIXEL_FORMAT_YV12:
274 case HAL_PIXEL_FORMAT_RGBA_1010102:
275 break;
276 default:
277 ALOGE("gralloc_lock doesn't support YUV formats. Please use gralloc_lock_ycbcr()");
278 return -EINVAL;
279 }
280
281#ifdef GRALLOC_RANGE_FLUSH
282 if(usage & GRALLOC_USAGE_SW_WRITE_MASK)
283 {
284 hnd->lock_usage = GRALLOC_USAGE_SW_WRITE_RARELY;
285 hnd->lock_offset = t * hnd->stride;
286 hnd->lock_len = h * hnd->stride;
287 }
288 else
289 {
290 hnd->lock_usage = 0;
291 hnd->lock_offset = 0;
292 hnd->lock_len = 0;
293 }
294#endif
295
296 if (!hnd->base)
297 gralloc_map(module, hnd);
298
299 *vaddr = INT_TO_PTR(hnd->base);
300
301 return 0;
302}
303
304int gralloc_unlock(gralloc_module_t const* module,
305 buffer_handle_t handle)
306{
307 // we're done with a software buffer. nothing to do in this
308 // implementation. typically this is used to flush the data cache.
309 if (private_handle_t::validate(handle) < 0)
310 return -EINVAL;
311
312 private_handle_t* hnd = (private_handle_t*)handle;
313
314 if (!((hnd->flags & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN))
315 return 0;
316
317#ifdef GRALLOC_RANGE_FLUSH
318 if(hnd->lock_usage & GRALLOC_USAGE_SW_WRITE_MASK)
319 {
320 if(((hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
321 || (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)) && (hnd->lock_offset != 0))
322 exynos_ion_sync_fd_partial(getIonFd(module), hnd->fd, hnd->lock_offset * 4, hnd->lock_len * 4);
323 else
324 exynos_ion_sync_fd(getIonFd(module), hnd->fd);
325
326 if (hnd->fd1 >= 0)
327 exynos_ion_sync_fd(getIonFd(module), hnd->fd1);
328 if (hnd->fd2 >= 0)
329 exynos_ion_sync_fd(getIonFd(module), hnd->fd2);
330
331 hnd->lock_usage = 0;
332 }
333#else
334 exynos_ion_sync_fd(getIonFd(module), hnd->fd);
335
336 if (hnd->fd1 >= 0)
337 exynos_ion_sync_fd(getIonFd(module), hnd->fd1);
338 if (hnd->fd2 >= 0)
339 exynos_ion_sync_fd(getIonFd(module), hnd->fd2);
340#endif
341
342 return 0;
343}
344
345int gralloc_lock_ycbcr(gralloc_module_t const* module,
346 buffer_handle_t handle, int usage,
347 int l, int t, int w, int h,
348 android_ycbcr *ycbcr)
349{
350 if (private_handle_t::validate(handle) < 0)
351 {
352 ALOGE("handle is not valid. usage(%x), l,t,w,h(%d, %d, %d, %d)\n", usage, l, t, w, h);
353 return -EINVAL;
354 }
355
356 if (!ycbcr) {
357 ALOGE("gralloc_lock_ycbcr got NULL ycbcr struct");
358 return -EINVAL;
359 }
360
361 int ext_size = 256;
362
363 private_handle_t* hnd = (private_handle_t*)handle;
364
365 if (!hnd->base)
366 gralloc_map(module, hnd);
367
368 // If all CPU addresses are still NULL, do not anything.
369 if (!hnd->base && !hnd->base1 && !hnd->base2)
370 return 0;
371
372 // Calculate offsets to underlying YUV data
373 size_t yStride;
374 size_t cStride;
375 size_t uOffset;
376 size_t vOffset;
377 size_t cStep;
378 switch (hnd->format) {
379 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
380 yStride = cStride = hnd->width;
381 vOffset = yStride * hnd->height;
382 uOffset = vOffset + 1;
383 cStep = 2;
384 ycbcr->y = (void *)((unsigned long)hnd->base);
385 ycbcr->cb = (void *)(((unsigned long)hnd->base) + uOffset);
386 ycbcr->cr = (void *)(((unsigned long)hnd->base) + vOffset);
387 break;
388 case HAL_PIXEL_FORMAT_YV12:
389 yStride = ALIGN(hnd->width, 16);
390 cStride = ALIGN(yStride/2, 16);
391 vOffset = yStride * hnd->height;
392 uOffset = vOffset + (cStride * (hnd->height / 2));
393 cStep = 1;
394 ycbcr->y = (void*)((unsigned long)hnd->base);
395 ycbcr->cr = (void*)(((unsigned long)hnd->base) + vOffset);
396 ycbcr->cb = (void*)(((unsigned long)hnd->base) + uOffset);
397 cStep = 1;
398 break;
399 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
400 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV:
401 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B:
402 yStride = cStride = hnd->stride;
403 vOffset = 1;
404 cStep = 2;
405 ycbcr->y = (void *)((unsigned long)hnd->base);
406 ycbcr->cb = (void *)((unsigned long)hnd->base1);
407 ycbcr->cr = (void *)(((unsigned long)hnd->base1) + vOffset);
408
409 if ((hnd->format != HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M) && (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)) /* usage name will be changed as GRALLOC_USAGE_HW_VIDEO since v2.0 */
410 ycbcr->cr = (void *)((unsigned long)hnd->base2);
411 break;
412 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P:
413 yStride = hnd->stride;
414 cStride = ALIGN(yStride/2, 16);
415 uOffset = yStride * hnd->height;
416 vOffset = uOffset + (cStride * (hnd->height / 2));
417 cStep = 1;
418 ycbcr->y = (void *)((unsigned long)hnd->base);
419 ycbcr->cb = (void*)(((unsigned long)hnd->base) + uOffset);
420 ycbcr->cr = (void*)(((unsigned long)hnd->base) + vOffset);
421 break;
422 /* separated color plane */
423 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED: /* can't describe tiled format for user application */
424 if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) { /* usage name will be changed as GRALLOC_USAGE_HW_VIDEO since v2.0 */
425 yStride = hnd->stride;
426 cStride = hnd->stride;
427 cStep = 1;
428 ycbcr->y = (void *)((unsigned long)hnd->base);
429 ycbcr->cb = (void *)((unsigned long)hnd->base1);
430 ycbcr->cr = NULL;
431 } else {
432 ALOGE("gralloc_lock_ycbcr unexpected internal format %x",
433 hnd->format);
434 return -EINVAL;
435 }
436 break;
437 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
438 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
439 yStride = cStride = hnd->stride;
440 uOffset = 1;
441 cStep = 2;
442 ycbcr->y = (void *)((unsigned long)hnd->base);
443 ycbcr->cr = (void *)((unsigned long)hnd->base1);
444 ycbcr->cb = (void *)(((unsigned long)hnd->base1) + uOffset);
445 break;
446 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
447 yStride = hnd->stride;
448 cStride = ALIGN(yStride/2, 16);
449 cStep = 1;
450 ycbcr->y = (void *)((unsigned long)hnd->base);
451 ycbcr->cb = (void *)((unsigned long)hnd->base1);
452 ycbcr->cr = (void *)((unsigned long)hnd->base2);
453 break;
454 case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
455 yStride = hnd->stride;
456 cStride = ALIGN(yStride/2, 16);
457 cStep = 1;
458 ycbcr->y = (void *)((unsigned long)hnd->base);
459 ycbcr->cr = (void *)((unsigned long)hnd->base1);
460 ycbcr->cb = (void *)((unsigned long)hnd->base2);
461 break;
462 case HAL_PIXEL_FORMAT_YCbCr_422_I:
463 yStride = cStride = hnd->stride;
464 cStep = 1;
465 ycbcr->y = (void *)((unsigned long)hnd->base);
466 ycbcr->cb = 0;
467 ycbcr->cr = 0;
468 break;
469 /* included h/w restrictions */
470 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN:
471 yStride = cStride = hnd->stride;
472 uOffset = (yStride * hnd->vstride) + ext_size;
473 vOffset = uOffset + 1;
474 cStep = 2;
475 ycbcr->y = (void *)((unsigned long)hnd->base);
476 ycbcr->cb = (void *)(((unsigned long)hnd->base) + uOffset);
477 ycbcr->cr = (void *)(((unsigned long)hnd->base) + vOffset);
478 break;
479 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B:
480 yStride = cStride = hnd->stride;
481 uOffset = ((yStride * hnd->vstride) + ext_size) + ((ALIGN(hnd->width / 4, 16) * hnd->vstride) + 64);
482 vOffset = uOffset + 1;
483 cStep = 2;
484 ycbcr->y = (void *)((unsigned long)hnd->base);
485 ycbcr->cb = (void *)(((unsigned long)hnd->base) + uOffset);
486 ycbcr->cr = (void *)(((unsigned long)hnd->base) + vOffset);
487 break;
488 case HAL_PIXEL_FORMAT_Y8:
489 case HAL_PIXEL_FORMAT_Y16:
490 yStride = cStride = hnd->stride;
491 uOffset = 0;
492 vOffset = 0;
493 cStep = 1;
494 ycbcr->y = (void *)((unsigned long)hnd->base);
495 ycbcr->cb = 0;
496 ycbcr->cr = 0;
497 break;
498 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M:
499 yStride = cStride = hnd->stride;
500 vOffset = 2;
501 cStep = 2;
502 ycbcr->y = (void *)((unsigned long)hnd->base);
503 ycbcr->cb = (void *)((unsigned long)hnd->base1);
504 ycbcr->cr = (void *)((unsigned long)hnd->base2);
505 break;
506 default:
507 ALOGE("gralloc_lock_ycbcr unexpected internal format %x",
508 hnd->format);
509 return -EINVAL;
510 }
511
512 ycbcr->ystride = yStride;
513 ycbcr->cstride = cStride;
514 ycbcr->chroma_step = cStep;
515
516 // Zero out reserved fields
517 memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
518
519/*
520 ALOGD("gralloc_lock_ycbcr success. format : %x, usage: %x, ycbcr.y: %p, .cb: %p, .cr: %p, "
521 ".ystride: %d , .cstride: %d, .chroma_step: %d", hnd->format, usage,
522 ycbcr->y, ycbcr->cb, ycbcr->cr, ycbcr->ystride, ycbcr->cstride,
523 ycbcr->chroma_step);
524*/
525
526 return 0;
527}