Commit | Line | Data |
---|---|---|
2480eccc RSZ |
1 | /* |
2 | * Copyright (C) 2008 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 <cutils/log.h> | |
28 | #include <cutils/atomic.h> | |
29 | ||
30 | #include <hardware/hardware.h> | |
31 | #include <hardware/gralloc.h> | |
32 | ||
33 | #include "gralloc_priv.h" | |
34 | ||
35 | #include <ion/ion.h> | |
36 | #include <linux/ion.h> | |
37 | ||
38 | /*****************************************************************************/ | |
39 | ||
40 | static int gralloc_map(gralloc_module_t const* module, buffer_handle_t handle) | |
41 | { | |
42 | private_handle_t* hnd = (private_handle_t*)handle; | |
43 | ||
44 | void* mappedAddress = mmap(0, hnd->size, PROT_READ|PROT_WRITE, MAP_SHARED, | |
45 | hnd->fd, 0); | |
46 | if (mappedAddress == MAP_FAILED) { | |
47 | ALOGE("%s: could not mmap %s", __func__, strerror(errno)); | |
48 | return -errno; | |
49 | } | |
50 | ALOGV("%s: base %p %d %d %d %d\n", __func__, mappedAddress, hnd->size, | |
51 | hnd->width, hnd->height, hnd->stride); | |
52 | hnd->base = mappedAddress; | |
53 | return 0; | |
54 | } | |
55 | ||
56 | static int gralloc_unmap(gralloc_module_t const* module, buffer_handle_t handle) | |
57 | { | |
58 | private_handle_t* hnd = (private_handle_t*)handle; | |
59 | ||
3ece9dfd LM |
60 | if (!hnd->base) |
61 | return 0; | |
62 | ||
63 | if (munmap(hnd->base, hnd->size) < 0) { | |
2480eccc RSZ |
64 | ALOGE("%s :could not unmap %s %p %d", __func__, strerror(errno), |
65 | hnd->base, hnd->size); | |
66 | } | |
67 | ALOGV("%s: base %p %d %d %d %d\n", __func__, hnd->base, hnd->size, | |
68 | hnd->width, hnd->height, hnd->stride); | |
3ece9dfd | 69 | hnd->base = 0; |
2480eccc RSZ |
70 | return 0; |
71 | } | |
72 | ||
73 | /*****************************************************************************/ | |
74 | ||
ec68ab21 RSZ |
75 | int getIonFd(gralloc_module_t const *module) |
76 | { | |
77 | private_module_t* m = const_cast<private_module_t*>(reinterpret_cast<const private_module_t*>(module)); | |
78 | if (m->ionfd == -1) | |
79 | m->ionfd = ion_open(); | |
80 | return m->ionfd; | |
81 | } | |
82 | ||
2480eccc RSZ |
83 | static pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER; |
84 | ||
85 | /*****************************************************************************/ | |
86 | ||
87 | int gralloc_register_buffer(gralloc_module_t const* module, | |
88 | buffer_handle_t handle) | |
89 | { | |
2480eccc RSZ |
90 | if (private_handle_t::validate(handle) < 0) |
91 | return -EINVAL; | |
92 | ||
2480eccc RSZ |
93 | private_handle_t* hnd = (private_handle_t*)handle; |
94 | ALOGV("%s: base %p %d %d %d %d\n", __func__, hnd->base, hnd->size, | |
95 | hnd->width, hnd->height, hnd->stride); | |
ec68ab21 RSZ |
96 | |
97 | int ret; | |
98 | ret = ion_import(getIonFd(module), hnd->fd, &hnd->handle); | |
99 | if (ret) | |
100 | ALOGE("error importing handle %d %x\n", hnd->fd, hnd->format); | |
101 | if (hnd->fd1 >= 0) { | |
102 | ret = ion_import(getIonFd(module), hnd->fd1, &hnd->handle1); | |
103 | if (ret) | |
104 | ALOGE("error importing handle1 %d %x\n", hnd->fd1, hnd->format); | |
105 | } | |
106 | if (hnd->fd2 >= 0) { | |
107 | ret = ion_import(getIonFd(module), hnd->fd2, &hnd->handle2); | |
108 | if (ret) | |
109 | ALOGE("error importing handle2 %d %x\n", hnd->fd2, hnd->format); | |
110 | } | |
111 | ||
8a4849e1 | 112 | return ret; |
2480eccc RSZ |
113 | } |
114 | ||
115 | int gralloc_unregister_buffer(gralloc_module_t const* module, | |
116 | buffer_handle_t handle) | |
117 | { | |
118 | if (private_handle_t::validate(handle) < 0) | |
119 | return -EINVAL; | |
120 | ||
121 | private_handle_t* hnd = (private_handle_t*)handle; | |
122 | ALOGV("%s: base %p %d %d %d %d\n", __func__, hnd->base, hnd->size, | |
123 | hnd->width, hnd->height, hnd->stride); | |
124 | ||
125 | gralloc_unmap(module, handle); | |
126 | ||
ec68ab21 RSZ |
127 | if (hnd->handle) |
128 | ion_free(getIonFd(module), hnd->handle); | |
129 | if (hnd->handle1) | |
130 | ion_free(getIonFd(module), hnd->handle1); | |
131 | if (hnd->handle2) | |
132 | ion_free(getIonFd(module), hnd->handle2); | |
133 | ||
2480eccc RSZ |
134 | return 0; |
135 | } | |
136 | ||
137 | int gralloc_lock(gralloc_module_t const* module, | |
138 | buffer_handle_t handle, int usage, | |
139 | int l, int t, int w, int h, | |
140 | void** vaddr) | |
141 | { | |
142 | // this is called when a buffer is being locked for software | |
143 | // access. in thin implementation we have nothing to do since | |
144 | // not synchronization with the h/w is needed. | |
145 | // typically this is used to wait for the h/w to finish with | |
146 | // this buffer if relevant. the data cache may need to be | |
147 | // flushed or invalidated depending on the usage bits and the | |
148 | // hardware. | |
149 | ||
150 | if (private_handle_t::validate(handle) < 0) | |
151 | return -EINVAL; | |
152 | ||
153 | private_handle_t* hnd = (private_handle_t*)handle; | |
5258c21c RSZ |
154 | if (!hnd->base) |
155 | gralloc_map(module, hnd); | |
2480eccc RSZ |
156 | *vaddr = (void*)hnd->base; |
157 | return 0; | |
158 | } | |
159 | ||
160 | int gralloc_unlock(gralloc_module_t const* module, | |
161 | buffer_handle_t handle) | |
162 | { | |
163 | // we're done with a software buffer. nothing to do in this | |
164 | // implementation. typically this is used to flush the data cache. | |
f8552390 RSZ |
165 | private_handle_t* hnd = (private_handle_t*)handle; |
166 | ion_sync_fd(getIonFd(module), hnd->fd); | |
167 | if (hnd->fd1 >= 0) | |
168 | ion_sync_fd(getIonFd(module), hnd->fd1); | |
169 | if (hnd->fd2 >= 0) | |
170 | ion_sync_fd(getIonFd(module), hnd->fd2); | |
2480eccc RSZ |
171 | |
172 | if (private_handle_t::validate(handle) < 0) | |
173 | return -EINVAL; | |
174 | return 0; | |
175 | } |