1 /*
2 * Copyright (C) 2016, 2018-2019 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 #if GRALLOC_VERSION_MAJOR == 1
20 #include <hardware/gralloc1.h>
21 #elif GRALLOC_VERSION_MAJOR == 0
22 #include <hardware/gralloc.h>
23 #endif
24
25 #include "mali_gralloc_module.h"
26 #include "mali_gralloc_private_interface_types.h"
27 #include "mali_gralloc_buffer.h"
28 #include "mali_gralloc_ion.h"
29 #include "gralloc_buffer_priv.h"
30 #include "mali_gralloc_bufferallocation.h"
31 #include "mali_gralloc_debug.h"
32
33 static pthread_mutex_t s_map_lock = PTHREAD_MUTEX_INITIALIZER;
34
mali_gralloc_reference_retain(mali_gralloc_module const * module,buffer_handle_t handle)35 int mali_gralloc_reference_retain(mali_gralloc_module const *module, buffer_handle_t handle)
36 {
37 GRALLOC_UNUSED(module);
38
39 if (private_handle_t::validate(handle) < 0)
40 {
41 AERR("Registering/Retaining invalid buffer %p, returning error", handle);
42 return -EINVAL;
43 }
44
45 private_handle_t *hnd = (private_handle_t *)handle;
46 pthread_mutex_lock(&s_map_lock);
47
48 if (hnd->allocating_pid == getpid() || hnd->remote_pid == getpid())
49 {
50 hnd->ref_count++;
51 pthread_mutex_unlock(&s_map_lock);
52 return 0;
53 }
54 else
55 {
56 hnd->remote_pid = getpid();
57 hnd->ref_count = 1;
58 }
59
60 int retval = -EINVAL;
61
62 if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
63 {
64 retval = 0;
65 }
66 else if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_ION))
67 {
68 retval = mali_gralloc_ion_map(hnd);
69 #if GRALLOC_ION_HANDLE_IMPORT == 1
70 if (retval >= 0)
71 {
72 /* failing to import ion handle is not fatal */
73 import_exynos_ion_handles(hnd);
74 retval = 0;
75 }
76 #endif
77 }
78 else
79 {
80 AERR("Unknown buffer flags not supported. flags = %d", hnd->flags);
81 }
82
83 pthread_mutex_unlock(&s_map_lock);
84 return retval;
85 }
86
mali_gralloc_reference_release(mali_gralloc_module const * module,buffer_handle_t handle,bool canFree)87 int mali_gralloc_reference_release(mali_gralloc_module const *module, buffer_handle_t handle, bool canFree)
88 {
89 GRALLOC_UNUSED(module);
90
91 if (private_handle_t::validate(handle) < 0)
92 {
93 AERR("unregistering/releasing invalid buffer %p, returning error", handle);
94 return -EINVAL;
95 }
96
97 private_handle_t *hnd = (private_handle_t *)handle;
98 pthread_mutex_lock(&s_map_lock);
99
100 if (hnd->ref_count == 0)
101 {
102 AERR("Buffer %p should have already been released", handle);
103 pthread_mutex_unlock(&s_map_lock);
104 return -EINVAL;
105 }
106
107 if (hnd->allocating_pid == getpid())
108 {
109 hnd->ref_count--;
110
111 if (hnd->ref_count == 0 && canFree)
112 {
113 if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
114 {
115 close(hnd->fb_fd);
116 }
117 else
118 {
119 mali_gralloc_dump_buffer_erase(hnd);
120 }
121
122 #if GRALLOC_ION_HANDLE_IMPORT == 1
123 free_exynos_ion_handles(hnd);
124 #endif
125 mali_gralloc_buffer_free(handle);
126 delete handle;
127 }
128 }
129 else if (hnd->remote_pid == getpid()) // never unmap buffers that were not imported into this process
130 {
131 hnd->ref_count--;
132
133 if (hnd->ref_count == 0)
134 {
135
136 if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_ION))
137 {
138 mali_gralloc_ion_unmap(hnd);
139 #if GRALLOC_ION_HANDLE_IMPORT == 1
140 free_exynos_ion_handles(hnd);
141 #endif
142 }
143 else
144 {
145 AERR("Unregistering/Releasing unknown buffer is not supported. Flags = %d", hnd->flags);
146 }
147
148 #if GRALLOC_USE_ASHMEM_METADATA != 1
149 /*
150 * Close shared attribute region file descriptor. It might seem strange to "free"
151 * this here since this can happen in a client process, but free here is nothing
152 * but unmapping and closing the duplicated file descriptor. The original ashmem
153 * fd instance is still open until alloc_device_free() is called. Even sharing
154 * of gralloc buffers within the same process should have fds dup:ed.
155 */
156 gralloc_buffer_attr_free(hnd);
157 #endif
158
159 hnd->base = 0;
160 }
161 }
162 else
163 {
164 AERR("Trying to unregister buffer %p from process %d that was not imported into current process: %d", hnd,
165 hnd->remote_pid, getpid());
166 }
167
168 pthread_mutex_unlock(&s_map_lock);
169 return 0;
170 }
171