前面介绍了比较直观的framebuffer模块(负责把有一个内存地址ADDR的内容显示到屏上),hwc模块(叠加器,负责把surfaceFlinger送来的各种输入layer叠加到显存上),接下来开始介绍surfaceFLinger这个android显示相关最核心的系统服务。

文章目录

  • 一、SurfaceFlinger定义与概念
    • Surface定义---供生产方与消耗方交换图形buf缓冲区
    • SurfaceFlinger定义---统一管理surface的显示系统服务
    • SurfaceFlinger的基础框架client&&service(待更新)
  • 二、SurfaceFlinger关键设计分析
    • BufferQueue---基础buffer轮转组件
    • Vsync---基于显示刷新事件的过程同步控制
    • Triple Buffer---三重缓存机制 提高对性能波动的容忍度
    • fence机制---提前送帧设计降低buffer轮转延时
    • hwcomposer---多图层硬件叠加器封装
    • overlay---独立与主图层的单独显示层(依赖硬件,常作视频显示)
  • 三、SurfaceFlinger关键流程分析(待更新)
    • 1、从surface的resize用例关键流程分析
      • 前期准备,启动binder线程池(支持client和service通信)
      • 应用创建client,通过client创建surface(service端创建layer)
      • 应用程序对窗口的控制和绘制surface提交
    • 2、从SurfaceFlinger关键处理流程分析
      • 收到surface的signal信号等待Vsync叠加
  • 四、SurfaceFlinger的典型android通路(待更新)
  • 五、dumpsys SurfaceFlinger调试命令
  • 参考

一、SurfaceFlinger定义与概念

Surface定义—供生产方与消耗方交换图形buf缓冲区

要理解SurfaceFlinger,当然先要理解surface这一基础概念。应用的每个 Window 会关联一个 Surface,Surface会关联真正的Graphic Buffer缓冲队列。android绘图的API很多,比如2D的绘图skia;3D的绘图OpenGL,Vulkan等,绘制到surface上。

SurfaceFlinger定义—统一管理surface的显示系统服务

SurfaceFlinger是一个系统服务,要实现了Surface的建立、控制、管理,创建display显示通道,控制GraphicBuffer申请轮转,基于Vsync事件同步 管理需要参与显示的surface给HWComposer硬件叠加器叠加显示到屏幕上。

SurfaceFlinger的基础框架client&&service(待更新)

二、SurfaceFlinger关键设计分析

BufferQueue—基础buffer轮转组件

BufferQueues 是 Android 图形组件之间的粘合剂。它们是一对队列,可以管理buffer从生产方到消耗方的固定周期。BufferQueue 是将缓冲区池与队列相结合的数据结构,用 Binder IPC 在进程之间传递buffer(生产者消费者可在不同进程)。图像生产方的一些示例包括由相机 HAL 或 OpenGL ES 游戏生成的相机预览。图像消耗方的一些示例包括 SurfaceFlinger 或显示 OpenGL ES 流的另一个应用,如显示相机取景器的相机应用。

Vsync—基于显示刷新事件的过程同步控制

基于Vsync信号(垂直时序刷新信号,可以简单理解为屏幕每刷新一帧上报一个事件,比如60HZ刷新的屏幕,vsync上报就是每秒均衡的60次) 同步显示buffer处理流水线(包括 渲染绘制、合成、显示),让绘制叠加显示更有序匹配
SurfaceFlinger 通过调用 setVsyncEnabled 来控制 HWC 是否生成 VSYNC 事件。在 VSYNC 事件中,屏幕开始显示帧 N,而 SurfaceFlinger 开始为帧 N+1 合成,应用处理等待的输入并绘制生成帧 N+2
CPU开始处理第1帧的纹理,处理完成之后GPU进行合成,在第1帧到来时候,显示屏显示第1帧,接着同步的CPU可以开始处理第2帧的纹理,GPU在CPU处理完成之后栅格化合成,在第2个垂直同步信号到来的时候,显示屏可以展示第2帧。如下图为 不基于vsync和基于vsync的两种方式;

