android:flipinterval="30",[20100515]Android Gralloc HAL ——Framebuffer.cpp

博客详细解析了Android系统中Framebuffer设备驱动的工作流程,包括fb_device_open、mapFrameBufferLocked函数的实现,以及fb_setSwapInterval、fb_post等关键函数的作用。特别提到,fb_setSwapInterval函数在某些情况下可能无效,而fb_post函数则是核心,涉及到buffer的锁定和映射。文章还提及高通在局部刷新和不支持PAGE_FLIP情况下的特殊处理,通过msm_copy_buffer函数实现高效的数据传输。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Framebuffer.cpp就是以前的EGLdisplaysurface.cpp改进版

1、int fb_device_open(hw_module_t const* module, const char* name,

hw_device_t** device)

1)gralloc_open(module, &gralloc_device);

2)初始化fb_context_t(该结构继承framebuffer_device_t)

主要填充parent hw_device_t内容和两个重要函数

dev->device.setSwapInterval = fb_setSwapInterval;

dev->device.post            = fb_post;

3)mapFrameBuffer(m);-->mapFrameBufferLocked(module);

4)填充parent framebuffer_device_t结构体

2、int mapFrameBufferLocked(struct private_module_t* module)

1)打开framebuffer设备

2)get fb_fix_screeninfo and fb_var_screeninfo

3)refill fb_var_screeninfo

4)判断是否支持PAGE_FLIP

5)计算刷新率

6)打印gralloc信息

7)填充private_module_t

8)mmap the framebuffer

3、static int fb_setSwapInterval(struct framebuffer_device_t* dev,

int interval)

这个函数完全没用嘛,因为minSwapInterval=maxSwapInterval=1

4、static int fb_setUpdateRect(struct framebuffer_device_t* dev,

int l, int t, int w, int h)

局部刷新,默认不启用,MSM7K貌似启用了

5、static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)

最关键的函数

1)检查buffer是否合法

2)进行相应的类型转换

3)如果currentbuffer非空,unlokc

4-1)如果支持PAGE_FLIP

lock

ioctl

unlock

currentbuffer=buffer

重点看lock函数

m->base.lock(&m->base, buffer,

private_module_t::PRIV_USAGE_LOCKED_FOR_POST,

0, 0, m->info.xres, m->info.yres, NULL);

看参数,是没有vaddr的,lock时也不需要mmap操作。

4-2)如果不支持PAGE_FLIP

lock for read

lock for wrtie

memcpy

unlock

unlock

继续看其中一个lock

m->base.lock(&m->base, m->framebuffer,

GRALLOC_USAGE_SW_WRITE_RARELY,

0, 0, m->info.xres, m->info.yres,

&fb_vaddr);

看,usage被置位,有vaddr,需要进行mmap操作。

6、最后一个环节继续是喜闻乐见的高通干了啥节目

1)open中启用了局部刷新,不过也需要上层支持的

if (m->finfo.reserved[0] == 0x5444 &&

m->finfo.reserved[1] == 0x5055) {

dev->device.setUpdateRect = fb_setUpdateRect;

LOGD("UPDATE_ON_DEMAND supported");

}

2)貌似高通的MSM7K不支持PAGE_FLIP,但他绝不会傻到用memcpy来做,所以给个这个函数

/* Copy a pmem buffer to the framebuffer */

static void

msm_copy_buffer(buffer_handle_t handle, int fd, int width, int height,

int x, int y, int w, int h)

{

struct {

unsigned int count;

mdp_blit_req req;

} blit;

private_handle_t *priv = (private_handle_t*) handle;

memset(&blit, 0, sizeof(blit));

blit.count = 1;

blit.req.flags = 0;

blit.req.alpha = 0xff;

blit.req.transp_mask = 0xffffffff;

blit.req.src.width = width;

blit.req.src.height = height;

blit.req.src.offset = 0;

blit.req.src.memory_id = priv->fd;

blit.req.dst.width = width;

blit.req.dst.height = height;

blit.req.dst.offset = 0;

blit.req.dst.memory_id = fd;

blit.req.dst.format = MDP_RGB_565;

blit.req.src_rect.x = blit.req.dst_rect.x = x;

blit.req.src_rect.y = blit.req.dst_rect.y = y;

blit.req.src_rect.w = blit.req.dst_rect.w = w;

blit.req.src_rect.h = blit.req.dst_rect.h = h;

if (ioctl(fd, MSMFB_BLIT, &blit))

LOGE("MSMFB_BLIT failed = %d", -errno);

}

调用方法

//memcpy(fb_vaddr, buffer_vaddr, m->finfo.line_length * m->info.yres);

msm_copy_buffer(m->framebuffer, m->framebuffer->fd,

m->info.xres, m->info.yres,

m->info.xoffset, m->info.yoffset,

m->info.width, m->info.height);

说明:

1)看注释是用了PMEM,还么看到在哪申请的PMEM

2)看传参完全没有使用mmap获取的vaddr,而是将fd传入驱动,具体如何获取物理addr要仔细看msm的驱动(useful,高通真好)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值