必威体育Betway必威体育官网
当前位置:首页 > IT技术

浅谈Android之SurfaceFlinger相关介绍(一)

时间:2019-06-16 04:42:10来源:IT技术作者:seo实验室小编阅读:109次「手机版」
 

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的初始化连接已经结束,接下去就是基于会话对象,创建绘图表面了

相关阅读

怎么提高网站内容的相关度

很多seo新手经常会听到很多人强调网站内容相关性、网站垂直等之类的话语,网站内容相关性强弱也是决定关键词排名最重要的因素之一,

动态网页开发工具的介绍

  动态性网页页面的开发环境依据开发设计视频语音不一样而不一样,关键的方法取决于Python开发设计、JSP开发设计和ASP开发设计的

SEO外链推广,域名权重与相关性链接三者关系

在做SEO项目的时候,我们无法脱离与外链之间的关系,于是你总是面临这样的抉择,选择高权重的域名好,还是更多的创建相关性链接,也许它的

黑客十大常用工具介绍

黑客技术一度被认为是一个神秘的特有领域,随着技术的进步和领域环境的进步,它已经成为一种非常普遍的现象。黑客技术可以用于有害目

小米承认抄袭作品:删除相关内容并解雇相关员工

A5创业网(公众号:iadmin5)6月20日讯,据外媒报道称,小米承认抄袭作品,起因是西班牙小米网站滥用一位艺术家的作品来营销自己的产品,小米

分享到:

栏目导航

推荐阅读

热门阅读