我是靠谱客的博主 无奈啤酒,最近开发中收集的这篇文章主要介绍浅谈Android之SurfaceFlinger相关介绍(一),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

SurfaceFlinger是GUI的核心,以系统服务的形式存在,负责将所有App的图形数据按照Z Order顺序混合并输出到FrameBuffer。


根据图中描述,从下到上依次介绍:

1)  这里的FrameBuffer指显示设备驱动和Gralloc帧缓冲区管理

2)  面向SurfaceFlinger的Native Window

3)  通过OpenGl ES图形库来处理图形数据后绘制到NativeWindow

4)  SurfaceFlinger,是一个binderservice,用于管理接收各个App传输过来的图形数据

5)  面向App应用窗口绘制的Native Window

6)  采用OpenGL ES或者SKIA将图形数据绘制到Native Window,对于普通应用开发人员来说,使用OpenGLES的门槛相对会比较高,所以SKIA第三方图形库基于OpenGL ES做了封装,提供更加简单的GUI接口供开发人员使用,SKIA是Android应用默认的图形引擎

 

下面重点介绍下上述第3步和第6步分别都提到的NativeWindow,既然叫窗口,说明它的输入端肯定是图形数据,输出到哪呢?可以是另外一个窗口的输入或者是Framebuffer,总之,对输入方来说,它只需要在NatvieWindow上输入图形数据,至于NativeWindow拿到数据后怎么处理的,它不需要关心。

 

Android系统为NativeWindow定义了基础结构ANativeWindow

struct ANativeWindow

{

   /* horizontal and vertical resolution in DPI */

    const float xdpi;

    const float ydpi;

    int     (*setSwapInterval)(struct ANativeWindow* window,

                int interval);

    int     (*dequeueBuffer_DEPRECATED)(struct ANativeWindow* window,

                struct ANativeWindowBuffer** buffer);

    int     (*lockBuffer_DEPRECATED)(struct ANativeWindow* window,

                struct ANativeWindowBuffer* buffer);

    int     (*queueBuffer_DEPRECATED)(struct ANativeWindow* window,

                struct ANativeWindowBuffer* buffer);

    int     (*query)(const struct ANativeWindow* window,

                int what, int* value);

    int     (*perform)(struct ANativeWindow* window,

                int operation, ... );

    int     (*cancelBuffer_DEPRECATED)(struct ANativeWindow* window,

                struct ANativeWindowBuffer* buffer);

    int     (*dequeueBuffer)(struct ANativeWindow* window,

                struct ANativeWindowBuffer** buffer, int* fenceFd);

    int     (*queueBuffer)(struct ANativeWindow* window,

                struct ANativeWindowBuffer* buffer, int fenceFd);

    int     (*cancelBuffer)(struct ANativeWindow* window,

                struct ANativeWindowBuffer* buffer, int fenceFd);

};

 

这个结构包含窗口最基本的宽高属性外,还定义了一大堆的函数指针,派生自ANavtiveWindow的类在构造时需要对各个函数指针进行赋值,说白了,就是将C++虚函数自己用C语言实现了一遍,这里把ANavtiveWindow

 

定义成结构体,不知道是历史遗留还是为了兼容性考虑,没去细究过。

 

ANativeWindow定义的函数名就可以看出,其对象的实现,一定要包含一个buffer queue,然后输入方调用dequeueBuffer获取buffer用于写入图形数据,结束后,调用queueBuffer入列。

 

App端对应的NativeWindow为Surface:

class Surface

    : public ANativeObjectBase<ANativeWindow, Surface, RefBase>

{

 

SurfaceFlinger端对应的NativeWindow为

class FramebufferNativeWindow

    : public ANativeObjectBase<

        ANativeWindow,

        FramebufferNativeWindow,

        LightRefBase<FramebufferNativeWindow> >

{

 

二者皆派生实现了ANativeWindow接口。

 

Surface向上提供buffer供App绘制图形界面,然后将图形数据传到SurfaceFlinger,SurfaceFlinger基于OpenGL ES将数据做混合操作后,输出到FramebufferNativeWindow并最终显示到屏幕上。

 

接下去重点介绍Surface跟SurfaceFlinger的交互

 

3.1 建立Surface和SurfaceFlinger连接

SurfaceFlinger服务主要实现了两个Binder service用于App连接:

1)  SurfaceFlinger
派生自BnSurfaceComposer,是SurfaceFlinger程序的主服务,在程序启动时就被构造并添加到servicemanager,相关代码在main_surfaceflinger.cpp,服务名为”SurfaceFlinger”

2) Client
派生自BnSurfaceComposerClient,在SurfaceFlinger:: createConnection的时候被创建,对应一个App Client连接

 

然后App启动后,需要通过如下操作和SurfaceFlinger建立会话:

1)通过servicemanager获取服务SurfaceFlinger的BpBinder,然后转换成BpSurfaceComposer

2)调用BpsurfaceComposer.createConnection建立连接,然后将返回的BpBinder转换成

  BpSurfaceComposeClient

 

Android接着提供了两个类用于简化App端的操作,主要包括:

1)ComposerService
 
 单列类,主要封装跟SurfaceFlinger的连接,在构造时调用connectlocaked成员函数连接
   “SurfaceFlinger”然后将BpSurfaceCompose保存到成员变量mComposerService

2)SurfaceComposerClient
 
  封装跟SurfaceFlinger建立会话连接的操作,在onFirstRef时调用createConnection建立
   会话并将BpSurfaceComposerClient保存到成员变量mClient

3)Composer
  
单列类,主要封装对Layer数据配置相关操作

 

接下去基于代码来分析,封装好后,App初始化连接很简单

sp<SurfaceComposerClient> session= new SurfaceComposerClient();

 

就一行代码,接着看构造函数

SurfaceComposerClient::SurfaceComposerClient()

    : mStatus(NO_INIT), mComposer(Composer::getInstance())

{

}

 

获取Composer单例对象并保存到mComposer,由于SurfaceComposerClient派生自RefBase

class SurfaceComposerClient : public RefBase

 

所以在其构造时,会调用incStrong第一次增加强引用计数,同时onFirstRef会被调用

void SurfaceComposerClient::onFirstRef() {

    sp<ISurfaceComposer> sm(ComposerService::getComposerService());

    if (sm != 0) {

        sp<ISurfaceComposerClient> conn = sm->createConnection();

        if (conn != 0) {

            mClient = conn;

            mStatus = NO_ERROR;

        }

    }

}

 

这个函数完成了连接的最终操作,先是通过ComposerService::getComposerService()生成
ComposeService单列,并调用其connectLocked连接SurfaceFlinger返回BpSurfaceComposer,

接着调用sm->createConnection()创建会话并保存到mClient。

接下来看看SurfaceFlinger.createConnection的代码

sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()

{

    sp<ISurfaceComposerClient> bclient;

    sp<Client> client(new Client(this));

    status_t err = client->initCheck();

    if (err == NO_ERROR) {

        bclient = client;

    }

    return bclient;

}

 

很简单,就是创建Client本地对象并返回

到这里,App跟SurfaceFlinger的初始化连接已经结束,接下去就是基于会话对象,创建绘图表面了

最后

以上就是无奈啤酒为你收集整理的浅谈Android之SurfaceFlinger相关介绍(一)的全部内容,希望文章能够帮你解决浅谈Android之SurfaceFlinger相关介绍(一)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部