Chinaunix首页 | 论坛 | 博客
  • 博客访问: 275702
  • 博文数量: 95
  • 博客积分: 2047
  • 博客等级: 大尉
  • 技术积分: 1022
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-14 16:18
文章分类

全部博文(95)

文章存档

2013年(1)

2011年(94)

我的朋友

分类: 嵌入式

2011-08-27 10:49:48

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



阅读(931) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~