Triple Buffer—三重缓存机制 提高对性能波动的容忍度

除了Vsync的机制,Android还使用了多级缓冲的手段以优化UI流程度。下图分别为 双buffer和三buffer缓存面临 性能波动的情况下 平滑处理情况。


可见 由于资源抢占等性能问题导致某一帧GPU掉链子,vsync信号到来时buffer B的数据还没准备好,而此时Display又在显示buffer A的数据,双buffer条件下 导致 后面CPU/GPU没有新的buffer着手准备数据,空白时间无事可做,后面Jank频出,如果三buffer情况,CPU/GPU可以用C buffer开始准备数据。

fence机制—提前送帧设计降低buffer轮转延时

fence:android4.4开始引入的一种资源同步机制,主要用于处理跨硬件场景,如CPU、GPU、HWC之间的buffer资源同步。简单来说,就是 生产者 把buffer 在生产完成之前 带上一个fence节点 提前送出去(常叫aquire fence),消费者需要使用的时候 通过fence去查看是否生产完 来决定使用。或者 消费者 收到buffer后准备使用前就 把buffer 带上一个fence(常叫release fence)还给生产者,生产者需要再绘制时 通过fence去查看 是否消费完成。核心就是省去buffer中间调度传递的时间; android中基本fence是使用图如下:
参考博文:https://blog.csdn.net/runafterhit/article/details/89293013

hwcomposer—多图层硬件叠加器封装

为了解放GPU的绘制能力,很多芯片厂家会提供硬件叠加合成,如果硬件叠加器支持的场景都可以走硬件叠加,解放GPU的绘制能力专心绘制,提升的渲染性能同时还能大幅度的降低功耗(GPU强绘制,叠加搬移并不擅长,高功耗)。

参考博文:https://blog.csdn.net/runafterhit/article/details/118884165

overlay—独立与主图层的单独显示层(依赖硬件,常作视频显示)

Overlay(覆盖)是一种数字视频的显示技术,它允许数字信号不经过显示芯片(GPU)处理,而直接通过显存输出到显示器屏幕上。Overlay显示模式最大的用途在于优化视频播放。很多芯片厂商在适配底层显示系统的时候,都会针对 播放视频内容做效果优化的视频独立通路得到更好的效果。
这个很好理解,视频的采集-编码-压缩传输-解码-调优显示 和 图形 和 绘制渲染 本身可以说是两个领域,各自有各自的技术衍生发展方向。一般基于android的TV和机顶盒都会支持overlay显示这种方式。

三、SurfaceFlinger关键流程分析(待更新)

1、从surface的resize用例关键流程分析

前期准备,启动binder线程池(支持client和service通信)

在关联SurfaceFlinger之前,先要准备好通信环境(client和service是基于binder通信的)。首先获取ProcessState对象。调用startThreadPool方法启动进程内的binder线程池。

// set up the thread-pool
sp<ProcessState> proc(ProcessState::self());
ProcessState::self()->startThreadPool();

应用创建client,通过client创建surface(service端创建layer)

SurfaceFlinger是一个系统服务,应用通过client客户端连接service服务,应用 用client创建surface(对应一个surfaceContrl来管理),服务端创建layer来表示应用的surface,layer中通过BufferQueue管理 生产消费模型,BufferQueue中包含BufferSlot数组 关联 真正的 绘制内存;

sp<SurfaceComposerClient> client = new SurfaceComposerClient(); // 创建与service关联的client
sp<SurfaceControl> surfaceControl = // 创建一个surface-通过surfaceContrl管理client->createSurface(String8("resize"), 160, 240, PIXEL_FORMAT_RGB_565, 0);
sp<Surface> surface = surfaceControl->getSurface(); // 通过surfaceContrl获取surface

应用程序对窗口的控制和绘制surface提交

拿到surface之后就可以往上面开始绘制了,为了让画面能够显示出来,还需要设置zorder,也就是Z序,表示在图形叠加过程中的层位置,z越大越在顶层(可通过dumpsys看每个layer的z=xxx来看其大小)

