hardware: samsung_slsi: Add fnumber item for metadata
[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
788e20df
SK
47#define ION_HEAP_EXYNOS_CONTIG_MASK (1 << 4)
48#define ION_EXYNOS_VIDEO_MASK (1 << 29)
49
2480eccc
RSZ
50/*****************************************************************************/
51
52struct gralloc_context_t {
53 alloc_device_t device;
54 /* our private data here */
55};
56
57static int gralloc_alloc_buffer(alloc_device_t* dev,
58 size_t size, int usage, buffer_handle_t* pHandle);
59
60/*****************************************************************************/
61
62int fb_device_open(const hw_module_t* module, const char* name,
63 hw_device_t** device);
64
65static int gralloc_device_open(const hw_module_t* module, const char* name,
66 hw_device_t** device);
67
68extern int gralloc_lock(gralloc_module_t const* module,
69 buffer_handle_t handle, int usage,
70 int l, int t, int w, int h,
71 void** vaddr);
72
73extern int gralloc_unlock(gralloc_module_t const* module,
74 buffer_handle_t handle);
75
76extern int gralloc_register_buffer(gralloc_module_t const* module,
77 buffer_handle_t handle);
78
79extern int gralloc_unregister_buffer(gralloc_module_t const* module,
80 buffer_handle_t handle);
81
82/*****************************************************************************/
83
84static struct hw_module_methods_t gralloc_module_methods = {
85open: gralloc_device_open
86};
87
88struct private_module_t HAL_MODULE_INFO_SYM = {
89base: {
90common: {
91tag: HARDWARE_MODULE_TAG,
92 version_major: 1,
93 version_minor: 0,
94 id: GRALLOC_HARDWARE_MODULE_ID,
95 name: "Graphics Memory Allocator Module",
96 author: "The Android Open Source Project",
97 methods: &gralloc_module_methods
98 },
ec68ab21
RSZ
99 registerBuffer: gralloc_register_buffer,
100 unregisterBuffer: gralloc_unregister_buffer,
101 lock: gralloc_lock,
102 unlock: gralloc_unlock,
2480eccc 103 },
ec68ab21
RSZ
104 framebuffer: 0,
105 flags: 0,
106 numBuffers: 0,
107 bufferMask: 0,
108 lock: PTHREAD_MUTEX_INITIALIZER,
109 currentBuffer: 0,
110 ionfd: -1,
2480eccc
RSZ
111};
112
113/*****************************************************************************/
114
115#define ALIGN(x, a) (((x) + (a - 1)) & ~(a - 1))
116
788e20df
SK
117static unsigned int _select_heap(int usage)
118{
119 unsigned int heap_mask;
120
121 if (usage & GRALLOC_USAGE_PROTECTED)
122 heap_mask = ION_HEAP_EXYNOS_CONTIG_MASK;
123 else
124 heap_mask = ION_HEAP_SYSTEM_MASK;
125
126 return heap_mask;
127}
128
da3d8712
RSZ
129static int gralloc_alloc_rgb(int ionfd, int w, int h, int format, int usage,
130 unsigned int ion_flags, private_handle_t **hnd, int *stride)
2480eccc
RSZ
131{
132 size_t size, bpr;
70212e56 133 int bpp = 0, vstride, fd, err;
788e20df
SK
134 unsigned int heap_mask = _select_heap(usage);
135
2480eccc
RSZ
136 switch (format) {
137 case HAL_PIXEL_FORMAT_RGBA_8888:
138 case HAL_PIXEL_FORMAT_RGBX_8888:
139 case HAL_PIXEL_FORMAT_BGRA_8888:
140 bpp = 4;
141 break;
142 case HAL_PIXEL_FORMAT_RGB_888:
143 bpp = 3;
144 break;
145 case HAL_PIXEL_FORMAT_RGB_565:
146 case HAL_PIXEL_FORMAT_RGBA_5551:
147 case HAL_PIXEL_FORMAT_RGBA_4444:
148 case HAL_PIXEL_FORMAT_RAW_SENSOR:
149 bpp = 2;
150 break;
151 case HAL_PIXEL_FORMAT_BLOB:
152 bpp = 1;
153 break;
154 default:
155 return -EINVAL;
156 }
157 bpr = ALIGN(w*bpp, 16);
c41b757c
GH
158 vstride = ALIGN(h, 16);
159 if (vstride == h)
160 size = bpr * (vstride + 1);
161 else
162 size = bpr * vstride;
2480eccc
RSZ
163 *stride = bpr / bpp;
164 size = ALIGN(size, PAGE_SIZE);
165
788e20df 166 err = ion_alloc_fd(ionfd, size, 0, heap_mask, ion_flags,
da3d8712
RSZ
167 &fd);
168 *hnd = new private_handle_t(fd, size, usage, w, h, format, *stride,
169 vstride);
2480eccc
RSZ
170
171 return err;
172}
173
55a3039b
RSZ
174static int gralloc_alloc_framework_yuv(int ionfd, int w, int h, int format,
175 int usage, unsigned int ion_flags,
176 private_handle_t **hnd, int *stride)
177{
178 size_t size;
179 int err, fd;
180
181 switch (format) {
182 case HAL_PIXEL_FORMAT_YV12:
183 *stride = ALIGN(w, 16);
184 break;
185 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
186 *stride = w;
187 break;
188 default:
bcf29611
RSZ
189 ALOGE("invalid yuv format %d\n", format);
190 return -EINVAL;
55a3039b
RSZ
191 }
192
193 size = *stride * h * 3 / 2;
194 err = ion_alloc_fd(ionfd, size, 0, 1 << ION_HEAP_TYPE_SYSTEM,
195 ion_flags, &fd);
196 if (err)
197 return err;
198
199 *hnd = new private_handle_t(fd, size, usage, w, h, format, *stride, h);
200 return err;
201}
202
203static int gralloc_alloc_yuv(int ionfd, int w, int h, int format,
204 int usage, unsigned int ion_flags,
205 private_handle_t **hnd, int *stride)
2480eccc
RSZ
206{
207 size_t luma_size, chroma_size;
208 int err, planes, fd, fd1, fd2 = 0;
70212e56 209 size_t luma_vstride;
788e20df
SK
210 unsigned int heap_mask = _select_heap(usage);
211
2480eccc
RSZ
212 *stride = ALIGN(w, 16);
213
214 switch (format) {
c853be7b 215 case HAL_PIXEL_FORMAT_EXYNOS_YV12:
bcf29611
RSZ
216 {
217 luma_vstride = ALIGN(h, 16);
218 luma_size = luma_vstride * *stride;
219 chroma_size = (luma_vstride / 2) * ALIGN(*stride / 2, 16);
220 planes = 3;
221 break;
222 }
c853be7b 223 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP:
2480eccc
RSZ
224 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
225 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
bcf29611
RSZ
226 {
227 size_t chroma_vstride = ALIGN(h / 2, 32);
228 luma_vstride = ALIGN(h, 32);
229 luma_size = luma_vstride * *stride;
230 chroma_size = chroma_vstride * *stride;
231 planes = 2;
232 break;
233 }
55a3039b
RSZ
234 case HAL_PIXEL_FORMAT_YV12:
235 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
236 return gralloc_alloc_framework_yuv(ionfd, w, h, format, usage,
237 ion_flags, hnd, stride);
2480eccc 238 default:
bcf29611
RSZ
239 ALOGE("invalid yuv format %d\n", format);
240 return -EINVAL;
2480eccc
RSZ
241 }
242
788e20df 243 err = ion_alloc_fd(ionfd, luma_size, 0, heap_mask, ion_flags, &fd);
2480eccc
RSZ
244 if (err)
245 return err;
788e20df 246 err = ion_alloc_fd(ionfd, chroma_size, 0, heap_mask, ion_flags, &fd1);
2480eccc
RSZ
247 if (err)
248 goto err1;
249 if (planes == 3) {
788e20df 250 err = ion_alloc_fd(ionfd, chroma_size, 0, heap_mask, ion_flags, &fd2);
2480eccc
RSZ
251 if (err)
252 goto err2;
2480eccc 253
ec68ab21
RSZ
254 *hnd = new private_handle_t(fd, fd1, fd2, luma_size, usage, w, h,
255 format, *stride, luma_vstride);
256 } else {
257 *hnd = new private_handle_t(fd, fd1, luma_size, usage, w, h, format,
258 *stride, luma_vstride);
259 }
2480eccc
RSZ
260 return err;
261
262err2:
263 close(fd1);
264err1:
265 close(fd);
266 return err;
267}
268
269static int gralloc_alloc(alloc_device_t* dev,
270 int w, int h, int format, int usage,
271 buffer_handle_t* pHandle, int* pStride)
272{
273 int stride;
274 int err;
da3d8712 275 unsigned int ion_flags = 0;
2480eccc
RSZ
276 private_handle_t *hnd;
277
278 if (!pHandle || !pStride)
279 return -EINVAL;
280
281 if( (usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN )
da3d8712 282 ion_flags = ION_FLAG_CACHED;
788e20df
SK
283 if (usage & GRALLOC_USAGE_PROTECTED)
284 ion_flags |= ION_EXYNOS_VIDEO_MASK;
2480eccc
RSZ
285
286 private_module_t* m = reinterpret_cast<private_module_t*>
287 (dev->common.module);
288 gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>
289 (dev->common.module);
290
da3d8712
RSZ
291 err = gralloc_alloc_rgb(m->ionfd, w, h, format, usage, ion_flags, &hnd,
292 &stride);
2480eccc 293 if (err)
da3d8712
RSZ
294 err = gralloc_alloc_yuv(m->ionfd, w, h, format, usage, ion_flags,
295 &hnd, &stride);
2480eccc
RSZ
296 if (err)
297 return err;
298
299 err = grallocMap(module, hnd);
300
301 if (err != 0)
302 goto err;
303
304 *pHandle = hnd;
305 *pStride = stride;
306 return 0;
307err:
308 close(hnd->fd);
ec68ab21 309 if (hnd->fd1 >= 0)
2480eccc 310 close(hnd->fd1);
ec68ab21 311 if (hnd->fd2 >= 0)
2480eccc
RSZ
312 close(hnd->fd2);
313 return err;
314}
315
316static int gralloc_free(alloc_device_t* dev,
317 buffer_handle_t handle)
318{
319 if (private_handle_t::validate(handle) < 0)
320 return -EINVAL;
321
322 private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle);
323 gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>(
324 dev->common.module);
325
326 grallocUnmap(module, const_cast<private_handle_t*>(hnd));
327 close(hnd->fd);
ec68ab21 328 if (hnd->fd1 >= 0)
2480eccc 329 close(hnd->fd1);
ec68ab21 330 if (hnd->fd2 >= 0)
2480eccc
RSZ
331 close(hnd->fd2);
332
333 delete hnd;
334 return 0;
335}
336
337/*****************************************************************************/
338
339static int gralloc_close(struct hw_device_t *dev)
340{
341 gralloc_context_t* ctx = reinterpret_cast<gralloc_context_t*>(dev);
342 if (ctx) {
343 /* TODO: keep a list of all buffer_handle_t created, and free them
344 * all here.
345 */
346 free(ctx);
347 }
348 return 0;
349}
350
351int gralloc_device_open(const hw_module_t* module, const char* name,
352 hw_device_t** device)
353{
354 int status = -EINVAL;
355 if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
356 gralloc_context_t *dev;
357 dev = (gralloc_context_t*)malloc(sizeof(*dev));
358
359 /* initialize our state here */
360 memset(dev, 0, sizeof(*dev));
361
362 /* initialize the procs */
363 dev->device.common.tag = HARDWARE_DEVICE_TAG;
364 dev->device.common.version = 0;
365 dev->device.common.module = const_cast<hw_module_t*>(module);
366 dev->device.common.close = gralloc_close;
367
368 dev->device.alloc = gralloc_alloc;
369 dev->device.free = gralloc_free;
370
371 private_module_t *p = reinterpret_cast<private_module_t*>(dev->device.common.module);
372 p->ionfd = ion_open();
373
374 *device = &dev->device.common;
375 status = 0;
376 } else {
377 status = fb_device_open(module, name, device);
378 }
379 return status;
380}