概述
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相关介绍(一)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复