// 设置surface的zorder 让他能够显示
SurfaceComposerClient::openGlobalTransaction();
surfaceControl->setLayer(100000);
SurfaceComposerClient::closeGlobalTransaction();

设置了Z序列后,图层可以显示出来了,通过surface->lock锁定取出outBuffer(锁定的含义就是此时这个buffer正在被使用,不能参与轮转合成),进行绘制(这里直接通过cpu进行memset,由于前面格式是RGB565,系统大端,16bit高位是表示blue,是一个蓝色的区域),绘制完成后unlockAndPost()解锁送显示(此动作会把buffer送到缓存区,并最后触发一个signalLayerUpdate通知SurfaceFlinger合并输出)。

ANativeWindow_Buffer outBuffer;
surface->lock(&outBuffer, NULL);
ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
android_memset16((uint16_t*)outBuffer.bits, 0xF800, bpr*outBuffer.height);
surface->unlockAndPost();

绘制完成buffer提交显示后,还可以改变surface属性调整显示,比如setSize改变其大小;(这里是通过消息事件通知surfaceFlinger调整大小,没有改变buffer内容,因此不用lock重新绘制)

SurfaceComposerClient::openGlobalTransaction();
surfaceControl->setSize(320, 240);
SurfaceComposerClient::closeGlobalTransaction();

2、从SurfaceFlinger关键处理流程分析

收到surface的signal信号等待Vsync叠加

当APP绘制完成buffer后,unlockAndPost()最终会发送signal到SurfaceFlinger的消息队列MessageQueue,SurfaceFlinger会等待Vsync信号(垂直时序信号,每一帧显示画面一次事件)到来后进行 事件处理开始同步合成显示
onMessageReceived主要收两类消息:1、INVALIDATE 无效重新绘制事件(触发检测是否需要重新绘制,需要就触发refresh事件); 2、REFRESH 刷新显示事件;

refresh核心流程如下:遍历参与显示的layer标记-收集需要真正显示的layer-设置HWC叠加器-执行硬件/软件叠加 显示工作

void SurfaceFlinger::handleMessageRefresh() {// ...略...// 1、按Zorder遍历每一个参与显示的layer,判断是否需要刷新并标记(发送signalLayerUpdate事件);preComposition(refreshStartTime);// 2、把全部layer按Z序取出过滤,保留在屏幕上非透明区域图层layersSortedByZ收集rebuildLayerStacks();// 3、设置HWComposer,将Layer中的信息传递给HWC叠加器 进行preparesetUpHWComposer();// 4、遍历全部显示通道,执行叠加显示主体presentAndGetReleaseFences叠加显示获取取releaseFence,doComposition();// 5、善后工作postComposition(refreshStartTime);// ...略...
}

四、SurfaceFlinger的典型android通路(待更新)

五、dumpsys SurfaceFlinger调试命令

通过dumpsys SurfaceFlinger可以查看surfaceFlinger相关系统信息,比如 系统中的layer信息,hwc合成信息,buffer信息 等等;
参考博文:https://blog.csdn.net/feifei_csdn/article/details/81703778

参考

官方文档:https://source.android.google.cn/devices/graphics
老罗:https://blog.csdn.net/luoshengyang/article/details/7846923
https://gitee.com/ldkxingzhe/ldk/blob/master/Android_Service_SurfaceFlinger.org
https://blog.csdn.net/freekiteyu/article/details/79483406
http://www.wowotech.net/graphic_subsystem/graphic_subsystem_overview.html
https://blog.csdn.net/haigand/article/details/90489336
https://zhuanlan.zhihu.com/p/62813895
https://blog.csdn.net/rabbyheathy/article/details/103748551
http://www.kokojia.com/article/18618.html
https://blog.csdn.net/feifei_csdn/article/details/81703778
https://www.imooc.com/article/279279

