summaryrefslogtreecommitdiff
path: root/gralloc_module_ion.cpp (plain)
blob: 9950ea294c95fa5a6b60e99cc1a250d41d8fee09
1/*
2 * Copyright (C) 2013 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
19#include <errno.h>
20#include <pthread.h>
21
22#include <cutils/log.h>
23#include <cutils/atomic.h>
24#include <hardware/hardware.h>
25#include <hardware/gralloc.h>
26
27#include "gralloc_priv.h"
28#include "alloc_device.h"
29#include "framebuffer_device.h"
30
31#include <linux/ion.h>
32#include <ion/ion.h>
33#include <sys/mman.h>
34
35int gralloc_backend_register(private_handle_t* hnd)
36{
37 int retval = -EINVAL;
38
39 switch (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_UMP |
40 private_handle_t::PRIV_FLAGS_USES_ION))
41 {
42 case private_handle_t::PRIV_FLAGS_USES_UMP:
43 AERR("Gralloc does not support UMP. Unable to register UMP memory for handle %p", hnd );
44 break;
45 case private_handle_t::PRIV_FLAGS_USES_ION:
46 unsigned char *mappedAddress;
47 size_t size = hnd->size;
48 hw_module_t * pmodule = NULL;
49 private_module_t *m=NULL;
50 if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&pmodule) == 0)
51 {
52 m = reinterpret_cast<private_module_t *>(pmodule);
53 }
54 else
55 {
56 AERR("Could not get gralloc module for handle: %p", hnd);
57 retval = -errno;
58 break;
59 }
60 /* the test condition is set to m->ion_client <= 0 here, because:
61 * 1) module structure are initialized to 0 if no initial value is applied
62 * 2) a second user process should get a ion fd greater than 0.
63 */
64 if (m->ion_client <= 0)
65 {
66 /* a second user process must obtain a client handle first via ion_open before it can obtain the shared ion buffer*/
67 m->ion_client = ion_open();
68
69 if (m->ion_client < 0)
70 {
71 AERR( "Could not open ion device for handle: %p", hnd );
72 retval = -errno;
73 break;
74 }
75 }
76
77 mappedAddress = (unsigned char*)mmap( NULL, size, PROT_READ | PROT_WRITE,
78 MAP_SHARED, hnd->share_fd, 0 );
79
80 if ( MAP_FAILED == mappedAddress )
81 {
82 AERR( "mmap( share_fd:%d ) failed with %s", hnd->share_fd, strerror( errno ) );
83 retval = -errno;
84 break;
85 }
86
87 hnd->base = (void*)(uintptr_t(mappedAddress) + hnd->offset);
88 retval = 0;
89 break;
90 }
91
92 return retval;
93}
94
95void gralloc_backend_unregister(private_handle_t* hnd)
96{
97 switch (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_UMP |
98 private_handle_t::PRIV_FLAGS_USES_ION))
99 {
100 case private_handle_t::PRIV_FLAGS_USES_UMP:
101 AERR( "Can't unregister UMP buffer for handle %p. Not supported", hnd );
102 break;
103 case private_handle_t::PRIV_FLAGS_USES_ION:
104 void* base = (void*)hnd->base;
105 size_t size = hnd->size;
106
107 if ( munmap( base,size ) < 0 )
108 {
109 AERR("Could not munmap base:%p size:%zd '%s'", base, size, strerror(errno));
110 }
111 break;
112 }
113}
114
115void gralloc_backend_sync(private_handle_t* hnd)
116{
117 switch (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_UMP |
118 private_handle_t::PRIV_FLAGS_USES_ION))
119 {
120 case private_handle_t::PRIV_FLAGS_USES_UMP:
121 AERR( "Buffer %p is UMP type but it is not supported", hnd );
122 break;
123 case private_handle_t::PRIV_FLAGS_USES_ION:
124 hw_module_t * pmodule = NULL;
125 private_module_t *m=NULL;
126 if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&pmodule) == 0)
127 {
128 if(!(hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION_DMA_HEAP))
129 {
130 m = reinterpret_cast<private_module_t *>(pmodule);
131 ion_sync_fd(m->ion_client, hnd->share_fd);
132 }
133 }
134 else
135 {
136 AERR("Could not get gralloc module for handle %p\n", hnd);
137 }
138 break;
139 }
140}
141