Android 显示系统

news/2024/7/8 5:23:02 标签: android, jni, wrapper, layer, 图形, buffer

Android display system introduce(Qualcomm 8x60 platform)(二、SW架构--1)
2010-12-31 11:17

一、Overview

    上图的原型取自高通的文档,由于原图无法描述现有的架构,我在原图的基础了做了些修改,主要是增加了 overlay 部分,另外其他部分根据现有的软件也做了些许改动。下面先对上图做个大概的介绍,后面会针对重点部分做详细的分析。

          最上面一层为应用程序,根据数据类型以及应用的不同可以分为几种。

第一种是最普通的应用,如 UI 界面的显示,这部分通常数据类型为 RGB 格式,数据无须再经过特殊的处理。该应用可以说遍布各个应用程序,几乎是实时存在的。

第二种是针对大块 YUV 数据的应用,如 camera 的 preview 、视频的播放等。该应用只针对特定的应用程序,开启时通过 overlay 直接把大块的 YUV 数据送到 kernel 显示。

         第三种其实和第一种类似,只不过由于应用的需求在显示之前需要对数据进行 2D 、 3D 的处理(使用 OpenGL 、 OpenVG 、 SVG 、 SKIA ),处理之后的流程和普通的显示就没什么差别了。一般在 Game 、地图、 Flash 等应用中会用到。

         应用之下是 framework ,其中最核心的就是 surfaceflinger 了,它为所有的应用程序的显示提供服务。由于 overlay 的接口挂在 surfaceflinger 里面(虽然 2 者在功能上不相干),所有使用 overlay 的 AP 需要通过 surfaceflinger 才可以访问 overlay ;另外,由于 surfaceflinger 需要使用 OpenGL 来 compose surface ,这也就是为什么 surfacelfinger 会调用 EGL wrapper 了, EGL wrapper 是对 Graphics HAL 的封装,除了 surfaceflinger 会调用它来 compose surface 外,上层的 2D 、 3D 应用也会调用它来进行图形处理。

         再下一层就是 HAL 了。

首先一个是 overlay 模块,对上提供 control channel 和 data channel ;对下则通过系统调用到 kernel 中的 MDP driver 。

再一个是 Gralloc 模块,注意它是和 overlay 并列的,它包含 2 个部分,一部分是为上层提供 pmem 的接口,另一部分则是对 framebuffer 进行刷新,这里的 framebuffer 其实就是 UI 的数据。由此可见上层有 2 个通道把显示数据送到 kernel 中, framebuffer 是传统的方式, overlay 是 android ( éclair 以后)后增加的。

          红色及右边部分是 OpenGL 的 HAL ,其中红色部分代表 HW solution ,高通提供的,这部分是没有源码的;右边的 software graphics library 是 SW solution , android 自身的。 HW 和 SW solution 可以同时存在也可以只有一个,后面会讲解。

         再往下就是 kernel 中的 driver 了,最主要的就是 fb 设备驱动以及 MDP4 overlay 的驱动,从硬件上看 2 者是并列的, framebuffer 最终也是通过 overlay 方式送入 MDP 的。 PMEM 和 KGSL 分别对应 kernel 中 pmem 的 driver ( /dev/pmem )和 Adreno220 的 driver 。

二、 Surfaceflinger 详解

1.overview

         Surfaceflinger 可以说是 Android 显示系统中的核心,在 android 当中它是一个 service , 提供系统 范围内的 surface composer  功能,它能够将各种应用 程序的 2D  、 3D surface  进行组合 ,合并最终得到的一个main surface 数据会送入显存。简单的说,surfaceflinger 就像是画布,它不关心画上去的内容,只是一味的执行合成功能,当然要根据画的位置、大小以及效果等参数。这很像Photoshop 中的各个Layer ,你可以在不同的layer 画任意的内容,每个layer 可以设置位置、大小、效果参数等,最终通过merge 合成一个layer

         从应用的角度看,每个应用程序可能对应一个或多个图形界面,每个界面可以看作是一个 surface 。首先每个 surface 有它的位置、大小、内容等元素,这些元素是可以随便变化的;另外不同的 surface 的位置会有重叠,会涉及到透明度等效果处理问题,这些都是通过 surfaceflinger 来完成的。当然了, surfaceflinger 担任是一个管理的职责,对于效果处理及合成它是通过 OpenGL 来做的,但前提是 surfaceflinger 需要把相关参数计算好,如重叠的位置等。

2. Surfaceflinger 在系统中的位置

