blob: 4937bbbaf634252b386d9238de5597cb037e49e7 [file] [log] [blame]
Rebecca Schultz Zavin2480ecc2012-08-14 16:08:04 -07001/*
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 },
96registerBuffer: gralloc_register_buffer,
97 unregisterBuffer: gralloc_unregister_buffer,
98 lock: gralloc_lock,
99 unlock: gralloc_unlock,
100 },
101framebuffer: 0,
102 flags: 0,
103 numBuffers: 0,
104 bufferMask: 0,
105 lock: PTHREAD_MUTEX_INITIALIZER,
106 currentBuffer: 0,
107 ionfd: -1,
108};
109
110/*****************************************************************************/
111
112#define ALIGN(x, a) (((x) + (a - 1)) & ~(a - 1))
113
114static int gralloc_alloc_rgb(int ionfd, int w, int h, int format, int flags,
115 private_handle_t **hnd, int *stride)
116{
117 size_t size, bpr;
118 int bpp = 0, fd, err;
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);
141 size = bpr * h;
142 *stride = bpr / bpp;
143 size = ALIGN(size, PAGE_SIZE);
144
145 err = ion_alloc_fd(ionfd, size, 0, 1 << ION_HEAP_TYPE_SYSTEM, flags, &fd);
146 *hnd = new private_handle_t(fd, size, 0, w, h, format, *stride);
147
148 return err;
149}
150
151static int gralloc_alloc_yuv(int ionfd, int w, int h, int format, int flags,
152 private_handle_t **hnd, int *stride)
153{
154 size_t luma_size, chroma_size;
155 int err, planes, fd, fd1, fd2 = 0;
156 *stride = ALIGN(w, 16);
157
158 switch (format) {
159 ALOGE("invalid yuv format %d\n", format);
160 case HAL_PIXEL_FORMAT_YV12:
161 {
162 size_t vstride = ALIGN(h, 16);
163 luma_size = vstride * *stride;
164 chroma_size = (vstride / 2) * ALIGN(*stride / 2, 16);
165 planes = 3;
166 break;
167 }
168 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
169 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
170 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
171 {
172 size_t luma_vstride = ALIGN(h, 32);
173 size_t chroma_vstride = ALIGN(h / 2, 32);
174 luma_size = luma_vstride * *stride;
175 chroma_size = chroma_vstride * *stride;
176 planes = 2;
177 break;
178 }
179 default:
180 ALOGE("invalid yuv format %d\n", format);
181 return -EINVAL;
182 }
183
184 err = ion_alloc_fd(ionfd, luma_size, 0, 1 << ION_HEAP_TYPE_SYSTEM, flags,
185 &fd);
186 if (err)
187 return err;
188 err = ion_alloc_fd(ionfd, chroma_size, 0, 1 << ION_HEAP_TYPE_SYSTEM, flags,
189 &fd1);
190 if (err)
191 goto err1;
192 if (planes == 3) {
193 err = ion_alloc_fd(ionfd, chroma_size, 0, 1 << ION_HEAP_TYPE_SYSTEM,
194 flags, &fd2);
195 if (err)
196 goto err2;
197 }
198
199 *hnd = new private_handle_t(fd, fd1, fd2, luma_size, 0, w, h, format,
200 *stride);
201 return err;
202
203err2:
204 close(fd1);
205err1:
206 close(fd);
207 return err;
208}
209
210static int gralloc_alloc(alloc_device_t* dev,
211 int w, int h, int format, int usage,
212 buffer_handle_t* pHandle, int* pStride)
213{
214 int stride;
215 int err;
216 int flags = 0;
217 private_handle_t *hnd;
218
219 if (!pHandle || !pStride)
220 return -EINVAL;
221
222 if( (usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN )
223 flags = ION_FLAG_CACHED;
224
225 private_module_t* m = reinterpret_cast<private_module_t*>
226 (dev->common.module);
227 gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>
228 (dev->common.module);
229
230 err = gralloc_alloc_rgb(m->ionfd, w, h, format, flags, &hnd, &stride);
231 if (err)
232 err = gralloc_alloc_yuv(m->ionfd, w, h, format, flags, &hnd, &stride);
233 if (err)
234 return err;
235
236 err = grallocMap(module, hnd);
237
238 if (err != 0)
239 goto err;
240
241 *pHandle = hnd;
242 *pStride = stride;
243 return 0;
244err:
245 close(hnd->fd);
246 if (hnd->fd1 > 0)
247 close(hnd->fd1);
248 if (hnd->fd2 > 0)
249 close(hnd->fd2);
250 return err;
251}
252
253static int gralloc_free(alloc_device_t* dev,
254 buffer_handle_t handle)
255{
256 if (private_handle_t::validate(handle) < 0)
257 return -EINVAL;
258
259 private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle);
260 gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>(
261 dev->common.module);
262
263 grallocUnmap(module, const_cast<private_handle_t*>(hnd));
264 close(hnd->fd);
265 if (hnd->fd1 > 0)
266 close(hnd->fd1);
267 if (hnd->fd2 > 0)
268 close(hnd->fd2);
269
270 delete hnd;
271 return 0;
272}
273
274/*****************************************************************************/
275
276static int gralloc_close(struct hw_device_t *dev)
277{
278 gralloc_context_t* ctx = reinterpret_cast<gralloc_context_t*>(dev);
279 if (ctx) {
280 /* TODO: keep a list of all buffer_handle_t created, and free them
281 * all here.
282 */
283 free(ctx);
284 }
285 return 0;
286}
287
288int gralloc_device_open(const hw_module_t* module, const char* name,
289 hw_device_t** device)
290{
291 int status = -EINVAL;
292 if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
293 gralloc_context_t *dev;
294 dev = (gralloc_context_t*)malloc(sizeof(*dev));
295
296 /* initialize our state here */
297 memset(dev, 0, sizeof(*dev));
298
299 /* initialize the procs */
300 dev->device.common.tag = HARDWARE_DEVICE_TAG;
301 dev->device.common.version = 0;
302 dev->device.common.module = const_cast<hw_module_t*>(module);
303 dev->device.common.close = gralloc_close;
304
305 dev->device.alloc = gralloc_alloc;
306 dev->device.free = gralloc_free;
307
308 private_module_t *p = reinterpret_cast<private_module_t*>(dev->device.common.module);
309 p->ionfd = ion_open();
310
311 *device = &dev->device.common;
312 status = 0;
313 } else {
314 status = fb_device_open(module, name, device);
315 }
316 return status;
317}