Import ion handles when registering buffers
[GitHub/LineageOS/android_hardware_samsung_slsi_exynos5.git] / gralloc / gralloc.cpp
CommitLineData
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#ifdef HAVE_ANDROID_OS // just want PAGE_SIZE define
18# include <asm/page.h>
19#else
20# include <sys/user.h>
21#endif
22#include <limits.h>
23#include <unistd.h>
24#include <fcntl.h>
25#include <errno.h>
26#include <pthread.h>
27#include <stdlib.h>
28#include <string.h>
29
30#include <sys/mman.h>
31#include <sys/stat.h>
32#include <sys/types.h>
33#include <sys/ioctl.h>
34
35#include <ion/ion.h>
36#include <linux/ion.h>
37#include <cutils/log.h>
38#include <cutils/atomic.h>
39
40#include <hardware/hardware.h>
41#include <hardware/gralloc.h>
42
43#include "gralloc_priv.h"
44#include "exynos_format.h"
45#include "gr.h"
46
47/*****************************************************************************/
48
49struct gralloc_context_t {
50 alloc_device_t device;
51 /* our private data here */
52};
53
54static int gralloc_alloc_buffer(alloc_device_t* dev,
55 size_t size, int usage, buffer_handle_t* pHandle);
56
57/*****************************************************************************/
58
59int fb_device_open(const hw_module_t* module, const char* name,
60 hw_device_t** device);
61
62static int gralloc_device_open(const hw_module_t* module, const char* name,
63 hw_device_t** device);
64
65extern int gralloc_lock(gralloc_module_t const* module,
66 buffer_handle_t handle, int usage,
67 int l, int t, int w, int h,
68 void** vaddr);
69
70extern int gralloc_unlock(gralloc_module_t const* module,
71 buffer_handle_t handle);
72
73extern int gralloc_register_buffer(gralloc_module_t const* module,
74 buffer_handle_t handle);
75
76extern int gralloc_unregister_buffer(gralloc_module_t const* module,
77 buffer_handle_t handle);
78
79/*****************************************************************************/
80
81static struct hw_module_methods_t gralloc_module_methods = {
82open: gralloc_device_open
83};
84
85struct private_module_t HAL_MODULE_INFO_SYM = {
86base: {
87common: {
88tag: HARDWARE_MODULE_TAG,
89 version_major: 1,
90 version_minor: 0,
91 id: GRALLOC_HARDWARE_MODULE_ID,
92 name: "Graphics Memory Allocator Module",
93 author: "The Android Open Source Project",
94 methods: &gralloc_module_methods
95 },
ec68ab21
RSZ
96 registerBuffer: gralloc_register_buffer,
97 unregisterBuffer: gralloc_unregister_buffer,
98 lock: gralloc_lock,
99 unlock: gralloc_unlock,
2480eccc 100 },
ec68ab21
RSZ
101 framebuffer: 0,
102 flags: 0,
103 numBuffers: 0,
104 bufferMask: 0,
105 lock: PTHREAD_MUTEX_INITIALIZER,
106 currentBuffer: 0,
107 ionfd: -1,
2480eccc
RSZ
108};
109
110/*****************************************************************************/
111
112#define ALIGN(x, a) (((x) + (a - 1)) & ~(a - 1))
113
da3d8712
RSZ
114static int gralloc_alloc_rgb(int ionfd, int w, int h, int format, int usage,
115 unsigned int ion_flags, private_handle_t **hnd, int *stride)
2480eccc
RSZ
116{
117 size_t size, bpr;
70212e56 118 int bpp = 0, vstride, fd, err;
2480eccc
RSZ
119 switch (format) {
120 case HAL_PIXEL_FORMAT_RGBA_8888:
121 case HAL_PIXEL_FORMAT_RGBX_8888:
122 case HAL_PIXEL_FORMAT_BGRA_8888:
123 bpp = 4;
124 break;
125 case HAL_PIXEL_FORMAT_RGB_888:
126 bpp = 3;
127 break;
128 case HAL_PIXEL_FORMAT_RGB_565:
129 case HAL_PIXEL_FORMAT_RGBA_5551:
130 case HAL_PIXEL_FORMAT_RGBA_4444:
131 case HAL_PIXEL_FORMAT_RAW_SENSOR:
132 bpp = 2;
133 break;
134 case HAL_PIXEL_FORMAT_BLOB:
135 bpp = 1;
136 break;
137 default:
138 return -EINVAL;
139 }
140 bpr = ALIGN(w*bpp, 16);
70212e56
RSZ
141 vstride = ALIGN(h, 16);
142 size = bpr * vstride;
2480eccc
RSZ
143 *stride = bpr / bpp;
144 size = ALIGN(size, PAGE_SIZE);
145
da3d8712
RSZ
146 err = ion_alloc_fd(ionfd, size, 0, 1 << ION_HEAP_TYPE_SYSTEM, ion_flags,
147 &fd);
148 *hnd = new private_handle_t(fd, size, usage, w, h, format, *stride,
149 vstride);
2480eccc
RSZ
150
151 return err;
152}
153
da3d8712
RSZ
154static int gralloc_alloc_yuv(int ionfd, int w, int h, int format, int usage,
155 unsigned int ion_flags, private_handle_t **hnd, int *stride)
2480eccc
RSZ
156{
157 size_t luma_size, chroma_size;
158 int err, planes, fd, fd1, fd2 = 0;
70212e56 159 size_t luma_vstride;
2480eccc
RSZ
160 *stride = ALIGN(w, 16);
161
162 switch (format) {
163 ALOGE("invalid yuv format %d\n", format);
c853be7b 164 case HAL_PIXEL_FORMAT_EXYNOS_YV12:
2480eccc 165 {
70212e56
RSZ
166 luma_vstride = ALIGN(h, 16);
167 luma_size = luma_vstride * *stride;
168 chroma_size = (luma_vstride / 2) * ALIGN(*stride / 2, 16);
2480eccc
RSZ
169 planes = 3;
170 break;
171 }
c853be7b 172 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP:
2480eccc
RSZ
173 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
174 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
175 {
2480eccc 176 size_t chroma_vstride = ALIGN(h / 2, 32);
70212e56 177 luma_vstride = ALIGN(h, 32);
2480eccc
RSZ
178 luma_size = luma_vstride * *stride;
179 chroma_size = chroma_vstride * *stride;
180 planes = 2;
181 break;
182 }
183 default:
184 ALOGE("invalid yuv format %d\n", format);
185 return -EINVAL;
186 }
187
da3d8712
RSZ
188 err = ion_alloc_fd(ionfd, luma_size, 0, 1 << ION_HEAP_TYPE_SYSTEM,
189 ion_flags, &fd);
2480eccc
RSZ
190 if (err)
191 return err;
da3d8712
RSZ
192 err = ion_alloc_fd(ionfd, chroma_size, 0, 1 << ION_HEAP_TYPE_SYSTEM,
193 ion_flags,
2480eccc
RSZ
194 &fd1);
195 if (err)
196 goto err1;
197 if (planes == 3) {
198 err = ion_alloc_fd(ionfd, chroma_size, 0, 1 << ION_HEAP_TYPE_SYSTEM,
da3d8712 199 ion_flags, &fd2);
2480eccc
RSZ
200 if (err)
201 goto err2;
2480eccc 202
ec68ab21
RSZ
203 *hnd = new private_handle_t(fd, fd1, fd2, luma_size, usage, w, h,
204 format, *stride, luma_vstride);
205 } else {
206 *hnd = new private_handle_t(fd, fd1, luma_size, usage, w, h, format,
207 *stride, luma_vstride);
208 }
2480eccc
RSZ
209 return err;
210
211err2:
212 close(fd1);
213err1:
214 close(fd);
215 return err;
216}
217
218static int gralloc_alloc(alloc_device_t* dev,
219 int w, int h, int format, int usage,
220 buffer_handle_t* pHandle, int* pStride)
221{
222 int stride;
223 int err;
da3d8712 224 unsigned int ion_flags = 0;
2480eccc
RSZ
225 private_handle_t *hnd;
226
227 if (!pHandle || !pStride)
228 return -EINVAL;
229
230 if( (usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN )
da3d8712 231 ion_flags = ION_FLAG_CACHED;
2480eccc
RSZ
232
233 private_module_t* m = reinterpret_cast<private_module_t*>
234 (dev->common.module);
235 gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>
236 (dev->common.module);
237
da3d8712
RSZ
238 err = gralloc_alloc_rgb(m->ionfd, w, h, format, usage, ion_flags, &hnd,
239 &stride);
2480eccc 240 if (err)
da3d8712
RSZ
241 err = gralloc_alloc_yuv(m->ionfd, w, h, format, usage, ion_flags,
242 &hnd, &stride);
2480eccc
RSZ
243 if (err)
244 return err;
245
246 err = grallocMap(module, hnd);
247
248 if (err != 0)
249 goto err;
250
251 *pHandle = hnd;
252 *pStride = stride;
253 return 0;
254err:
255 close(hnd->fd);
ec68ab21 256 if (hnd->fd1 >= 0)
2480eccc 257 close(hnd->fd1);
ec68ab21 258 if (hnd->fd2 >= 0)
2480eccc
RSZ
259 close(hnd->fd2);
260 return err;
261}
262
263static int gralloc_free(alloc_device_t* dev,
264 buffer_handle_t handle)
265{
266 if (private_handle_t::validate(handle) < 0)
267 return -EINVAL;
268
269 private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle);
270 gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>(
271 dev->common.module);
272
273 grallocUnmap(module, const_cast<private_handle_t*>(hnd));
274 close(hnd->fd);
ec68ab21 275 if (hnd->fd1 >= 0)
2480eccc 276 close(hnd->fd1);
ec68ab21 277 if (hnd->fd2 >= 0)
2480eccc
RSZ
278 close(hnd->fd2);
279
280 delete hnd;
281 return 0;
282}
283
284/*****************************************************************************/
285
286static int gralloc_close(struct hw_device_t *dev)
287{
288 gralloc_context_t* ctx = reinterpret_cast<gralloc_context_t*>(dev);
289 if (ctx) {
290 /* TODO: keep a list of all buffer_handle_t created, and free them
291 * all here.
292 */
293 free(ctx);
294 }
295 return 0;
296}
297
298int gralloc_device_open(const hw_module_t* module, const char* name,
299 hw_device_t** device)
300{
301 int status = -EINVAL;
302 if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
303 gralloc_context_t *dev;
304 dev = (gralloc_context_t*)malloc(sizeof(*dev));
305
306 /* initialize our state here */
307 memset(dev, 0, sizeof(*dev));
308
309 /* initialize the procs */
310 dev->device.common.tag = HARDWARE_DEVICE_TAG;
311 dev->device.common.version = 0;
312 dev->device.common.module = const_cast<hw_module_t*>(module);
313 dev->device.common.close = gralloc_close;
314
315 dev->device.alloc = gralloc_alloc;
316 dev->device.free = gralloc_free;
317
318 private_module_t *p = reinterpret_cast<private_module_t*>(dev->device.common.module);
319 p->ionfd = ion_open();
320
321 *device = &dev->device.common;
322 status = 0;
323 } else {
324 status = fb_device_open(module, name, device);
325 }
326 return status;
327}