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.
27 #include <sys/types.h>
28 #include <sys/ioctl.h>
31 #include <linux/ion.h>
32 #include <cutils/log.h>
33 #include <cutils/atomic.h>
35 #include <hardware/hardware.h>
36 #include <hardware/gralloc.h>
38 #include "gralloc_priv.h"
39 #include "exynos_format.h"
41 #define ION_HEAP_EXYNOS_CONTIG_MASK (1 << 4)
42 #define ION_EXYNOS_FIMD_VIDEO_MASK (1 << 28)
43 #define ION_EXYNOS_MFC_OUTPUT_MASK (1 << 26)
44 #define ION_EXYNOS_MFC_INPUT_MASK (1 << 25)
45 #define ION_HEAP_SYSTEM_ID 0
46 #define ION_HEAP_EXYNOS_CONTIG_ID 4
47 #define ION_HEAP_CHUNK_ID 6
48 #define MB_1 (1024*1024)
51 /*****************************************************************************/
53 struct gralloc_context_t
{
54 alloc_device_t device
;
55 /* our private data here */
58 static int gralloc_alloc_buffer(alloc_device_t
* dev
,
59 size_t size
, int usage
, buffer_handle_t
* pHandle
);
61 /*****************************************************************************/
63 int fb_device_open(const hw_module_t
* module
, const char* name
,
64 hw_device_t
** device
);
66 static int gralloc_device_open(const hw_module_t
* module
, const char* name
,
67 hw_device_t
** device
);
69 extern int gralloc_lock(gralloc_module_t
const* module
,
70 buffer_handle_t handle
, int usage
,
71 int l
, int t
, int w
, int h
,
74 extern int gralloc_unlock(gralloc_module_t
const* module
,
75 buffer_handle_t handle
);
77 extern int gralloc_register_buffer(gralloc_module_t
const* module
,
78 buffer_handle_t handle
);
80 extern int gralloc_unregister_buffer(gralloc_module_t
const* module
,
81 buffer_handle_t handle
);
83 /*****************************************************************************/
85 static struct hw_module_methods_t gralloc_module_methods
= {
86 open
: gralloc_device_open
89 struct private_module_t HAL_MODULE_INFO_SYM
= {
92 tag
: HARDWARE_MODULE_TAG
,
95 id
: GRALLOC_HARDWARE_MODULE_ID
,
96 name
: "Graphics Memory Allocator Module",
97 author
: "The Android Open Source Project",
98 methods
: &gralloc_module_methods
100 registerBuffer
: gralloc_register_buffer
,
101 unregisterBuffer
: gralloc_unregister_buffer
,
103 unlock
: gralloc_unlock
,
109 lock
: PTHREAD_MUTEX_INITIALIZER
,
115 /*****************************************************************************/
117 static unsigned int _select_heap(int usage
)
119 unsigned int heap_mask
;
121 if (usage
& GRALLOC_USAGE_PROTECTED
)
122 heap_mask
= (1 << ION_HEAP_EXYNOS_CONTIG_ID
);
124 heap_mask
= (1 << ION_HEAP_SYSTEM_ID
) | (1 << ION_HEAP_CHUNK_ID
);
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
)
132 size_t size
, bpr
, alignment
= 0;
133 int bpp
= 0, vstride
, fd
, err
;
134 unsigned int heap_mask
= _select_heap(usage
);
136 if (format
== HAL_PIXEL_FORMAT_RGBA_8888
) {
137 bool sw_usage
= !!(usage
& (GRALLOC_USAGE_SW_READ_MASK
|
138 GRALLOC_USAGE_SW_WRITE_MASK
));
140 if (usage
& GRALLOC_USAGE_HW_FB
) {
142 "framebuffer target should not have SW usage bits; ignoring");
143 format
= HAL_PIXEL_FORMAT_BGRA_8888
;
144 } else if (usage
& GRALLOC_USAGE_HW_VIDEO_ENCODER
) {
147 format
= HAL_PIXEL_FORMAT_BGRA_8888
;
152 case HAL_PIXEL_FORMAT_RGBA_8888
:
153 case HAL_PIXEL_FORMAT_RGBX_8888
:
154 case HAL_PIXEL_FORMAT_BGRA_8888
:
157 case HAL_PIXEL_FORMAT_RGB_888
:
160 case HAL_PIXEL_FORMAT_RGB_565
:
161 case HAL_PIXEL_FORMAT_RAW_SENSOR
:
164 case HAL_PIXEL_FORMAT_BLOB
:
173 if (format
!= HAL_PIXEL_FORMAT_BLOB
) {
174 bpr
= ALIGN(w
*bpp
, 64);
175 vstride
= ALIGN(h
, 16);
177 size
= bpr
* (h
+ 2);
179 size
= bpr
* vstride
;
181 size
= ALIGN(size
, PAGE_SIZE
);
184 if (usage
& GRALLOC_USAGE_PROTECTED
) {
186 ion_flags
|= ION_EXYNOS_FIMD_VIDEO_MASK
;
189 err
= ion_alloc_fd(ionfd
, size
, alignment
, heap_mask
, ion_flags
,
191 *hnd
= new private_handle_t(fd
, size
, usage
, w
, h
, format
, *stride
,
197 static int gralloc_alloc_framework_yuv(int ionfd
, int w
, int h
, int format
,
198 int usage
, unsigned int ion_flags
,
199 private_handle_t
**hnd
, int *stride
)
203 unsigned int heap_mask
= _select_heap(usage
);
206 case HAL_PIXEL_FORMAT_YV12
:
207 *stride
= ALIGN(w
, 16);
208 size
= (*stride
* h
) + (ALIGN(*stride
/ 2, 16) * h
);
210 case HAL_PIXEL_FORMAT_YCrCb_420_SP
:
212 size
= *stride
* h
* 3 / 2;
215 ALOGE("invalid yuv format %d\n", format
);
219 err
= ion_alloc_fd(ionfd
, size
, 0, heap_mask
, ion_flags
, &fd
);
223 *hnd
= new private_handle_t(fd
, size
, usage
, w
, h
, format
, *stride
, h
);
227 static int gralloc_alloc_yuv(int ionfd
, int w
, int h
, int format
,
228 int usage
, unsigned int ion_flags
,
229 private_handle_t
**hnd
, int *stride
)
231 size_t luma_size
, chroma_size
;
232 int err
, planes
, fd
, fd1
, fd2
= 0;
234 unsigned int heap_mask
= _select_heap(usage
);
236 *stride
= ALIGN(w
, 16);
238 if (format
== HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED
) {
239 ALOGV("HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED : usage(%x), flags(%x)\n", usage
, ion_flags
);
240 if ((usage
& GRALLOC_USAGE_HW_CAMERA_ZSL
) == GRALLOC_USAGE_HW_CAMERA_ZSL
) {
241 format
= HAL_PIXEL_FORMAT_YCbCr_422_I
; // YUYV
242 } else if (usage
& GRALLOC_USAGE_HW_TEXTURE
) {
243 format
= HAL_PIXEL_FORMAT_EXYNOS_YV12
;
244 } else if (usage
& GRALLOC_USAGE_HW_VIDEO_ENCODER
) {
245 format
= HAL_PIXEL_FORMAT_YCbCr_420_SP
; // NV12M
249 case HAL_PIXEL_FORMAT_EXYNOS_YV12
:
251 *stride
= ALIGN(w
, 32);
252 luma_vstride
= ALIGN(h
, 16);
253 luma_size
= luma_vstride
* *stride
;
254 chroma_size
= (luma_vstride
/ 2) * ALIGN(*stride
/ 2, 16);
258 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP
:
259 case HAL_PIXEL_FORMAT_YCbCr_420_SP
:
260 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED
:
262 size_t chroma_vstride
= ALIGN(h
/ 2, 32);
263 luma_vstride
= ALIGN(h
, 32);
264 luma_size
= luma_vstride
* *stride
;
265 chroma_size
= chroma_vstride
* *stride
;
269 case HAL_PIXEL_FORMAT_YV12
:
270 case HAL_PIXEL_FORMAT_YCrCb_420_SP
:
271 return gralloc_alloc_framework_yuv(ionfd
, w
, h
, format
, usage
,
272 ion_flags
, hnd
, stride
);
273 case HAL_PIXEL_FORMAT_YCbCr_422_I
:
276 luma_size
= luma_vstride
* *stride
* 2;
282 ALOGE("invalid yuv format %d\n", format
);
286 if (usage
& GRALLOC_USAGE_PROTECTED
)
287 ion_flags
|= ION_EXYNOS_MFC_OUTPUT_MASK
;
289 err
= ion_alloc_fd(ionfd
, luma_size
, 0, heap_mask
, ion_flags
, &fd
);
293 *hnd
= new private_handle_t(fd
, luma_size
, usage
, w
, h
,
294 format
, *stride
, luma_vstride
);
296 err
= ion_alloc_fd(ionfd
, chroma_size
, 0, heap_mask
, ion_flags
, &fd1
);
300 err
= ion_alloc_fd(ionfd
, chroma_size
, 0, heap_mask
, ion_flags
, &fd2
);
304 *hnd
= new private_handle_t(fd
, fd1
, fd2
, luma_size
, usage
, w
, h
,
305 format
, *stride
, luma_vstride
);
307 *hnd
= new private_handle_t(fd
, fd1
, luma_size
, usage
, w
, h
, format
,
308 *stride
, luma_vstride
);
311 // Set chroma & gamut fields
313 if (usage
& GRALLOC_USAGE_PRIVATE_CHROMA
) {
314 (*hnd
)->chroma
= HAL_PIXEL_CHROMA_BT601_8
;
315 (*hnd
)->gamut
= HAL_PIXEL_GAMUT_NARROW_8
;
317 (*hnd
)->chroma
= HAL_PIXEL_CHROMA_BT709_8
;
318 (*hnd
)->gamut
= HAL_PIXEL_GAMUT_WIDE_8
;
330 static int gralloc_alloc(alloc_device_t
* dev
,
331 int w
, int h
, int format
, int usage
,
332 buffer_handle_t
* pHandle
, int* pStride
)
336 unsigned int ion_flags
= 0;
337 private_handle_t
*hnd
= NULL
;
339 if (!pHandle
|| !pStride
)
342 if( (usage
& GRALLOC_USAGE_SW_READ_MASK
) == GRALLOC_USAGE_SW_READ_OFTEN
)
343 ion_flags
= ION_FLAG_CACHED
| ION_FLAG_CACHED_NEEDS_SYNC
;
345 private_module_t
* m
= reinterpret_cast<private_module_t
*>
346 (dev
->common
.module
);
347 gralloc_module_t
* module
= reinterpret_cast<gralloc_module_t
*>
348 (dev
->common
.module
);
350 err
= gralloc_alloc_rgb(m
->ionfd
, w
, h
, format
, usage
, ion_flags
, &hnd
,
353 err
= gralloc_alloc_yuv(m
->ionfd
, w
, h
, format
, usage
, ion_flags
,
358 err
= gralloc_register_buffer(module
, hnd
);
376 static int gralloc_free(alloc_device_t
* dev
,
377 buffer_handle_t handle
)
379 if (private_handle_t::validate(handle
) < 0)
382 private_handle_t
const* hnd
= reinterpret_cast<private_handle_t
const*>(handle
);
383 gralloc_module_t
* module
= reinterpret_cast<gralloc_module_t
*>(
386 gralloc_unregister_buffer(module
, hnd
);
398 /*****************************************************************************/
400 static int gralloc_close(struct hw_device_t
*dev
)
402 gralloc_context_t
* ctx
= reinterpret_cast<gralloc_context_t
*>(dev
);
404 private_module_t
*p
= reinterpret_cast<private_module_t
*>(ctx
->device
.common
.module
);
405 pthread_mutex_lock(&p
->lock
);
406 LOG_ALWAYS_FATAL_IF(!p
->refcount
);
410 pthread_mutex_unlock(&p
->lock
);
412 /* TODO: keep a list of all buffer_handle_t created, and free them
420 int gralloc_device_open(const hw_module_t
* module
, const char* name
,
421 hw_device_t
** device
)
423 int status
= -EINVAL
;
424 if (!strcmp(name
, GRALLOC_HARDWARE_GPU0
)) {
425 gralloc_context_t
*dev
;
426 dev
= (gralloc_context_t
*)malloc(sizeof(*dev
));
428 /* initialize our state here */
429 memset(dev
, 0, sizeof(*dev
));
431 /* initialize the procs */
432 dev
->device
.common
.tag
= HARDWARE_DEVICE_TAG
;
433 dev
->device
.common
.version
= 0;
434 dev
->device
.common
.module
= const_cast<hw_module_t
*>(module
);
435 dev
->device
.common
.close
= gralloc_close
;
437 dev
->device
.alloc
= gralloc_alloc
;
438 dev
->device
.free
= gralloc_free
;
440 private_module_t
*p
= reinterpret_cast<private_module_t
*>(dev
->device
.common
.module
);
441 pthread_mutex_lock(&p
->lock
);
443 p
->ionfd
= ion_open();
445 pthread_mutex_unlock(&p
->lock
);
447 *device
= &dev
->device
.common
;
450 status
= fb_device_open(module
, name
, device
);