GUI显示系统之SurfaceFlinger_笔记

转载自 From LXS. http://blog.csdn.net/uiop78uiop78/

声明:本学习笔记来源是  http://blog.csdn.net/xuesen_lin/article/details/8954508 (林学森的csdn),本笔记仅供我个人总结和学习备用。


1. Gralloc与Framebuffer

Gralloc是一个模块,此模块负责gralloc和frambuffer两个设备,分别对应 gpu0和fb*,gpu0负责图形缓冲区的分配和释放,fb就是主屏幕。   

  frambuffer提供的设备文件节点是/gaphics/fb*,理论上支持多个屏幕显示,fb0为主显示屏。

Gralloc模块是由FramebufferNativeWindown在构造时加载的,其中 grDev和fbDev成员变量来管理gralloc和fb设备,在其构造函数中这两个设备分别用 gralloc_open(GRALLOC_HARDWARE_GPU0)和frambuffer_open(GRALLOC_HARDWARE_FB0)函数打开。然后调用到module_method的open函数来调用我们厂商根据各自平台实现的fb和gralloc的打开关闭和管理等函数指针。

static struct hw_module_methods_t gralloc_module_methods =
{
    .open = gralloc_device_open  //本函数内部是有厂商自己实现
};
<pre name="code" class="cpp">int gralloc_device_open(const hw_module_t* module, const char* name,hw_device_t** device)
{
    if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {//打开gralloc设备
           dev->device.alloc = gralloc_alloc;
           dev->device.free = gralloc_free;
    } else{
          fb_device_open(module, name, device);//否则就是fb设备
    }
    return status;
}

 
/*hardware/libhardware/modules/gralloc/Framebuffer.cpp*/
int fb_device_open(hw_module_t const* module, const char* name,hw_device_t** device)
{
    int status = -EINVAL;
    if (!strcmp(name,GRALLOC_HARDWARE_FB0)) {//设备名是否正确
        fb_context_t *dev =(fb_context_t*)malloc(sizeof(*dev));//分配hw_device_t空间,这是一个“壳”
        memset(dev, 0,sizeof(*dev));//初始化,良好的编程习惯
                   …
       dev->device.common.close = fb_close;//这几个接口是fb设备的核心
       dev->device.setSwapInterval = fb_setSwapInterval;
        dev->device.post          = fb_post;
                   …
        private_module_t* m =(private_module_t*)module;
        status = mapFrameBuffer(m);//内存映射,以及参数配置
        if (status >= 0) {
            …
            *device =&dev->device.common;//“壳”和“核心”的关系
        }
    }
    return status;
}

一个标准的fb设备通常要提供如下的函数实现:

Ø  int(*post)(struct framebuffer_device_t* dev, buffer_handle_t buffer);

        将buffer数据post到显示屏上。要求buffer必须与屏幕尺寸一致,并且没有被locked。这样的话buffer内容将在下一次VSYNC中被显示出来

Ø  int(*setSwapInterval)(struct framebuffer_device_t* window, int interval);

       设置两个缓冲区交换的时间间隔

Ø  int(*setUpdateRect)(struct framebuffer_device_t* window, int left, int top, int width, int height);

        设置刷新区域,需要framebuffer驱动支持“update-on-demand”。也就是说在这个区域外的数据很可能被认为无效




2. Android中的本地窗口(NativeWindow)

 至少需要两种本地窗口:

Ø  面向管理者(SurfaceFlinger) : FramebufferNativeWindow

      既然SurfaceFlinger扮演了系统中所有UI界面的管理者,那么它需要直接或间接地持有“本地窗口”

Ø  面向应用程序 : SurfaceTextureClient

  系统中存在多个应用程序时,从内存中为它们每个分配缓冲区空间,这样保证它们都获得一个本地窗口;

SufaceFlinger会手机所有程序的显示需求,然后对它们做统一的图像混合操作,再输出到自己的本地窗口(这种窗口是能直接显示在终端屏幕上的——它使用了帧缓冲区)。

这些本地窗口都可以与OPENGL ES绑定,使用OPENGL ES来完成复杂的界面渲染。

不论哪种本地窗口,都必须要与NativeWindowType保持一致,否则就无法正常使用EGL了/*frameworks/native/opengl/include/egl/Eglplatform.h*/,Android平台下使用的是ANativeWindow指针/*system/core/include/system/Window.h*/

ANativeWindow结构体中:

setSwapInterval                     

设置交换间隔时间,后面我们会讲解swap的作用

dequeueBuffer

EGL通过这个接口来申请一个buffer。以前面我们所举的例子来说,两个本地窗口所提供的buffer分别来自于帧缓冲区和内存空间。单词“dequeue”的字面意思是“出队列”,这从侧面告诉我们,一个Window所包含的buffer很可能不只一份

lockBuffer

申请到的buffer并没有被锁定,这种情况下是不允许我们去修改其中的内容的。所以我们必须要先调用lockBuffer来获得一个锁

queueBuffer

当EGL对一块buffer渲染完成后,它调用这个接口来unlock和post buffer

query

用于向本地窗口咨询相关信息

ANativeWindow像是一份“协议”,规定了一个本地窗口的形态和功能,在FramebufferNativeWindow构造函数中我们还要根据FramebufferNativeWindow的实现来填充ANativeWindow中的“协议”:

        FramebufferNativeWindow继承ANativeWindow,会将其成员函数填充到ANativeWindow中的函数指针中,比如,

        ANativeWindow::setSwapInterval = setSwapInterval;

        ANativeWindow::dequeueBuffer = dequeueBuffer;

这样子OpenGL ES才能通过一个ANativeWindow来正确地与本地窗口建立连接。


FramebufferNativeWindow构造函数中grDev->alloc 申请的usage类型是GRALLOC_USAGE_HW_FB,表示缓冲区用于framebuffer设备


针对应用程序端的本地窗口是SurfaceTextureClient,和FramebufferNativeWindow一样,它必须继承ANativeWindow,SurfaceTextureClient是面向Android系统中所有UI应用程序的,也就是说它承担着单个应用进程中的UI显示需求。SurfaceTextureClient提供给上层(主要是java层)绘制图像的“画板”,然后SurfaceFlinger需要收集系统中所有应用程序绘制的图像数据,然后集中显示到物理屏幕上。


为应用程序服务的本地窗口SurfaceTextureClient在server端的实现是BufferQueue。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值