android多媒体框架介绍(五)显示图形系统之SurfaceFlinger初步介绍相关推荐

  1. android多媒体框架学习 详解

    原址 一:多媒体框架概述 jellybean 的多媒体跟以前的版本,通过对比没啥变化,最大的变化是google终于舍得给multimedia建个独立的git了(framework/av),等你好久了! ...

  2. android多媒体框架学习 详解 最新版本

    一:多媒体框架概述 jellybean 的多媒体跟以前的版本,通过对比没啥变化,最大的变化是google终于舍得给multimedia建个独立的git了(framework/av),等你好久了!也体现 ...

  3. Android 多媒体框架 OpenCore(PacketVideo)介绍

    OpenCore的另外一个常用的称呼是PacketVideo,它是Android的多媒体核心.PacketVideo是一家公司的名称,OpenCore是这套多媒体框架的软件层的名称.在Android的 ...

  4. android 多媒体框架服务之StagefrightPlayer和OMXCodec实现原理学习

    https://www.2cto.com/kf/201608/542839.html 1. 框架结构 1.1StageFright和openCore和NuPlayer的关系 上图可知,stagefri ...

  5. android多媒体框架介绍(四)显示图形系统之hwc叠加器

    前面我们讲解了整个android图形显示系统的主要模块关系,和framebuffer,接下来我们讲解hwc叠加模块. Android7.0提供了HWC和HWC2两个版本,到了Android8.0就都默 ...

  6. Android 开源框架Universal-Image-Loader全然解析(一)--- 基本介绍及使用

    转载请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/26810303).请尊重他人的辛勤劳动成果,谢谢! 大家好! ...

  7. Android多媒体框架之MediaMetadataRetriever

    前言 MediaMetadataRetriever是Android原生提供的获取音视频文件信息的一个类,我们可以通过这个类的相关方法获取一些基本信息,如视频时长.宽高.帧率.方向.某一帧的图片等. 初 ...

  8. Android 开源框架Universal-Image-Loader完全解析(一)--- 基本介绍及使用

      转载请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/26810303),请尊重他人的辛勤劳动成果,谢谢! 大家 ...

  9. android多媒体(十五)

    介绍App开发常见的多媒体技术,主要包括如何使用各种图像控件实现自定义相册.如何使用几种主要的音频播放技术.如何使用几种常见的视频播放控件.如何在屏幕上划分多窗口进行特殊处理. 一.相    册 介绍 ...

最新文章

  1. HTML基础部分(2)表格
  2. python属性和局部变量_python类与对象1
  3. 神策数据杨宁:财富管理转型趋势下的精细化运营
  4. linux按时间升序排列文件,Linux展示以时间生升序显示文件
  5. java byte转换成string_Java byte []到/从String转换
  6. 饶毅教授纵论“科学家的九个层次”;看到最后一句,终于绷不住了
  7. ZZULIOJ 1159: 最大的两个数(指针专题)
  8. VMware NSX-T Data Center 2.5 下载(转载)
  9. FastSpring.NET V2.05 final 发布[集成Spring.net NHibernate Ajax]
  10. 如何让Tuxera NTFS总是挂载不干净的卷?
  11. bash shell之数组使用
  12. (十:2020.08.28)CVPR 2018 追踪之论文纲要(译)
  13. 浏览器对象模型BOM、文档对象模型DOM
  14. IDEA多module的项目共享配置文件的处理
  15. 测量平差中必要观测数的确定
  16. oracle 会话数上不去_(一)UDS诊断服务中的诊断会话控制(DiagnosticSessionControl,0x10)...
  17. 杀戮空间2服务器协议,杀戮空间2服务器设置
  18. 前端静态资源缓存最优解以及max-age的陷阱
  19. Andersen Global在南非拓展业务
  20. 揭秘开心农场开发团队:初期仅15万元创业基金

热门文章

  1. 百度服务器最近不稳定,分析最近百度快照回档的原因
  2. 点光源对焦模糊,将图片导入DP工具,观察PL_STATE
  3. 艺龙首页-手风琴效果
  4. 自动切换IE代理设置: 简单使用IE自动配置脚本
  5. イルルゥ / 伊露露
  6. Word: 一行未满便换行
  7. 【JVM学习笔记1】JVM与Java体系结构
  8. Windows 安装 Podman
  9. linux netlink 机制,Linux Netlink 编程
  10. php input onclick,html中onclick事件属性定义与用法