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
:
161 if (format
!= HAL_PIXEL_FORMAT_BLOB
) {
162 bpr
= ALIGN(w
*bpp
, 16);
163 vstride
= ALIGN(h
, 16);
165 size
= bpr
* (vstride
+ 1);
167 size
= bpr
* vstride
;
169 size
= ALIGN(size
, PAGE_SIZE
);
172 if (usage
& GRALLOC_USAGE_PROTECTED
)
173 ion_flags
|= ION_EXYNOS_FIMD_VIDEO_MASK
;
175 err
= ion_alloc_fd(ionfd
, size
, 0, heap_mask
, ion_flags
,
177 *hnd
= new private_handle_t(fd
, size
, usage
, w
, h
, format
, *stride
,
183 static int gralloc_alloc_framework_yuv(int ionfd
, int w
, int h
, int format
,
184 int usage
, unsigned int ion_flags
,
185 private_handle_t
**hnd
, int *stride
)
191 case HAL_PIXEL_FORMAT_YV12
:
192 *stride
= ALIGN(w
, 16);
194 case HAL_PIXEL_FORMAT_YCrCb_420_SP
:
198 ALOGE("invalid yuv format %d\n", format
);
202 size
= *stride
* h
* 3 / 2;
203 err
= ion_alloc_fd(ionfd
, size
, 0, 1 << ION_HEAP_TYPE_SYSTEM
,
208 *hnd
= new private_handle_t(fd
, size
, usage
, w
, h
, format
, *stride
, h
);
212 static int gralloc_alloc_yuv(int ionfd
, int w
, int h
, int format
,
213 int usage
, unsigned int ion_flags
,
214 private_handle_t
**hnd
, int *stride
)
216 size_t luma_size
, chroma_size
;
217 int err
, planes
, fd
, fd1
, fd2
= 0;
219 unsigned int heap_mask
= _select_heap(usage
);
221 *stride
= ALIGN(w
, 16);
223 if (format
== HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED
) {
224 ALOGV("HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED : usage(%x), flags(%x)\n", usage
, ion_flags
);
225 if ((usage
& GRALLOC_USAGE_HW_CAMERA_ZSL
) == GRALLOC_USAGE_HW_CAMERA_ZSL
) {
226 format
= HAL_PIXEL_FORMAT_YCbCr_422_I
; // YUYV
227 } else if (usage
& GRALLOC_USAGE_HW_TEXTURE
) {
228 format
= HAL_PIXEL_FORMAT_EXYNOS_YV12
;
229 } else if (usage
& GRALLOC_USAGE_HW_VIDEO_ENCODER
) {
230 format
= HAL_PIXEL_FORMAT_YCbCr_420_SP
; // NV12M
234 case HAL_PIXEL_FORMAT_EXYNOS_YV12
:
236 luma_vstride
= ALIGN(h
, 16);
237 luma_size
= luma_vstride
* *stride
;
238 chroma_size
= (luma_vstride
/ 2) * ALIGN(*stride
/ 2, 16);
242 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP
:
243 case HAL_PIXEL_FORMAT_YCbCr_420_SP
:
244 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED
:
246 size_t chroma_vstride
= ALIGN(h
/ 2, 32);
247 luma_vstride
= ALIGN(h
, 32);
248 luma_size
= luma_vstride
* *stride
;
249 chroma_size
= chroma_vstride
* *stride
;
253 case HAL_PIXEL_FORMAT_YV12
:
254 case HAL_PIXEL_FORMAT_YCrCb_420_SP
:
255 return gralloc_alloc_framework_yuv(ionfd
, w
, h
, format
, usage
,
256 ion_flags
, hnd
, stride
);
257 case HAL_PIXEL_FORMAT_YCbCr_422_I
:
260 luma_size
= luma_vstride
* *stride
* 2;
266 ALOGE("invalid yuv format %d\n", format
);
270 if (usage
& GRALLOC_USAGE_PROTECTED
)
271 ion_flags
|= ION_EXYNOS_MFC_OUTPUT_MASK
;
273 err
= ion_alloc_fd(ionfd
, luma_size
, 0, heap_mask
, ion_flags
, &fd
);
277 *hnd
= new private_handle_t(fd
, luma_size
, usage
, w
, h
,
278 format
, *stride
, luma_vstride
);
280 err
= ion_alloc_fd(ionfd
, chroma_size
, 0, heap_mask
, ion_flags
, &fd1
);
284 err
= ion_alloc_fd(ionfd
, chroma_size
, 0, heap_mask
, ion_flags
, &fd2
);
288 *hnd
= new private_handle_t(fd
, fd1
, fd2
, luma_size
, usage
, w
, h
,
289 format
, *stride
, luma_vstride
);
291 *hnd
= new private_handle_t(fd
, fd1
, luma_size
, usage
, w
, h
, format
,
292 *stride
, luma_vstride
);
304 static int gralloc_alloc(alloc_device_t
* dev
,
305 int w
, int h
, int format
, int usage
,
306 buffer_handle_t
* pHandle
, int* pStride
)
310 unsigned int ion_flags
= 0;
311 private_handle_t
*hnd
= NULL
;
313 if (!pHandle
|| !pStride
)
316 if( (usage
& GRALLOC_USAGE_SW_READ_MASK
) == GRALLOC_USAGE_SW_READ_OFTEN
)
317 ion_flags
= ION_FLAG_CACHED
| ION_FLAG_CACHED_NEEDS_SYNC
;
319 private_module_t
* m
= reinterpret_cast<private_module_t
*>
320 (dev
->common
.module
);
321 gralloc_module_t
* module
= reinterpret_cast<gralloc_module_t
*>
322 (dev
->common
.module
);
324 err
= gralloc_alloc_rgb(m
->ionfd
, w
, h
, format
, usage
, ion_flags
, &hnd
,
327 err
= gralloc_alloc_yuv(m
->ionfd
, w
, h
, format
, usage
, ion_flags
,
332 err
= grallocMap(module
, hnd
);
351 static int gralloc_free(alloc_device_t
* dev
,
352 buffer_handle_t handle
)
354 if (private_handle_t::validate(handle
) < 0)
357 private_handle_t
const* hnd
= reinterpret_cast<private_handle_t
const*>(handle
);
358 gralloc_module_t
* module
= reinterpret_cast<gralloc_module_t
*>(
361 grallocUnmap(module
, const_cast<private_handle_t
*>(hnd
));
372 /*****************************************************************************/
374 static int gralloc_close(struct hw_device_t
*dev
)
376 gralloc_context_t
* ctx
= reinterpret_cast<gralloc_context_t
*>(dev
);
378 /* TODO: keep a list of all buffer_handle_t created, and free them
386 int gralloc_device_open(const hw_module_t
* module
, const char* name
,
387 hw_device_t
** device
)
389 int status
= -EINVAL
;
390 if (!strcmp(name
, GRALLOC_HARDWARE_GPU0
)) {
391 gralloc_context_t
*dev
;
392 dev
= (gralloc_context_t
*)malloc(sizeof(*dev
));
394 /* initialize our state here */
395 memset(dev
, 0, sizeof(*dev
));
397 /* initialize the procs */
398 dev
->device
.common
.tag
= HARDWARE_DEVICE_TAG
;
399 dev
->device
.common
.version
= 0;
400 dev
->device
.common
.module
= const_cast<hw_module_t
*>(module
);
401 dev
->device
.common
.close
= gralloc_close
;
403 dev
->device
.alloc
= gralloc_alloc
;
404 dev
->device
.free
= gralloc_free
;
406 private_module_t
*p
= reinterpret_cast<private_module_t
*>(dev
->device
.common
.module
);
407 p
->ionfd
= ion_open();
409 *device
= &dev
->device
.common
;
412 status
= fb_device_open(module
, name
, device
);