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相关介绍(一)相关推荐

  1. android fps 垂直同步,浅谈Android流畅度

    原标题:浅谈Android流畅度 哈哈 讲个故事 白 1 流畅度 关于流畅度谷歌官方给出的解释为:running at a consistent 60 frames per second, witho ...

  2. 浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路

    原文地址: http://blog.csdn.net/luoshengyang/article/details/6627260 在前面一篇文章浅谈Service Manager成为Android进程间 ...

  3. android分屏模式_浅谈 Android 7.0 多窗口分屏模式的实现

    从 Android 7.0 开始,Google 推出了一个名为"多窗口模式"的新功能,也就是我们常说的"分屏模式".那么,这个功能有什么用呢?作为开发者,我们又 ...

  4. 浅谈Android Architecture Components

    浅谈Android Architecture Components 浅谈Android Architecture Components 简介 Android Architecture Componen ...

  5. 浅谈Android中的MVP与动态代理的结合

    浅谈Android中的MVP与动态代理的结合 本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 在Android开发平台上接触MVP足足算起来大概已经有一个年头左右.从最开始到现在经 ...

  6. 浅谈Android引用计数(2)

    在浅谈Android引用计数(1)中讲了LightRefBase实现对象计数管理的原理,这篇文章将要分析重量级的引用基类:RefBase的实现和它的作用. 下面是RefBase和相关类的类图: 图中可 ...

  7. 浅谈Android onTouchEvent 与 onInterceptTouchEvent的区别详解

    浅谈Android onTouchEvent 与 onInterceptTouchEvent的区别详解 本篇文章小编为大家介绍,Android onTouchEvent 与 onInterceptTo ...

  8. android 存储空间监控,浅谈 Android 内存监控(中)

    前言 在上篇 浅谈 Android 内存监控(上) 中,我们聊了 LeakCanary,微信的 Matirx 和美团的 Probe,它们各自有不同的应用场景,例如,在开发测试环境,我们会偏向用 Lea ...

  9. 浅谈Android文件管理器的几种实现方式(原理篇)--对我有帮助

    转自 https://blog.csdn.net/weixin_33698823/article/details/87269955 浅谈Android文件管理器的几种实现方式 为了完成毕业设计,我花费 ...

最新文章

  1. 安装eclipse for c/c++环境
  2. C语言数组中找到第一个重复元素的算法(附完整源码)
  3. sql查询成绩最高分_sql查询各科成绩前三名----详述过程,思路清晰不烧脑!
  4. leetcode 25. Reverse Nodes in k-Group | 25. K 个一组翻转链表(Java)
  5. 一文讲清数据治理、数据管理、数据资产管理区别,数据专家必看
  6. [学习备忘录]编译gdb及gdbserver
  7. 【软件测试】Homework 1 Briefly describe an error
  8. 人工智能规模化落地还有哪些坑?阿里副总裁华先胜连麦详解!
  9. 用C# Regex类实现的一些常规输入判断
  10. sql常用语句集合(工作总结)
  11. 《Shell脚本学习指南》学习笔记
  12. 如何用UE4制作2D游戏文档(五)——战斗篇
  13. java定时任务 时间_java 定时任务的执行时间表示-
  14. Socket+华为云 实现广域网五子棋在线对战
  15. SNDACode介绍
  16. gee引擎修改UI界面图文教程
  17. 怎么调整图片大小会不变形?
  18. knex mysql 操作_mysql – 使用knex.js的我的Sql Alter表
  19. Count Inversion逆序对数问题
  20. 排序算法——简单选择排序(PythonJava)

热门文章

  1. linux字符终端浏览器-----Lynx
  2. 学习PHP 第七天 die() 函数,及Mysql的操作
  3. python 人像素描_基于python实现把图片转换成素描
  4. linux memwatch的内存检测-double-free
  5. 按键精灵9.5.1.11790秒速启动,多余元素全灭版
  6. 名片管理系统python详解_详解Python做一个名片管理系统
  7. HRSID舰船检测数据集标签格式转换,json转为xml
  8. VUE:自定义指令(directives )选项的用法
  9. 单行、多行 注释.HTML
  10. pip命令大全 含换源方法