Android 中的图形系统采用 Client/Server 架构。服务端负责 Surface 的合成等处理工作,客户端提供接口给上层操作自己的 Surface ,并向服务端发送消息完成实际处理工作 。 服务端  ( 即 SurfaceFlinger) 主要由 c++ 代码编写而成。客户端 端代码分为两部分,一部分是由 Java 提供的供应用使用的 api, 另一部分则是由 c++ 写成的底层实现。 如下图所示:

除去最上层的应用不算, surface 最上层的接口就是 java surface 了,文件路径如下:

frameworks/base/core/java/android/view/Surface.java ,该文件中的接口会被应用间接调用。

我们从 JNI 开始看, surface 的 JNI 文件路径如下:

frameworks/base/core/jni/android_view_Surface.cpp ,里面的接口大概分为 2 类,一类是负责管理 ibinder 通信的;另一类才是和显示控制相关的,第二类接口会直接调用 C 实现函数。

C 实现的文件路径如下:

frameworks/base/libs/ui/Surface.cpp

         我们来看看 JNI 中一些重要的接口:

         SurfaceSession_init :本接口只会被调用一次,负责创建 surfacecomposerclient ,主要为进程间通信做准备。对应的销毁函数有 SurfaceSession_destroy 和 SurfaceSession_kill 。

Surface_init 负责创建 surface ,最终会调用到 surfaceflinger 中的 createSurface ,对应的销毁函数有 Surface_destroy 和 Surface_release 。

Surface_lockCanvas :当对一个 surface 进行绘图之前要调用的,将该 surface 锁定,并且得到 surface 的 back buffer ,应用可以绘图。

Surface_unlockCanvasAndPost :当上层绘图完毕后,通过该函数通知底层 back buffer 已绘制完毕,可以更新到显存中。

Surface_setLayer/

Surface_setPosition/

Surface_setSize/

Surface_hide/

Surface_show/

Surface_setOrientation/

Surface_freeze/

Surface_unfreeze

Surface_setFlags/

Surface_setAlpha/

Surface_setMatrix: 设置 surface 的一些属性,如大小、位置、方位、截取范围, Z - order 等。其最终改变的都是 surface 的结构体属性,如下:

             uint32_t         what;// 哪一项属性改变

             int32_t          x;// 显示位置

             int32_t          y; // 显示位置

              uint32_t         z; //layer 顺序

             uint32_t         w;// 宽度

             uint32_t         h;// 高度

             float            alpha;// 透明度

             uint32_t         tint;// 色彩,未使用

             uint8_t          flags;//  标志

             uint8_t          mask;// 屏蔽命令

             uint8_t          reserved;

             matrix22_t       matrix;// 截取范围

             Region           transparentRegion;// 透明度设置

3. JNI 与 Surfaceflinger 的连接通讯

由于 JNI 及 C 函数实现与 surfaceflinger 不在同一个进程(一个在应用端-客户端,另一个在服务端), android 中通过 IPC ( Binder )方式实现进程间通信,下图来源于网上,不过我修改了里面的一些错误,它演示了 JNI 和 surfaceflinger 建立连接以及创建 surface 的流程。

JNI 和 C 函数实现我们看作是一个部分

这里看到一个比较重要的部分—— SurfaceComposerClient ,它是 surfacelinger 的客户端,通过它上层才可以和 surfaceflinger 使用 Binder 联系到一起, IsurfaceComposer 和 IsurfaceFlingerClient 都是用来实现 Binder 通信的。具体流程讲解   如下:

应用程序通过 JNI 接口 SurfaceSession_init 创建 SurfaceComposerClient 。通过 SurfaceComposerClient 函数中调用 getComposerService 获得 IsurfaceComposer 的 IBinder 对象,然后通过这个对象的 createConnection 又获得 IsurfaceFlingerClient 的 IBinder ,通过这个 IBinder , JNI 就可以调用 Surfaceflinger 中的接口了,如 createSurface 。由于采用 Binder 方式,代码部分稍微复杂一些,需要多看几遍才能把流程理清楚。

4. Surfaceflinger 与 libui 、 OpenGL 、显示设备的连接

这里不得不提到 android 对媒体框架中一个很重要的部分,那就是 libui ,它是一个框架库提供对底层操作的接口,比如会调用 Gralloc 、 Overlay 等 HAL 层接口。其他的库类继承的方式来调用 libui , surfaceflinger 就是这样和显示设备连接的(包括写显存和对 pmem 的使用)

