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 /*****************************************************************************/
49 struct gralloc_context_t
{
50 alloc_device_t device
;
51 /* our private data here */
54 static int gralloc_alloc_buffer(alloc_device_t
* dev
,
55 size_t size
, int usage
, buffer_handle_t
* pHandle
);
57 /*****************************************************************************/
59 int fb_device_open(const hw_module_t
* module
, const char* name
,
60 hw_device_t
** device
);
62 static int gralloc_device_open(const hw_module_t
* module
, const char* name
,
63 hw_device_t
** device
);
65 extern int gralloc_lock(gralloc_module_t
const* module
,
66 buffer_handle_t handle
, int usage
,
67 int l
, int t
, int w
, int h
,
70 extern int gralloc_unlock(gralloc_module_t
const* module
,
71 buffer_handle_t handle
);
73 extern int gralloc_register_buffer(gralloc_module_t
const* module
,
74 buffer_handle_t handle
);
76 extern int gralloc_unregister_buffer(gralloc_module_t
const* module
,
77 buffer_handle_t handle
);
79 /*****************************************************************************/
81 static struct hw_module_methods_t gralloc_module_methods
= {
82 open
: gralloc_device_open
85 struct private_module_t HAL_MODULE_INFO_SYM
= {
88 tag
: HARDWARE_MODULE_TAG
,
91 id
: GRALLOC_HARDWARE_MODULE_ID
,
92 name
: "Graphics Memory Allocator Module",
93 author
: "The Android Open Source Project",
94 methods
: &gralloc_module_methods
96 registerBuffer
: gralloc_register_buffer
,
97 unregisterBuffer
: gralloc_unregister_buffer
,
99 unlock
: gralloc_unlock
,
105 lock
: PTHREAD_MUTEX_INITIALIZER
,
110 /*****************************************************************************/
112 #define ALIGN(x, a) (((x) + (a - 1)) & ~(a - 1))
114 static int gralloc_alloc_rgb(int ionfd
, int w
, int h
, int format
, int flags
,
115 private_handle_t
**hnd
, int *stride
)
118 int bpp
= 0, vstride
, fd
, err
;
120 case HAL_PIXEL_FORMAT_RGBA_8888
:
121 case HAL_PIXEL_FORMAT_RGBX_8888
:
122 case HAL_PIXEL_FORMAT_BGRA_8888
:
125 case HAL_PIXEL_FORMAT_RGB_888
:
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
:
134 case HAL_PIXEL_FORMAT_BLOB
:
140 bpr
= ALIGN(w
*bpp
, 16);
141 vstride
= ALIGN(h
, 16);
142 size
= bpr
* vstride
;
144 size
= ALIGN(size
, PAGE_SIZE
);
146 err
= ion_alloc_fd(ionfd
, size
, 0, 1 << ION_HEAP_TYPE_SYSTEM
, flags
, &fd
);
147 *hnd
= new private_handle_t(fd
, size
, 0, w
, h
, format
, *stride
, vstride
);
152 static int gralloc_alloc_yuv(int ionfd
, int w
, int h
, int format
, int flags
,
153 private_handle_t
**hnd
, int *stride
)
155 size_t luma_size
, chroma_size
;
156 int err
, planes
, fd
, fd1
, fd2
= 0;
158 *stride
= ALIGN(w
, 16);
161 ALOGE("invalid yuv format %d\n", format
);
162 case HAL_PIXEL_FORMAT_YV12
:
164 luma_vstride
= ALIGN(h
, 16);
165 luma_size
= luma_vstride
* *stride
;
166 chroma_size
= (luma_vstride
/ 2) * ALIGN(*stride
/ 2, 16);
170 case HAL_PIXEL_FORMAT_YCrCb_420_SP
:
171 case HAL_PIXEL_FORMAT_YCbCr_420_SP
:
172 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED
:
174 size_t chroma_vstride
= ALIGN(h
/ 2, 32);
175 luma_vstride
= ALIGN(h
, 32);
176 luma_size
= luma_vstride
* *stride
;
177 chroma_size
= chroma_vstride
* *stride
;
182 ALOGE("invalid yuv format %d\n", format
);
186 err
= ion_alloc_fd(ionfd
, luma_size
, 0, 1 << ION_HEAP_TYPE_SYSTEM
, flags
,
190 err
= ion_alloc_fd(ionfd
, chroma_size
, 0, 1 << ION_HEAP_TYPE_SYSTEM
, flags
,
195 err
= ion_alloc_fd(ionfd
, chroma_size
, 0, 1 << ION_HEAP_TYPE_SYSTEM
,
201 *hnd
= new private_handle_t(fd
, fd1
, fd2
, luma_size
, 0, w
, h
, format
,
202 *stride
, luma_vstride
);
212 static int gralloc_alloc(alloc_device_t
* dev
,
213 int w
, int h
, int format
, int usage
,
214 buffer_handle_t
* pHandle
, int* pStride
)
219 private_handle_t
*hnd
;
221 if (!pHandle
|| !pStride
)
224 if( (usage
& GRALLOC_USAGE_SW_READ_MASK
) == GRALLOC_USAGE_SW_READ_OFTEN
)
225 flags
= ION_FLAG_CACHED
;
227 private_module_t
* m
= reinterpret_cast<private_module_t
*>
228 (dev
->common
.module
);
229 gralloc_module_t
* module
= reinterpret_cast<gralloc_module_t
*>
230 (dev
->common
.module
);
232 err
= gralloc_alloc_rgb(m
->ionfd
, w
, h
, format
, flags
, &hnd
, &stride
);
234 err
= gralloc_alloc_yuv(m
->ionfd
, w
, h
, format
, flags
, &hnd
, &stride
);
238 err
= grallocMap(module
, hnd
);
255 static int gralloc_free(alloc_device_t
* dev
,
256 buffer_handle_t handle
)
258 if (private_handle_t::validate(handle
) < 0)
261 private_handle_t
const* hnd
= reinterpret_cast<private_handle_t
const*>(handle
);
262 gralloc_module_t
* module
= reinterpret_cast<gralloc_module_t
*>(
265 grallocUnmap(module
, const_cast<private_handle_t
*>(hnd
));
276 /*****************************************************************************/
278 static int gralloc_close(struct hw_device_t
*dev
)
280 gralloc_context_t
* ctx
= reinterpret_cast<gralloc_context_t
*>(dev
);
282 /* TODO: keep a list of all buffer_handle_t created, and free them
290 int gralloc_device_open(const hw_module_t
* module
, const char* name
,
291 hw_device_t
** device
)
293 int status
= -EINVAL
;
294 if (!strcmp(name
, GRALLOC_HARDWARE_GPU0
)) {
295 gralloc_context_t
*dev
;
296 dev
= (gralloc_context_t
*)malloc(sizeof(*dev
));
298 /* initialize our state here */
299 memset(dev
, 0, sizeof(*dev
));
301 /* initialize the procs */
302 dev
->device
.common
.tag
= HARDWARE_DEVICE_TAG
;
303 dev
->device
.common
.version
= 0;
304 dev
->device
.common
.module
= const_cast<hw_module_t
*>(module
);
305 dev
->device
.common
.close
= gralloc_close
;
307 dev
->device
.alloc
= gralloc_alloc
;
308 dev
->device
.free
= gralloc_free
;
310 private_module_t
*p
= reinterpret_cast<private_module_t
*>(dev
->device
.common
.module
);
311 p
->ionfd
= ion_open();
313 *device
= &dev
->device
.common
;
316 status
= fb_device_open(module
, name
, device
);