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_FIMD_VIDEO_MASK (1 << 28)
49 #define ION_EXYNOS_MFC_OUTPUT_MASK (1 << 26)
50 #define ION_EXYNOS_MFC_INPUT_MASK (1 << 25)
53 /*****************************************************************************/
55 struct gralloc_context_t
{
56 alloc_device_t device
;
57 /* our private data here */
60 static int gralloc_alloc_buffer(alloc_device_t
* dev
,
61 size_t size
, int usage
, buffer_handle_t
* pHandle
);
63 /*****************************************************************************/
65 int fb_device_open(const hw_module_t
* module
, const char* name
,
66 hw_device_t
** device
);
68 static int gralloc_device_open(const hw_module_t
* module
, const char* name
,
69 hw_device_t
** device
);
71 extern int gralloc_lock(gralloc_module_t
const* module
,
72 buffer_handle_t handle
, int usage
,
73 int l
, int t
, int w
, int h
,
76 extern int gralloc_unlock(gralloc_module_t
const* module
,
77 buffer_handle_t handle
);
79 extern int gralloc_register_buffer(gralloc_module_t
const* module
,
80 buffer_handle_t handle
);
82 extern int gralloc_unregister_buffer(gralloc_module_t
const* module
,
83 buffer_handle_t handle
);
85 /*****************************************************************************/
87 static struct hw_module_methods_t gralloc_module_methods
= {
88 open
: gralloc_device_open
91 struct private_module_t HAL_MODULE_INFO_SYM
= {
94 tag
: HARDWARE_MODULE_TAG
,
97 id
: GRALLOC_HARDWARE_MODULE_ID
,
98 name
: "Graphics Memory Allocator Module",
99 author
: "The Android Open Source Project",
100 methods
: &gralloc_module_methods
102 registerBuffer
: gralloc_register_buffer
,
103 unregisterBuffer
: gralloc_unregister_buffer
,
105 unlock
: gralloc_unlock
,
111 lock
: PTHREAD_MUTEX_INITIALIZER
,
116 /*****************************************************************************/
118 static unsigned int _select_heap(int usage
)
120 unsigned int heap_mask
;
122 if (usage
& GRALLOC_USAGE_PROTECTED
)
123 heap_mask
= ION_HEAP_EXYNOS_CONTIG_MASK
;
125 heap_mask
= ION_HEAP_SYSTEM_MASK
;
130 static int gralloc_alloc_rgb(int ionfd
, int w
, int h
, int format
, int usage
,
131 unsigned int ion_flags
, private_handle_t
**hnd
, int *stride
)
134 int bpp
= 0, vstride
, fd
, err
;
135 unsigned int heap_mask
= _select_heap(usage
);
138 case HAL_PIXEL_FORMAT_RGBA_8888
:
139 case HAL_PIXEL_FORMAT_RGBX_8888
:
140 case HAL_PIXEL_FORMAT_BGRA_8888
:
143 case HAL_PIXEL_FORMAT_RGB_888
:
146 case HAL_PIXEL_FORMAT_RGB_565
:
147 case HAL_PIXEL_FORMAT_RGBA_5551
:
148 case HAL_PIXEL_FORMAT_RGBA_4444
:
149 case HAL_PIXEL_FORMAT_RAW_SENSOR
:
152 case HAL_PIXEL_FORMAT_BLOB
:
158 bpr
= ALIGN(w
*bpp
, 16);
159 vstride
= ALIGN(h
, 16);
161 size
= bpr
* (vstride
+ 1);
163 size
= bpr
* vstride
;
165 size
= ALIGN(size
, PAGE_SIZE
);
167 if (usage
& GRALLOC_USAGE_PROTECTED
)
168 ion_flags
|= ION_EXYNOS_FIMD_VIDEO_MASK
;
170 err
= ion_alloc_fd(ionfd
, size
, 0, heap_mask
, ion_flags
,
172 *hnd
= new private_handle_t(fd
, size
, usage
, w
, h
, format
, *stride
,
178 static int gralloc_alloc_framework_yuv(int ionfd
, int w
, int h
, int format
,
179 int usage
, unsigned int ion_flags
,
180 private_handle_t
**hnd
, int *stride
)
186 case HAL_PIXEL_FORMAT_YV12
:
187 *stride
= ALIGN(w
, 16);
189 case HAL_PIXEL_FORMAT_YCrCb_420_SP
:
193 ALOGE("invalid yuv format %d\n", format
);
197 size
= *stride
* h
* 3 / 2;
198 err
= ion_alloc_fd(ionfd
, size
, 0, 1 << ION_HEAP_TYPE_SYSTEM
,
203 *hnd
= new private_handle_t(fd
, size
, usage
, w
, h
, format
, *stride
, h
);
207 static int gralloc_alloc_yuv(int ionfd
, int w
, int h
, int format
,
208 int usage
, unsigned int ion_flags
,
209 private_handle_t
**hnd
, int *stride
)
211 size_t luma_size
, chroma_size
;
212 int err
, planes
, fd
, fd1
, fd2
= 0;
214 unsigned int heap_mask
= _select_heap(usage
);
216 *stride
= ALIGN(w
, 16);
218 if (format
== HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED
) {
219 ALOGV("HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED : usage(%x), flags(%x)\n", usage
, ion_flags
);
220 if ((usage
& GRALLOC_USAGE_HW_CAMERA_ZSL
) == GRALLOC_USAGE_HW_CAMERA_ZSL
) {
221 format
= HAL_PIXEL_FORMAT_YCbCr_422_I
; // YUYV
222 } else if (usage
& GRALLOC_USAGE_HW_TEXTURE
) {
223 format
= HAL_PIXEL_FORMAT_EXYNOS_YV12
;
224 } else if (usage
& GRALLOC_USAGE_HW_VIDEO_ENCODER
) {
225 format
= HAL_PIXEL_FORMAT_YCbCr_420_SP
; // NV12M
229 case HAL_PIXEL_FORMAT_EXYNOS_YV12
:
231 luma_vstride
= ALIGN(h
, 16);
232 luma_size
= luma_vstride
* *stride
;
233 chroma_size
= (luma_vstride
/ 2) * ALIGN(*stride
/ 2, 16);
237 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP
:
238 case HAL_PIXEL_FORMAT_YCbCr_420_SP
:
239 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED
:
241 size_t chroma_vstride
= ALIGN(h
/ 2, 32);
242 luma_vstride
= ALIGN(h
, 32);
243 luma_size
= luma_vstride
* *stride
;
244 chroma_size
= chroma_vstride
* *stride
;
248 case HAL_PIXEL_FORMAT_YV12
:
249 case HAL_PIXEL_FORMAT_YCrCb_420_SP
:
250 return gralloc_alloc_framework_yuv(ionfd
, w
, h
, format
, usage
,
251 ion_flags
, hnd
, stride
);
252 case HAL_PIXEL_FORMAT_YCbCr_422_I
:
255 luma_size
= luma_vstride
* *stride
* 2;
261 ALOGE("invalid yuv format %d\n", format
);
265 if (usage
& GRALLOC_USAGE_PROTECTED
)
266 ion_flags
|= ION_EXYNOS_MFC_OUTPUT_MASK
;
268 err
= ion_alloc_fd(ionfd
, luma_size
, 0, heap_mask
, ion_flags
, &fd
);
272 *hnd
= new private_handle_t(fd
, luma_size
, usage
, w
, h
,
273 format
, *stride
, luma_vstride
);
275 err
= ion_alloc_fd(ionfd
, chroma_size
, 0, heap_mask
, ion_flags
, &fd1
);
279 err
= ion_alloc_fd(ionfd
, chroma_size
, 0, heap_mask
, ion_flags
, &fd2
);
283 *hnd
= new private_handle_t(fd
, fd1
, fd2
, luma_size
, usage
, w
, h
,
284 format
, *stride
, luma_vstride
);
286 *hnd
= new private_handle_t(fd
, fd1
, luma_size
, usage
, w
, h
, format
,
287 *stride
, luma_vstride
);
299 static int gralloc_alloc(alloc_device_t
* dev
,
300 int w
, int h
, int format
, int usage
,
301 buffer_handle_t
* pHandle
, int* pStride
)
305 unsigned int ion_flags
= 0;
306 private_handle_t
*hnd
= NULL
;
308 if (!pHandle
|| !pStride
)
311 if( (usage
& GRALLOC_USAGE_SW_READ_MASK
) == GRALLOC_USAGE_SW_READ_OFTEN
)
312 ion_flags
= ION_FLAG_CACHED
;
314 private_module_t
* m
= reinterpret_cast<private_module_t
*>
315 (dev
->common
.module
);
316 gralloc_module_t
* module
= reinterpret_cast<gralloc_module_t
*>
317 (dev
->common
.module
);
319 err
= gralloc_alloc_rgb(m
->ionfd
, w
, h
, format
, usage
, ion_flags
, &hnd
,
322 err
= gralloc_alloc_yuv(m
->ionfd
, w
, h
, format
, usage
, ion_flags
,
327 err
= grallocMap(module
, hnd
);
346 static int gralloc_free(alloc_device_t
* dev
,
347 buffer_handle_t handle
)
349 if (private_handle_t::validate(handle
) < 0)
352 private_handle_t
const* hnd
= reinterpret_cast<private_handle_t
const*>(handle
);
353 gralloc_module_t
* module
= reinterpret_cast<gralloc_module_t
*>(
356 grallocUnmap(module
, const_cast<private_handle_t
*>(hnd
));
367 /*****************************************************************************/
369 static int gralloc_close(struct hw_device_t
*dev
)
371 gralloc_context_t
* ctx
= reinterpret_cast<gralloc_context_t
*>(dev
);
373 /* TODO: keep a list of all buffer_handle_t created, and free them
381 int gralloc_device_open(const hw_module_t
* module
, const char* name
,
382 hw_device_t
** device
)
384 int status
= -EINVAL
;
385 if (!strcmp(name
, GRALLOC_HARDWARE_GPU0
)) {
386 gralloc_context_t
*dev
;
387 dev
= (gralloc_context_t
*)malloc(sizeof(*dev
));
389 /* initialize our state here */
390 memset(dev
, 0, sizeof(*dev
));
392 /* initialize the procs */
393 dev
->device
.common
.tag
= HARDWARE_DEVICE_TAG
;
394 dev
->device
.common
.version
= 0;
395 dev
->device
.common
.module
= const_cast<hw_module_t
*>(module
);
396 dev
->device
.common
.close
= gralloc_close
;
398 dev
->device
.alloc
= gralloc_alloc
;
399 dev
->device
.free
= gralloc_free
;
401 private_module_t
*p
= reinterpret_cast<private_module_t
*>(dev
->device
.common
.module
);
402 p
->ionfd
= ion_open();
404 *device
= &dev
->device
.common
;
407 status
= fb_device_open(module
, name
, device
);