blob: f458a624d50c43c35e1afc3ee0e8de0c5706cdf0 [file] [log] [blame]
Vishal Bhoj78e90492015-12-07 01:36:32 +05301/*
2 * Copyright (C) 2010 ARM Limited. All rights reserved.
3 *
4 * Copyright (C) 2008 The Android Open Source Project
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
Laura Abbott311955b2017-06-30 11:39:35 +053019#include <cstdlib>
Vishal Bhoj78e90492015-12-07 01:36:32 +053020#include <string.h>
21#include <errno.h>
22#include <pthread.h>
John Stultzc3571ac2020-04-23 00:07:31 +000023#include <sys/types.h>
24#include <sys/stat.h>
25#include <fcntl.h>
Vishal Bhoj78e90492015-12-07 01:36:32 +053026
27#include <cutils/log.h>
28#include <cutils/atomic.h>
29#include <hardware/hardware.h>
30#include <hardware/gralloc.h>
31
32#include <sys/ioctl.h>
33
34#include "alloc_device.h"
35#include "gralloc_priv.h"
36#include "gralloc_helper.h"
37#include "framebuffer_device.h"
38
39#if GRALLOC_ARM_UMP_MODULE
40#include <ump/ump.h>
41#include <ump/ump_ref_drv.h>
42#endif
43
44#if GRALLOC_ARM_DMA_BUF_MODULE
Vishal Bhoj78e90492015-12-07 01:36:32 +053045#include <ion/ion.h>
Laura Abbott311955b2017-06-30 11:39:35 +053046#include "ion_4.12.h"
John Stultzc3571ac2020-04-23 00:07:31 +000047#include "dma-heap.h"
John Stultzf3d868d2017-12-05 16:15:11 -080048
49#define ION_SYSTEM (char*)"ion_system_heap"
50#define ION_CMA (char*)"linux,cma"
51
John Stultzc3571ac2020-04-23 00:07:31 +000052#define DMABUF_SYSTEM (char*)"system"
53#define DMABUF_CMA (char*)"linux,cma"
54static enum {
55 INTERFACE_UNKNOWN,
56 INTERFACE_ION_LEGACY,
57 INTERFACE_ION_MODERN,
58 INTERFACE_DMABUF_HEAPS
59} interface_ver;
60
John Stultzf98a4ba2020-04-22 22:50:12 +000061static int system_heap_id;
62static int cma_heap_id;
Vishal Bhoj78e90492015-12-07 01:36:32 +053063#endif
64
Vishal Bhoj78e90492015-12-07 01:36:32 +053065#if GRALLOC_SIMULATE_FAILURES
66#include <cutils/properties.h>
67
68/* system property keys for controlling simulated UMP allocation failures */
69#define PROP_MALI_TEST_GRALLOC_FAIL_FIRST "mali.test.gralloc.fail_first"
70#define PROP_MALI_TEST_GRALLOC_FAIL_INTERVAL "mali.test.gralloc.fail_interval"
71
72static int __ump_alloc_should_fail()
73{
74
75 static unsigned int call_count = 0;
76 unsigned int first_fail = 0;
77 int fail_period = 0;
78 int fail = 0;
79
80 ++call_count;
81
82 /* read the system properties that control failure simulation */
83 {
84 char prop_value[PROPERTY_VALUE_MAX];
85
86 if (property_get(PROP_MALI_TEST_GRALLOC_FAIL_FIRST, prop_value, "0") > 0)
87 {
88 sscanf(prop_value, "%11u", &first_fail);
89 }
90
91 if (property_get(PROP_MALI_TEST_GRALLOC_FAIL_INTERVAL, prop_value, "0") > 0)
92 {
93 sscanf(prop_value, "%11u", &fail_period);
94 }
95 }
96
97 /* failure simulation is enabled by setting the first_fail property to non-zero */
98 if (first_fail > 0)
99 {
100 LOGI("iteration %u (fail=%u, period=%u)\n", call_count, first_fail, fail_period);
101
102 fail = (call_count == first_fail) ||
103 (call_count > first_fail && fail_period > 0 && 0 == (call_count - first_fail) % fail_period);
104
105 if (fail)
106 {
107 AERR("failed ump_ref_drv_allocate on iteration #%d\n", call_count);
108 }
109 }
110
111 return fail;
112}
113#endif
114
John Stultze5c5bb32018-03-20 18:16:49 -0700115#ifdef FBIOGET_DMABUF
116static int fb_get_framebuffer_dmabuf(private_module_t *m, private_handle_t *hnd)
117{
118 struct fb_dmabuf_export fb_dma_buf;
119 int res;
120 res = ioctl(m->framebuffer->fd, FBIOGET_DMABUF, &fb_dma_buf);
121
122 if (res == 0)
123 {
124 hnd->share_fd = fb_dma_buf.fd;
125 return 0;
126 }
127 else
128 {
129 AINF("FBIOGET_DMABUF ioctl failed(%d). See gralloc_priv.h and the integration manual for vendor framebuffer "
130 "integration",
131 res);
132 return -1;
133 }
134}
135#endif
Vishal Bhoj78e90492015-12-07 01:36:32 +0530136
John Stultzf98a4ba2020-04-22 22:50:12 +0000137#if GRALLOC_ARM_DMA_BUF_MODULE
John Stultzc3571ac2020-04-23 00:07:31 +0000138#define DEVPATH "/dev/dma_heap"
139int dma_heap_open(const char* name)
140{
141 int ret, fd;
142 char buf[256];
143
144 ret = sprintf(buf, "%s/%s", DEVPATH, name);
145 if (ret < 0) {
146 AERR("sprintf failed!\n");
147 return ret;
148 }
149
John Stultzc090c642020-09-22 20:09:48 +0000150 fd = open(buf, O_RDONLY);
John Stultzc3571ac2020-04-23 00:07:31 +0000151 if (fd < 0)
152 AERR("open %s failed!\n", buf);
153 return fd;
154}
155
156int dma_heap_alloc(int fd, size_t len, unsigned int flags, int *dmabuf_fd)
157{
158 struct dma_heap_allocation_data data = {
159 .len = len,
160 .fd_flags = O_RDWR | O_CLOEXEC,
161 .heap_flags = flags,
162 };
163 int ret;
164
165 if (dmabuf_fd == NULL)
166 return -EINVAL;
167
168 ret = ioctl(fd, DMA_HEAP_IOCTL_ALLOC, &data);
169 if (ret < 0)
170 return ret;
171 *dmabuf_fd = (int)data.fd;
172 return ret;
173}
174
John Stultzf98a4ba2020-04-22 22:50:12 +0000175static int alloc_ion_fd(int ion_fd, size_t size, unsigned int heap_mask, unsigned int flags, int *shared_fd)
176{
177 int heap;
178
John Stultzc3571ac2020-04-23 00:07:31 +0000179 if (interface_ver == INTERFACE_DMABUF_HEAPS) {
180 int fd = system_heap_id;
181 unsigned long flg = 0;
182 if (heap_mask == ION_HEAP_TYPE_DMA_MASK)
183 fd = cma_heap_id;
184
185 return dma_heap_alloc(fd, size, flg, shared_fd);
186 }
187
188 if (interface_ver == INTERFACE_ION_MODERN) {
John Stultzf98a4ba2020-04-22 22:50:12 +0000189 heap = 1 << system_heap_id;
190 if (heap_mask == ION_HEAP_TYPE_DMA_MASK)
191 heap = 1 << cma_heap_id;
192 } else {
193 heap = heap_mask;
194 }
195 return ion_alloc_fd(ion_fd, size, 0, heap, flags, shared_fd);
196}
197#endif
198
Vishal Bhoj78e90492015-12-07 01:36:32 +0530199static int gralloc_alloc_buffer(alloc_device_t *dev, size_t size, int usage, buffer_handle_t *pHandle)
200{
201#if GRALLOC_ARM_DMA_BUF_MODULE
202 {
203 private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
John Stultze5c5bb32018-03-20 18:16:49 -0700204 void *cpu_ptr = MAP_FAILED;
Vishal Bhoj78e90492015-12-07 01:36:32 +0530205 int shared_fd;
206 int ret;
John Stultze5c5bb32018-03-20 18:16:49 -0700207 unsigned int heap_mask;
208 int lock_state = 0;
209 int map_mask = 0;
Vishal Bhoj78e90492015-12-07 01:36:32 +0530210
John Stultzf98a4ba2020-04-22 22:50:12 +0000211 if (usage & GRALLOC_USAGE_PROTECTED) {
John Stultze5c5bb32018-03-20 18:16:49 -0700212#if defined(ION_HEAP_SECURE_MASK)
213 heap_mask = ION_HEAP_SECURE_MASK;
214#else
215 AERR("The platform does NOT support protected ION memory.");
216 return -1;
217#endif
Chia-I Wu06695a62017-05-08 12:55:28 -0700218 }
John Stultzf98a4ba2020-04-22 22:50:12 +0000219 else if (usage & GRALLOC_USAGE_HW_FB) {
220 heap_mask = ION_HEAP_TYPE_DMA_MASK;
221 }
222 else {
John Stultze5c5bb32018-03-20 18:16:49 -0700223 heap_mask = ION_HEAP_SYSTEM_MASK;
Laura Abbott6ed00bc2017-06-30 11:39:35 +0530224 }
Chia-I Wu06695a62017-05-08 12:55:28 -0700225
John Stultzf98a4ba2020-04-22 22:50:12 +0000226 ret = alloc_ion_fd(m->ion_client, size, heap_mask, 0, &shared_fd);
227 if (ret != 0) {
228 AERR("Failed to ion_alloc_fd from ion_client:%d", m->ion_client);
229 return -1;
John Stultze5c5bb32018-03-20 18:16:49 -0700230 }
231
232 if (!(usage & GRALLOC_USAGE_PROTECTED))
233 {
234 map_mask = PROT_READ | PROT_WRITE;
235 }
236 else
237 {
238 map_mask = PROT_WRITE;
239 }
John Stultze5c5bb32018-03-20 18:16:49 -0700240
241 cpu_ptr = mmap(NULL, size, map_mask, MAP_SHARED, shared_fd, 0);
Vishal Bhoj78e90492015-12-07 01:36:32 +0530242
243 if (MAP_FAILED == cpu_ptr)
244 {
245 AERR("ion_map( %d ) failed", m->ion_client);
246
Vishal Bhoj78e90492015-12-07 01:36:32 +0530247 close(shared_fd);
248 return -1;
249 }
250
John Stultze5c5bb32018-03-20 18:16:49 -0700251 lock_state = private_handle_t::LOCK_STATE_MAPPED;
252
253 private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_ION, usage, size, cpu_ptr, lock_state);
Vishal Bhoj78e90492015-12-07 01:36:32 +0530254
255 if (NULL != hnd)
256 {
257 hnd->share_fd = shared_fd;
Vishal Bhoj78e90492015-12-07 01:36:32 +0530258 *pHandle = hnd;
259 return 0;
260 }
261 else
262 {
263 AERR("Gralloc out of mem for ion_client:%d", m->ion_client);
264 }
265
266 close(shared_fd);
John Stultze5c5bb32018-03-20 18:16:49 -0700267
Vishal Bhoj78e90492015-12-07 01:36:32 +0530268 ret = munmap(cpu_ptr, size);
269
270 if (0 != ret)
271 {
272 AERR("munmap failed for base:%p size: %lu", cpu_ptr, (unsigned long)size);
273 }
274
Vishal Bhoj78e90492015-12-07 01:36:32 +0530275 return -1;
276 }
277#endif
278
279#if GRALLOC_ARM_UMP_MODULE
280 MALI_IGNORE(dev);
281 {
282 ump_handle ump_mem_handle;
283 void *cpu_ptr;
284 ump_secure_id ump_id;
285 ump_alloc_constraints constraints;
286
287 size = round_up_to_page_size(size);
288
289 if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN)
290 {
291 constraints = UMP_REF_DRV_CONSTRAINT_USE_CACHE;
292 }
293 else
294 {
295 constraints = UMP_REF_DRV_CONSTRAINT_NONE;
296 }
297
298#ifdef GRALLOC_SIMULATE_FAILURES
299
300 /* if the failure condition matches, fail this iteration */
301 if (__ump_alloc_should_fail())
302 {
303 ump_mem_handle = UMP_INVALID_MEMORY_HANDLE;
304 }
305 else
306#endif
307 {
John Stultze5c5bb32018-03-20 18:16:49 -0700308 if (usage & GRALLOC_USAGE_PROTECTED)
Vishal Bhoj78e90492015-12-07 01:36:32 +0530309 {
John Stultze5c5bb32018-03-20 18:16:49 -0700310 AERR("gralloc_alloc_buffer() does not support to allocate protected UMP memory.");
Vishal Bhoj78e90492015-12-07 01:36:32 +0530311 }
312 else
313 {
John Stultze5c5bb32018-03-20 18:16:49 -0700314 ump_mem_handle = ump_ref_drv_allocate(size, constraints);
315
316 if (UMP_INVALID_MEMORY_HANDLE != ump_mem_handle)
317 {
318 cpu_ptr = ump_mapped_pointer_get(ump_mem_handle);
319
320 if (NULL != cpu_ptr)
321 {
322 ump_id = ump_secure_id_get(ump_mem_handle);
323
324 if (UMP_INVALID_SECURE_ID != ump_id)
325 {
326 private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_UMP, usage, size, cpu_ptr,
327 private_handle_t::LOCK_STATE_MAPPED, ump_id, ump_mem_handle);
328
329 if (NULL != hnd)
330 {
331 *pHandle = hnd;
332 return 0;
333 }
334 else
335 {
336 AERR("gralloc_alloc_buffer() failed to allocate handle. ump_handle = %p, ump_id = %d", ump_mem_handle, ump_id);
337 }
338 }
339 else
340 {
341 AERR("gralloc_alloc_buffer() failed to retrieve valid secure id. ump_handle = %p", ump_mem_handle);
342 }
343
344 ump_mapped_pointer_release(ump_mem_handle);
345 }
346 else
347 {
348 AERR("gralloc_alloc_buffer() failed to map UMP memory. ump_handle = %p", ump_mem_handle);
349 }
350
351 ump_reference_release(ump_mem_handle);
352 }
353 else
354 {
355 AERR("gralloc_alloc_buffer() failed to allocate UMP memory. size:%d constraints: %d", size, constraints);
356 }
Vishal Bhoj78e90492015-12-07 01:36:32 +0530357 }
358 }
359
360 return -1;
361 }
362#endif
363
364}
365
John Stultzf3d868d2017-12-05 16:15:11 -0800366#ifndef DISABLE_FRAMEBUFFER_HAL
Vishal Bhoj78e90492015-12-07 01:36:32 +0530367static int gralloc_alloc_framebuffer_locked(alloc_device_t *dev, size_t size, int usage, buffer_handle_t *pHandle)
368{
369 private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
370
371 // allocate the framebuffer
372 if (m->framebuffer == NULL)
373 {
374 // initialize the framebuffer, the framebuffer is mapped once and forever.
375 int err = init_frame_buffer_locked(m);
376
377 if (err < 0)
378 {
379 return err;
380 }
381 }
382
John Stultze5c5bb32018-03-20 18:16:49 -0700383 uint32_t bufferMask = m->bufferMask;
Vishal Bhoj78e90492015-12-07 01:36:32 +0530384 const uint32_t numBuffers = m->numBuffers;
385 const size_t bufferSize = m->finfo.line_length * m->info.yres;
386
387 if (numBuffers == 1)
388 {
389 // If we have only one buffer, we never use page-flipping. Instead,
390 // we return a regular buffer which will be memcpy'ed to the main
391 // screen when post is called.
392 int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
393 AERR("fallback to single buffering. Virtual Y-res too small %d", m->info.yres);
394 return gralloc_alloc_buffer(dev, bufferSize, newUsage, pHandle);
395 }
396
397 if (bufferMask >= ((1LU << numBuffers) - 1))
398 {
John Stultze5c5bb32018-03-20 18:16:49 -0700399 // We ran out of buffers, reset bufferMask.
400 bufferMask = 0;
401 m->bufferMask = 0;
Vishal Bhoj78e90492015-12-07 01:36:32 +0530402 }
403
404 void *vaddr = m->framebuffer->base;
405
406 // find a free slot
407 for (uint32_t i = 0 ; i < numBuffers ; i++)
408 {
409 if ((bufferMask & (1LU << i)) == 0)
410 {
411 m->bufferMask |= (1LU << i);
412 break;
413 }
414
415 vaddr = (void *)((uintptr_t)vaddr + bufferSize);
416 }
417
418 // The entire framebuffer memory is already mapped, now create a buffer object for parts of this memory
419 private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_FRAMEBUFFER, usage, size, vaddr,
John Stultze5c5bb32018-03-20 18:16:49 -0700420 0, m->framebuffer->fd, (uintptr_t)vaddr - (uintptr_t) m->framebuffer->base, m->framebuffer->fb_paddr);
421
Vishal Bhoj78e90492015-12-07 01:36:32 +0530422#if GRALLOC_ARM_UMP_MODULE
423 hnd->ump_id = m->framebuffer->ump_id;
424
425 /* create a backing ump memory handle if the framebuffer is exposed as a secure ID */
426 if ((int)UMP_INVALID_SECURE_ID != hnd->ump_id)
427 {
428 hnd->ump_mem_handle = (int)ump_handle_create_from_secure_id(hnd->ump_id);
429
430 if ((int)UMP_INVALID_MEMORY_HANDLE == hnd->ump_mem_handle)
431 {
432 AINF("warning: unable to create UMP handle from secure ID %i\n", hnd->ump_id);
433 }
434 }
435
436#endif
437
438#if GRALLOC_ARM_DMA_BUF_MODULE
439 {
440#ifdef FBIOGET_DMABUF
John Stultze5c5bb32018-03-20 18:16:49 -0700441 /*
442 * Perform allocator specific actions. If these fail we fall back to a regular buffer
443 * which will be memcpy'ed to the main screen when fb_post is called.
444 */
445 if (fb_get_framebuffer_dmabuf(m, hnd) == -1)
Vishal Bhoj78e90492015-12-07 01:36:32 +0530446 {
John Stultze5c5bb32018-03-20 18:16:49 -0700447 int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
Vishal Bhoj78e90492015-12-07 01:36:32 +0530448
John Stultze5c5bb32018-03-20 18:16:49 -0700449 AINF("Fallback to single buffering. Unable to map framebuffer memory to handle:%p", hnd);
450 return gralloc_alloc_buffer(dev, bufferSize, newUsage, pHandle);
451 }
Vishal Bhoj78e90492015-12-07 01:36:32 +0530452#endif
453 }
Chia-I Wua12e37d2017-05-08 12:46:13 -0700454
455 // correct numFds/numInts when there is no dmabuf fd
John Stultze5c5bb32018-03-20 18:16:49 -0700456 if (hnd->share_fd < 0)
457 {
Chia-I Wua12e37d2017-05-08 12:46:13 -0700458 hnd->numFds--;
459 hnd->numInts++;
460 }
Vishal Bhoj78e90492015-12-07 01:36:32 +0530461#endif
462
463 *pHandle = hnd;
464
465 return 0;
466}
467
468static int gralloc_alloc_framebuffer(alloc_device_t *dev, size_t size, int usage, buffer_handle_t *pHandle)
469{
470 private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
471 pthread_mutex_lock(&m->lock);
472 int err = gralloc_alloc_framebuffer_locked(dev, size, usage, pHandle);
473 pthread_mutex_unlock(&m->lock);
474 return err;
475}
John Stultzf3d868d2017-12-05 16:15:11 -0800476#endif /* DISABLE_FRAMEBUFFER_HAL */
Vishal Bhoj78e90492015-12-07 01:36:32 +0530477
478static int alloc_device_alloc(alloc_device_t *dev, int w, int h, int format, int usage, buffer_handle_t *pHandle, int *pStride)
479{
480 if (!pHandle || !pStride)
481 {
482 return -EINVAL;
483 }
484
485 size_t size;
486 size_t stride;
John Stultz30941512018-01-04 14:03:55 -0800487 int bpp = 1;
Vishal Bhoj78e90492015-12-07 01:36:32 +0530488
489 if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP || format == HAL_PIXEL_FORMAT_YV12
490 /* HAL_PIXEL_FORMAT_YCbCr_420_SP, HAL_PIXEL_FORMAT_YCbCr_420_P, HAL_PIXEL_FORMAT_YCbCr_422_I are not defined in Android.
491 * To enable Mali DDK EGLImage support for those formats, firstly, you have to add them in Android system/core/include/system/graphics.h.
492 * Then, define SUPPORT_LEGACY_FORMAT in the same header file(Mali DDK will also check this definition).
493 */
494#ifdef SUPPORT_LEGACY_FORMAT
495 || format == HAL_PIXEL_FORMAT_YCbCr_420_SP || format == HAL_PIXEL_FORMAT_YCbCr_420_P || format == HAL_PIXEL_FORMAT_YCbCr_422_I
496#endif
497 )
498 {
499 switch (format)
500 {
501 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
502 stride = GRALLOC_ALIGN(w, 16);
503 size = GRALLOC_ALIGN(h, 16) * (stride + GRALLOC_ALIGN(stride / 2, 16));
504 break;
505
506 case HAL_PIXEL_FORMAT_YV12:
507#ifdef SUPPORT_LEGACY_FORMAT
508 case HAL_PIXEL_FORMAT_YCbCr_420_P:
509#endif
John Stultze5c5bb32018-03-20 18:16:49 -0700510 /*
511 * Since Utgard has limitation that "64-byte alignment is enforced on texture and mipmap addresses", here to make sure
512 * the v, u plane start addresses are 64-byte aligned.
513 */
514 stride = GRALLOC_ALIGN(w, (h % 8 == 0) ? GRALLOC_ALIGN_BASE_16 :
515 ((h % 4 == 0) ? GRALLOC_ALIGN_BASE_64 : GRALLOC_ALIGN_BASE_128));
Vishal Bhoj78e90492015-12-07 01:36:32 +0530516 size = GRALLOC_ALIGN(h, 2) * (stride + GRALLOC_ALIGN(stride / 2, 16));
517
518 break;
519#ifdef SUPPORT_LEGACY_FORMAT
520
521 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
522 stride = GRALLOC_ALIGN(w, 16);
523 size = GRALLOC_ALIGN(h, 16) * (stride + GRALLOC_ALIGN(stride / 2, 16));
524 break;
525
526 case HAL_PIXEL_FORMAT_YCbCr_422_I:
527 stride = GRALLOC_ALIGN(w, 16);
528 size = h * stride * 2;
529
530 break;
531#endif
532
533 default:
534 return -EINVAL;
535 }
536 }
537 else
538 {
Vishal Bhoj78e90492015-12-07 01:36:32 +0530539
540 switch (format)
541 {
542 case HAL_PIXEL_FORMAT_RGBA_8888:
543 case HAL_PIXEL_FORMAT_RGBX_8888:
544 case HAL_PIXEL_FORMAT_BGRA_8888:
545 bpp = 4;
546 break;
547
548 case HAL_PIXEL_FORMAT_RGB_888:
549 bpp = 3;
550 break;
551
552 case HAL_PIXEL_FORMAT_RGB_565:
553#if PLATFORM_SDK_VERSION < 19
554 case HAL_PIXEL_FORMAT_RGBA_5551:
555 case HAL_PIXEL_FORMAT_RGBA_4444:
556#endif
557 bpp = 2;
558 break;
559
Yongqin Liu6e403d02017-12-06 01:09:43 +0800560 case HAL_PIXEL_FORMAT_BLOB:
561 if (h != 1) {
562 AERR("Height for HAL_PIXEL_FORMAT_BLOB must be 1. h=%d", h);
563 return -EINVAL;
564 }
565 break;
566
Vishal Bhoj78e90492015-12-07 01:36:32 +0530567 default:
Yongqin Liu6e403d02017-12-06 01:09:43 +0800568 AERR("The format is not supported yet: format=%d\n", format);
Vishal Bhoj78e90492015-12-07 01:36:32 +0530569 return -EINVAL;
570 }
571
Yongqin Liu6e403d02017-12-06 01:09:43 +0800572 if (format == HAL_PIXEL_FORMAT_BLOB) {
573 stride = 0; /* No 'rows', it's effectively a long one dimensional array */
574 size = w;
575 }else{
576 size_t bpr = GRALLOC_ALIGN(w * bpp, 64);
577 size = bpr * h;
578 stride = bpr / bpp;
579 }
Vishal Bhoj78e90492015-12-07 01:36:32 +0530580 }
581
582 int err;
583
John Stultzf3d868d2017-12-05 16:15:11 -0800584#ifndef DISABLE_FRAMEBUFFER_HAL
Vishal Bhoj78e90492015-12-07 01:36:32 +0530585
586 if (usage & GRALLOC_USAGE_HW_FB)
587 {
588 err = gralloc_alloc_framebuffer(dev, size, usage, pHandle);
589 }
590 else
591#endif
592
593 {
594 err = gralloc_alloc_buffer(dev, size, usage, pHandle);
595 }
596
597 if (err < 0)
598 {
599 return err;
600 }
601
602 /* match the framebuffer format */
603 if (usage & GRALLOC_USAGE_HW_FB)
604 {
605#ifdef GRALLOC_16_BITS
606 format = HAL_PIXEL_FORMAT_RGB_565;
607#else
608 format = HAL_PIXEL_FORMAT_BGRA_8888;
609#endif
610 }
611
612 private_handle_t *hnd = (private_handle_t *)*pHandle;
613 int private_usage = usage & (GRALLOC_USAGE_PRIVATE_0 |
614 GRALLOC_USAGE_PRIVATE_1);
615
616 switch (private_usage)
617 {
618 case 0:
619 hnd->yuv_info = MALI_YUV_BT601_NARROW;
620 break;
621
622 case GRALLOC_USAGE_PRIVATE_1:
623 hnd->yuv_info = MALI_YUV_BT601_WIDE;
624 break;
625
626 case GRALLOC_USAGE_PRIVATE_0:
627 hnd->yuv_info = MALI_YUV_BT709_NARROW;
628 break;
629
630 case (GRALLOC_USAGE_PRIVATE_0 | GRALLOC_USAGE_PRIVATE_1):
631 hnd->yuv_info = MALI_YUV_BT709_WIDE;
632 break;
633 }
634
635 hnd->width = w;
636 hnd->height = h;
637 hnd->format = format;
638 hnd->stride = stride;
John Stultz30941512018-01-04 14:03:55 -0800639 hnd->byte_stride = GRALLOC_ALIGN(w*bpp,64);
Vishal Bhoj78e90492015-12-07 01:36:32 +0530640 *pStride = stride;
641 return 0;
642}
643
John Stultz21ad5be2018-03-20 20:35:07 -0700644static int alloc_device_free(alloc_device_t __unused *dev, buffer_handle_t handle)
Vishal Bhoj78e90492015-12-07 01:36:32 +0530645{
646 if (private_handle_t::validate(handle) < 0)
647 {
648 return -EINVAL;
649 }
650
651 private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(handle);
652
653 if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
654 {
Vishal Bhoj78e90492015-12-07 01:36:32 +0530655#if GRALLOC_ARM_UMP_MODULE
656
657 if ((int)UMP_INVALID_MEMORY_HANDLE != hnd->ump_mem_handle)
658 {
659 ump_reference_release((ump_handle)hnd->ump_mem_handle);
660 }
661
662#endif
663 }
664 else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP)
665 {
666#if GRALLOC_ARM_UMP_MODULE
667
668 /* Buffer might be unregistered so we need to check for invalid ump handle*/
669 if ((int)UMP_INVALID_MEMORY_HANDLE != hnd->ump_mem_handle)
670 {
671 ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle);
672 ump_reference_release((ump_handle)hnd->ump_mem_handle);
673 }
674
675#else
John Stultze5c5bb32018-03-20 18:16:49 -0700676 AERR("Can't free ump memory for handle:%p. Not supported.", hnd);
Vishal Bhoj78e90492015-12-07 01:36:32 +0530677#endif
678 }
679 else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
680 {
681#if GRALLOC_ARM_DMA_BUF_MODULE
Vishal Bhoj78e90492015-12-07 01:36:32 +0530682 /* Buffer might be unregistered so we need to check for invalid ump handle*/
683 if (0 != hnd->base)
684 {
685 if (0 != munmap((void *)hnd->base, hnd->size))
686 {
John Stultze5c5bb32018-03-20 18:16:49 -0700687 AERR("Failed to munmap handle %p", hnd);
Vishal Bhoj78e90492015-12-07 01:36:32 +0530688 }
689 }
690
691 close(hnd->share_fd);
692
Vishal Bhoj78e90492015-12-07 01:36:32 +0530693 memset((void *)hnd, 0, sizeof(*hnd));
694#else
695 AERR("Can't free dma_buf memory for handle:0x%x. Not supported.", (unsigned int)hnd);
696#endif
697
698 }
699
700 delete hnd;
701
702 return 0;
703}
704
705static int alloc_device_close(struct hw_device_t *device)
706{
707 alloc_device_t *dev = reinterpret_cast<alloc_device_t *>(device);
708
709 if (dev)
710 {
711#if GRALLOC_ARM_DMA_BUF_MODULE
712 private_module_t *m = reinterpret_cast<private_module_t *>(device);
713
714 if (0 != ion_close(m->ion_client))
715 {
716 AERR("Failed to close ion_client: %d", m->ion_client);
717 }
718
719 close(m->ion_client);
720#endif
721 delete dev;
722#if GRALLOC_ARM_UMP_MODULE
723 ump_close(); // Our UMP memory refs will be released automatically here...
724#endif
725 }
726
727 return 0;
728}
729
Laura Abbott311955b2017-06-30 11:39:35 +0530730#if GRALLOC_ARM_DMA_BUF_MODULE
John Stultzc3571ac2020-04-23 00:07:31 +0000731static int find_heap_id(int ion_client, char* name)
Laura Abbott311955b2017-06-30 11:39:35 +0530732{
John Stultzf3d868d2017-12-05 16:15:11 -0800733 int i, ret, cnt, heap_id = -1;
Laura Abbott311955b2017-06-30 11:39:35 +0530734 struct ion_heap_data *data;
735
736 ret = ion_query_heap_cnt(ion_client, &cnt);
737
738 if (ret)
739 {
740 AERR("ion count query failed with %s", strerror(errno));
741 return -1;
742 }
743
744 data = (struct ion_heap_data *)malloc(cnt * sizeof(*data));
745 if (!data)
746 {
747 AERR("Error allocating data %s\n", strerror(errno));
748 return -1;
749 }
750
751 ret = ion_query_get_heaps(ion_client, cnt, data);
752 if (ret)
753 {
754 AERR("Error querying heaps from ion %s", strerror(errno));
755 }
756 else
757 {
758 for (i = 0; i < cnt; i++) {
759 struct ion_heap_data *dat = (struct ion_heap_data *)data;
John Stultzf3d868d2017-12-05 16:15:11 -0800760 if (strcmp(dat[i].name, name) == 0) {
761 heap_id = dat[i].heap_id;
Laura Abbott311955b2017-06-30 11:39:35 +0530762 break;
763 }
764 }
765
766 if (i > cnt)
767 {
768 AERR("No System Heap Found amongst %d heaps\n", cnt);
John Stultzf3d868d2017-12-05 16:15:11 -0800769 heap_id = -1;
Laura Abbott311955b2017-06-30 11:39:35 +0530770 }
771 }
772
773 free(data);
John Stultzf3d868d2017-12-05 16:15:11 -0800774 return heap_id;
Laura Abbott311955b2017-06-30 11:39:35 +0530775}
776#endif
777
John Stultzc3571ac2020-04-23 00:07:31 +0000778static int initialize_interface(private_module_t *m)
779{
780 int fd;
781
782 if (interface_ver != INTERFACE_UNKNOWN)
783 return 0;
784
785 /* test for dma-heaps*/
786 fd = dma_heap_open(DMABUF_SYSTEM);
787 if (fd >= 0) {
788 AINF("Using DMA-BUF Heaps.\n");
789 interface_ver = INTERFACE_DMABUF_HEAPS;
790 system_heap_id = fd;
791 cma_heap_id = dma_heap_open(DMABUF_CMA);
792 /* Open other dma heaps here */
793 return 0;
794 }
795
796 /* test for modern vs legacy ION */
797 m->ion_client = ion_open();
798 if (m->ion_client < 0) {
799 AERR("ion_open failed with %s", strerror(errno));
800 return -1;
801 }
802 if (!ion_is_legacy(m->ion_client)) {
803 system_heap_id = find_heap_id(m->ion_client, ION_SYSTEM);
804 cma_heap_id = find_heap_id(m->ion_client, ION_CMA);
805 if (system_heap_id < 0) {
806 ion_close(m->ion_client);
807 m->ion_client = -1;
808 AERR( "ion_open failed: no system heap found" );
809 return -1;
810 }
811 if (cma_heap_id < 0) {
812 AERR("No cma heap found, falling back to system");
813 cma_heap_id = system_heap_id;
814 }
815 AINF("Using ION Modern interface.\n");
816 interface_ver = INTERFACE_ION_MODERN;
817 } else {
818 AINF("Using ION Legacy interface.\n");
819 interface_ver = INTERFACE_ION_LEGACY;
820 }
821 return 0;
822}
823
Vishal Bhoj78e90492015-12-07 01:36:32 +0530824int alloc_device_open(hw_module_t const *module, const char *name, hw_device_t **device)
825{
826 MALI_IGNORE(name);
827 alloc_device_t *dev;
828
829 dev = new alloc_device_t;
830
831 if (NULL == dev)
832 {
833 return -1;
834 }
835
836#if GRALLOC_ARM_UMP_MODULE
837 ump_result ump_res = ump_open();
838
839 if (UMP_OK != ump_res)
840 {
841 AERR("UMP open failed with %d", ump_res);
842 delete dev;
843 return -1;
844 }
845
846#endif
847
848 /* initialize our state here */
849 memset(dev, 0, sizeof(*dev));
850
851 /* initialize the procs */
852 dev->common.tag = HARDWARE_DEVICE_TAG;
853 dev->common.version = 0;
854 dev->common.module = const_cast<hw_module_t *>(module);
855 dev->common.close = alloc_device_close;
856 dev->alloc = alloc_device_alloc;
857 dev->free = alloc_device_free;
858
859#if GRALLOC_ARM_DMA_BUF_MODULE
860 private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
Vishal Bhoj78e90492015-12-07 01:36:32 +0530861
John Stultzc3571ac2020-04-23 00:07:31 +0000862 if (initialize_interface(m) < 0) {
Vishal Bhoj78e90492015-12-07 01:36:32 +0530863 delete dev;
864 return -1;
865 }
Vishal Bhoj78e90492015-12-07 01:36:32 +0530866#endif
867
868 *device = &dev->common;
869
870 return 0;
871}