Surfaceflinger 使用 OpenGL 来合成 surface ,所以 surfaceflinger 会直接调用到 OpenGL 的接口。

它们的架构如下:

这部分的流程比较复杂,主要是各个类的继承绕的比较多,我也是看了很多遍代码以及参考了些资料才理出来,下面来详细解释下这个图:

Surfaceflinger 在设计时考虑到支持多个屏幕,但目前的版本只支持一个,在 surfaceflinger 当中一个显示设备对应一个图中的 DisplayHardware , surfaceflinger 在初始化时会新建 Displayhardware (请参考 surfaceflinger.cpp 中的 readyToRun 函数),它完成的主要任务一个是建立 FramebufferNativeWindow ,确定数据输出设备接口(请参考 FramebufferNativeWindow.cpp ),再一个就是初始化 OpenGL ,并创建 main surface ,后续 surfaceflinger 中所有的 layer 最终都将被画到这个 main surface 上(请参考 displayhardware.cpp 的 init 函数)。这样 main surface 、 OpenGL 和 libui 中的 FramebufferNativeWindow 接口就绑定在一起。

由于 libEGL 负责所有 layer 的最终合成,所以最后数据送往 HAL 一定要 libEGL 来触发,对应的函数流程是:

postFrameBuffer(surfaceflinger) >Flip( displayhardware) >   eglSwapBuffers( OpenGL)->   queueBuffer( libui)->fbpost( gralloc)

另外图中的 GraphicBuffer 是 libui 中提供的对 pmem 的操作接口,它会直接调用 gralloc 模块。关于 OpenGL 和 Gralloc 后面会有单独的章节来介绍。


http://blog.csdn.net/fengkehuan/archive/2011/05/05/6397600.aspx


http://www.niftyadmin.cn/n/1720060.html

相关文章

并发编程之Android中AsyncTask使用详解(四),android开发计算器界面

android:layout_width“match_parent” android:layout_height“match_parent” android:paddingLeft"dimen/activity_horizontal_margin" android:paddingRight"dimen/activity_horizontal_margin" android:paddingTop"dimen/activity_vertical_marg…

机器视觉-相机镜头光源介绍及选型-7.镜头参数

镜头参数 1.镜头主要参数 相对孔径: 是指该镜头入射光孔直径D与焦距f之比,即:相对孔径=D / f 光圈系数:aperture scale 即光通量,用F表示,以镜头焦距f和通光孔径D的比值来衡量。 …

Android 2.3 Overlay

Overlay 调用框架 说明 : camera 通过 Surfaceflinger 中的 laybuffer.cpp 调用到 libui 里面, libui 通过标准的 hw_get_module() 获取 Overlay HAL 中各种函数指针;另一方面, surfaceFlinger 中的 DisplayHardware.cpp 也可以…

机器视觉-相机镜头光源介绍及选型-8.镜头选型

镜头选型 1.1.选择依据: 根据物体大小(视野),物距,精度确定相机CCD靶面尺寸;从而计算出焦距,放大率; 然后根据分辩率,对比度,景深,光圈,接口畸变允许范围等确定型号。 1.2.选择步骤: (1) 根据精度确定相机最大CCD靶面尺寸 (2) 选择…

征服Android面试官路漫漫(三),rrxjava原理

调用了 ContextImpl.createActivityContext() 方法。 static ContextImpl createActivityContext(ActivityThread mainThread, LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId, Configuration overrideConfiguration) { … // …

机器视觉-相机镜头光源介绍及选型-9.相机概念

相机概念 像素:感光器件上的基本感光单元,也是一幅图像的基本单元 像素深度: 每位像素数据位数,常见8bit,10bit,12bit。 分辨率和像素深度决定图像大小。增加像素深度可增强测量精度,但降低系统速…

征服面试官系列: Binder 核心机制和进程间通信,你都理解了吗

就这样,一个远程的,提供成绩查询的服务就完成了。 2.客户端的实现 客户端自然而然的是要连接服务端进程成绩查询。因此,我们在客户端的Activity中取绑定GradeService进行成绩查询。代码如下: public class BinderActivity exte…

Android Camera系统

1. Overview 1.1 物理架构 1.2 Android架构 2. CameraService 3. HAL 4. Overlay 5. Video for Linux 1. Overview 本文以Freescale IMX为例剖析camera摄像头的系统架构。 1.1 物理架构 硬件方面,camera系统分为主控制器和摄像头设备,功能上主要有取景…