2 * Copyright (C) 2008 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #ifdef HAVE_ANDROID_OS // just want PAGE_SIZE define
18 # include <asm/page.h>
20 # include <sys/user.h>
32 #include <sys/types.h>
33 #include <sys/ioctl.h>
36 #include <linux/ion.h>
37 #include <cutils/log.h>
38 #include <cutils/atomic.h>
40 #include <hardware/hardware.h>
41 #include <hardware/gralloc.h>
43 #include "gralloc_priv.h"
44 #include "exynos_format.h"
47 #define ION_HEAP_EXYNOS_CONTIG_MASK (1 << 4)
48 #define ION_EXYNOS_VIDEO_MASK (1 << 29)
50 /*****************************************************************************/
52 struct gralloc_context_t
{
53 alloc_device_t device
;
54 /* our private data here */
57 static int gralloc_alloc_buffer(alloc_device_t
* dev
,
58 size_t size
, int usage
, buffer_handle_t
* pHandle
);
60 /*****************************************************************************/
62 int fb_device_open(const hw_module_t
* module
, const char* name
,
63 hw_device_t
** device
);
65 static int gralloc_device_open(const hw_module_t
* module
, const char* name
,
66 hw_device_t
** device
);
68 extern int gralloc_lock(gralloc_module_t
const* module
,
69 buffer_handle_t handle
, int usage
,
70 int l
, int t
, int w
, int h
,
73 extern int gralloc_unlock(gralloc_module_t
const* module
,
74 buffer_handle_t handle
);
76 extern int gralloc_register_buffer(gralloc_module_t
const* module
,
77 buffer_handle_t handle
);
79 extern int gralloc_unregister_buffer(gralloc_module_t
const* module
,
80 buffer_handle_t handle
);
82 /*****************************************************************************/
84 static struct hw_module_methods_t gralloc_module_methods
= {
85 open
: gralloc_device_open
88 struct private_module_t HAL_MODULE_INFO_SYM
= {
91 tag
: HARDWARE_MODULE_TAG
,
94 id
: GRALLOC_HARDWARE_MODULE_ID
,
95 name
: "Graphics Memory Allocator Module",
96 author
: "The Android Open Source Project",
97 methods
: &gralloc_module_methods
99 registerBuffer
: gralloc_register_buffer
,
100 unregisterBuffer
: gralloc_unregister_buffer
,
102 unlock
: gralloc_unlock
,
108 lock
: PTHREAD_MUTEX_INITIALIZER
,
113 /*****************************************************************************/
115 #define ALIGN(x, a) (((x) + (a - 1)) & ~(a - 1))
117 static unsigned int _select_heap(int usage
)
119 unsigned int heap_mask
;
121 if (usage
& GRALLOC_USAGE_PROTECTED
)
122 heap_mask
= ION_HEAP_EXYNOS_CONTIG_MASK
;
124 heap_mask
= ION_HEAP_SYSTEM_MASK
;
129 static 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
)
133 int bpp
= 0, vstride
, fd
, err
;
134 unsigned int heap_mask
= _select_heap(usage
);
137 case HAL_PIXEL_FORMAT_RGBA_8888
:
138 case HAL_PIXEL_FORMAT_RGBX_8888
:
139 case HAL_PIXEL_FORMAT_BGRA_8888
:
142 case HAL_PIXEL_FORMAT_RGB_888
:
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
:
151 case HAL_PIXEL_FORMAT_BLOB
:
157 bpr
= ALIGN(w
*bpp
, 16);
158 vstride
= ALIGN(h
, 16);
159 size
= bpr
* vstride
;
161 size
= ALIGN(size
, PAGE_SIZE
);
163 err
= ion_alloc_fd(ionfd
, size
, 0, heap_mask
, ion_flags
,
165 *hnd
= new private_handle_t(fd
, size
, usage
, w
, h
, format
, *stride
,
171 static int gralloc_alloc_framework_yuv(int ionfd
, int w
, int h
, int format
,
172 int usage
, unsigned int ion_flags
,
173 private_handle_t
**hnd
, int *stride
)
179 case HAL_PIXEL_FORMAT_YV12
:
180 *stride
= ALIGN(w
, 16);
182 case HAL_PIXEL_FORMAT_YCrCb_420_SP
:
186 ALOGE("invalid yuv format %d\n", format
);
190 size
= *stride
* h
* 3 / 2;
191 err
= ion_alloc_fd(ionfd
, size
, 0, 1 << ION_HEAP_TYPE_SYSTEM
,
196 *hnd
= new private_handle_t(fd
, size
, usage
, w
, h
, format
, *stride
, h
);
200 static int gralloc_alloc_yuv(int ionfd
, int w
, int h
, int format
,
201 int usage
, unsigned int ion_flags
,
202 private_handle_t
**hnd
, int *stride
)
204 size_t luma_size
, chroma_size
;
205 int err
, planes
, fd
, fd1
, fd2
= 0;
207 unsigned int heap_mask
= _select_heap(usage
);
209 *stride
= ALIGN(w
, 16);
212 case HAL_PIXEL_FORMAT_EXYNOS_YV12
:
214 luma_vstride
= ALIGN(h
, 16);
215 luma_size
= luma_vstride
* *stride
;
216 chroma_size
= (luma_vstride
/ 2) * ALIGN(*stride
/ 2, 16);
220 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP
:
221 case HAL_PIXEL_FORMAT_YCbCr_420_SP
:
222 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED
:
224 size_t chroma_vstride
= ALIGN(h
/ 2, 32);
225 luma_vstride
= ALIGN(h
, 32);
226 luma_size
= luma_vstride
* *stride
;
227 chroma_size
= chroma_vstride
* *stride
;
231 case HAL_PIXEL_FORMAT_YV12
:
232 case HAL_PIXEL_FORMAT_YCrCb_420_SP
:
233 return gralloc_alloc_framework_yuv(ionfd
, w
, h
, format
, usage
,
234 ion_flags
, hnd
, stride
);
236 ALOGE("invalid yuv format %d\n", format
);
240 err
= ion_alloc_fd(ionfd
, luma_size
, 0, heap_mask
, ion_flags
, &fd
);
243 err
= ion_alloc_fd(ionfd
, chroma_size
, 0, heap_mask
, ion_flags
, &fd1
);
247 err
= ion_alloc_fd(ionfd
, chroma_size
, 0, heap_mask
, ion_flags
, &fd2
);
251 *hnd
= new private_handle_t(fd
, fd1
, fd2
, luma_size
, usage
, w
, h
,
252 format
, *stride
, luma_vstride
);
254 *hnd
= new private_handle_t(fd
, fd1
, luma_size
, usage
, w
, h
, format
,
255 *stride
, luma_vstride
);
266 static int gralloc_alloc(alloc_device_t
* dev
,
267 int w
, int h
, int format
, int usage
,
268 buffer_handle_t
* pHandle
, int* pStride
)
272 unsigned int ion_flags
= 0;
273 private_handle_t
*hnd
;
275 if (!pHandle
|| !pStride
)
278 if( (usage
& GRALLOC_USAGE_SW_READ_MASK
) == GRALLOC_USAGE_SW_READ_OFTEN
)
279 ion_flags
= ION_FLAG_CACHED
;
280 if (usage
& GRALLOC_USAGE_PROTECTED
)
281 ion_flags
|= ION_EXYNOS_VIDEO_MASK
;
283 private_module_t
* m
= reinterpret_cast<private_module_t
*>
284 (dev
->common
.module
);
285 gralloc_module_t
* module
= reinterpret_cast<gralloc_module_t
*>
286 (dev
->common
.module
);
288 err
= gralloc_alloc_rgb(m
->ionfd
, w
, h
, format
, usage
, ion_flags
, &hnd
,
291 err
= gralloc_alloc_yuv(m
->ionfd
, w
, h
, format
, usage
, ion_flags
,
296 err
= grallocMap(module
, hnd
);
313 static int gralloc_free(alloc_device_t
* dev
,
314 buffer_handle_t handle
)
316 if (private_handle_t::validate(handle
) < 0)
319 private_handle_t
const* hnd
= reinterpret_cast<private_handle_t
const*>(handle
);
320 gralloc_module_t
* module
= reinterpret_cast<gralloc_module_t
*>(
323 grallocUnmap(module
, const_cast<private_handle_t
*>(hnd
));
334 /*****************************************************************************/
336 static int gralloc_close(struct hw_device_t
*dev
)
338 gralloc_context_t
* ctx
= reinterpret_cast<gralloc_context_t
*>(dev
);
340 /* TODO: keep a list of all buffer_handle_t created, and free them
348 int gralloc_device_open(const hw_module_t
* module
, const char* name
,
349 hw_device_t
** device
)
351 int status
= -EINVAL
;
352 if (!strcmp(name
, GRALLOC_HARDWARE_GPU0
)) {
353 gralloc_context_t
*dev
;
354 dev
= (gralloc_context_t
*)malloc(sizeof(*dev
));
356 /* initialize our state here */
357 memset(dev
, 0, sizeof(*dev
));
359 /* initialize the procs */
360 dev
->device
.common
.tag
= HARDWARE_DEVICE_TAG
;
361 dev
->device
.common
.version
= 0;
362 dev
->device
.common
.module
= const_cast<hw_module_t
*>(module
);
363 dev
->device
.common
.close
= gralloc_close
;
365 dev
->device
.alloc
= gralloc_alloc
;
366 dev
->device
.free
= gralloc_free
;
368 private_module_t
*p
= reinterpret_cast<private_module_t
*>(dev
->device
.common
.module
);
369 p
->ionfd
= ion_open();
371 *device
= &dev
->device
.common
;
374 status
= fb_device_open(module
, name
, device
);