Android系统的HAL ——Framebuffer.cpp

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,高通真好)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值