下面是分配内存最核心的函数:
static int gralloc_alloc(alloc_device_t* dev,
int w, int h, int format, int usage,
buffer_handle_t* pHandle, int* pStride)
{
if (!pHandle || !pStride)
return -EINVAL;
size_t size, stride;
int align = 4;
int bpp = 0;
switch (format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
bpp = 4;
break;
case HAL_PIXEL_FORMAT_RGB_888:
bpp = 3;
break;
case HAL_PIXEL_FORMAT_RGB_565:
case HAL_PIXEL_FORMAT_RAW_SENSOR:
bpp = 2;
break;
default:
return -EINVAL;
}
size_t bpr = (w*bpp + (align-1)) & ~(align-1);
size = bpr * h;
stride = bpr / bpp;
int err;
if (usage & GRALLOC_USAGE_HW_FB) {
err = gralloc_alloc_framebuffer(dev, size, usage, pHandle); //申请图形缓冲区,用来render
} else {
err = gralloc_alloc_buffer(dev, size, usage, pHandle); //申请帧缓冲区,用来显示
}
if (err < 0) {
return err;
}
*pStride = stride;
return 0;
}
{
/* buffer is never read in software */
GRALLOC_USAGE_SW_READ_NEVER = 0x00000000,
/* buffer is rarely read in software */
GRALLOC_USAGE_SW_READ_RARELY = 0x00000002,
/* buffer is often read in software */
GRALLOC_USAGE_SW_READ_OFTEN = 0x00000003,
/* mask for the software read values */
GRALLOC_USAGE_SW_READ_MASK = 0x0000000F,
/* buffer is never written in software */
GRALLOC_USAGE_SW_WRITE_NEVER = 0x00000000,
/* buffer is rarely written in software */
GRALLOC_USAGE_SW_WRITE_RARELY = 0x00000020,
/* buffer is often written in software */
GRALLOC_USAGE_SW_WRITE_OFTEN = 0x00000030,
/* mask for the software write values */
GRALLOC_USAGE_SW_WRITE_MASK = 0x000000F0,
/* buffer will be used as an OpenGL ES texture */
GRALLOC_USAGE_HW_TEXTURE = 0x00000100,
/* buffer will be used as an OpenGL ES render target */
GRALLOC_USAGE_HW_RENDER = 0x00000200,
/* buffer will be used by the 2D hardware blitter */
GRALLOC_USAGE_HW_2D = 0x00000400,
/* buffer will be used by the HWComposer HAL module */
GRALLOC_USAGE_HW_COMPOSER = 0x00000800,
/* buffer will be used with the framebuffer device */
GRALLOC_USAGE_HW_FB = 0x00001000,
/* buffer will be used with the HW video encoder */
GRALLOC_USAGE_HW_VIDEO_ENCODER = 0x00010000,
/* buffer will be written by the HW camera pipeline */
GRALLOC_USAGE_HW_CAMERA_WRITE = 0x00020000,
/* buffer will be read by the HW camera pipeline */
GRALLOC_USAGE_HW_CAMERA_READ = 0x00040000,
/* buffer will be used as part of zero-shutter-lag queue */
GRALLOC_USAGE_HW_CAMERA_ZSL = 0x00060000,
/* mask for the camera access values */
GRALLOC_USAGE_HW_CAMERA_MASK = 0x00060000,
/* mask for the software usage bit-mask */
GRALLOC_USAGE_HW_MASK = 0x00071F00,
/* buffer will be used as a RenderScript Allocation */
GRALLOC_USAGE_RENDERSCRIPT = 0x00100000,
GRALLOC_USAGE_HW_FIMC1 = 0x01000000,
GRALLOC_USAGE_HW_ION = 0x02000000,
GRALLOC_USAGE_YUV_ADDR = 0x04000000,
/* SEC Private usage , for Overlay path at HWC */
GRALLOC_USAGE_HWC_HWOVERLAY = 0x20000000,
/* buffer should be displayed full-screen on an external display when
* possible
*/
GRALLOC_USAGE_EXTERNAL_DISP = 0x00002000,
/* Must have a hardware-protected path to external display sink for
* this buffer. If a hardware-protected path is not available, then
* either don't composite only this buffer (preferred) to the
* external sink, or (less desirable) do not route the entire
* composition to the external sink.
*/
GRALLOC_USAGE_PROTECTED = 0x00004000,
/* implementation-specific private usage flags */
GRALLOC_USAGE_PRIVATE_0 = 0x10000000,
GRALLOC_USAGE_PRIVATE_1 = 0x20000000,
GRALLOC_USAGE_PRIVATE_2 = 0x40000000,
GRALLOC_USAGE_PRIVATE_3 = 0x80000000,
GRALLOC_USAGE_PRIVATE_MASK = 0xF0000000,
}
下面是framebuffer显示使用的函数
static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
{
if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
{
m->base.lock(&m->base, buffer, private_module_t::PRIV_USAGE_LOCKED_FOR_POST,
0, 0, m->info.xres, m->info.yres, NULL);
const size_t offset = hnd->base - m->framebuffer->base;
int interrupt;
m->info.activate = FB_ACTIVATE_VBL;
m->info.yoffset = offset / m->finfo.line_length;
#ifdef STANDARD_LINUX_SCREEN
#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
#define S3CFB_SET_VSYNC_INT _IOW('F', 206, unsigned int)
if (ioctl(m->framebuffer->fd, FBIOPAN_DISPLAY, &m->info) == -1)
{
AERR( "FBIOPAN_DISPLAY failed for fd: %d", m->framebuffer->fd );
m->base.unlock(&m->base, buffer);
return 0;
}
{
// enable VSYNC
interrupt = 1;
if(ioctl(m->framebuffer->fd, S3CFB_SET_VSYNC_INT, &interrupt) < 0)
{
AERR( "S3CFB_SET_VSYNC_INT enable failed for fd: %d", m->framebuffer->fd );
return 0;
}
// wait for VSYNC
#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE
gralloc_mali_vsync_report(MALI_VSYNC_EVENT_BEGIN_WAIT);
#endif
int crtc = 0;
if(ioctl(m->framebuffer->fd, FBIO_WAITFORVSYNC, &crtc) < 0)
{
AERR( "FBIO_WAITFORVSYNC failed for fd: %d", m->framebuffer->fd );
#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE
gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT);
#endif
return 0;
}
#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE
gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT);
#endif
// disable VSYNC
interrupt = 0;
if(ioctl(m->framebuffer->fd, S3CFB_SET_VSYNC_INT, &interrupt) < 0)
{
AERR( "S3CFB_SET_VSYNC_INT disable failed for fd: %d", m->framebuffer->fd );
return 0;
}
}
#else
/*Standard Android way*/
#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE
gralloc_mali_vsync_report(MALI_VSYNC_EVENT_BEGIN_WAIT);
#endif
if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1)
{
AERR( "FBIOPUT_VSCREENINFO failed for fd: %d", m->framebuffer->fd );
#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE
gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT);
#endif
m->base.unlock(&m->base, buffer);
return -errno;
}
#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE
gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT);
#endif
#endif
m->currentBuffer = buffer;
}
return 0;
}
注意:
这个函数只有在离线合成的方式下,由openGL调用eglSwapbuffer,才会被调用到。
参考:
http://blog.csdn.net/wan8180192/article/details/50269405
在线合成的方式下,会调用HWC->set 函数,即exynos4_set--->exynos4_post_fimd ---> window_pan_display最终显示
参考:
http://blog.csdn.net/wan8180192/article/details/50719123