Android画面显示流程分析(1)_android logo显示过程(1)

201 阅读13分钟

DVI(Digital Visual Interface),即数字视频接口。它是1998年9月,在Intel开发者论坛上成立的,由Silicon Image、Intel(英特尔)、Compaq(康柏)、IBM(国际商业机器公司)、HP(惠普)、NEC(日本电气股份有限公司)、Fujitsu(富士通)等公司共同组成的DDWG(Digital Display Working Group,数字显示工作组)推出的接口标准

LVDS(Low Voltage Differential Signaling,即低电压差分信号)接口又称RS-644总线接口,是20世纪90年代才提出的一种数据传输和接口技术。LVDS接口是美国NS美国国家半导体公司为克服以TTL电平方式传输宽带高码率数据时功耗大,电磁干扰大等缺点而研制的一种数字视频信号传输方式。由于其采用低压和低电流驱动方式,因此,实现了低噪声和低功耗。LVDS技术具有低功耗、低误码率、低串扰和低辐射等特点,其传输介质可以是铜质的PCB连线,也可以是平衡电缆。LVDS在对信号完整性、低抖动及共模特性要求较高的系统中得到了越来越广泛的应用,常见于液晶电视中。

MIPI(Mobile Industry Processor Interface)是2003年由ARM, Nokia, ST ,TI等公司成立的一个联盟,目的是把手机内部的接口如摄像头、显示屏接口、射频/基带接口等标准化,从而减少手机设计的复杂程度和增加设计灵活性。MIPI联盟下面有不同的WorkGroup,分别定义了一系列的手机内部接口标准,比如摄像头接口CSI、显示接口DSI、射频接口DigRF、麦克风/喇叭接口SLIMbus等。统一接口标准的好处是手机厂商根据需要可以从市面上灵活选择不同的芯片和模组,更改设计和功能时更加快捷方便。

目前手机屏幕和SOC间多使用MIPI接口来传输屏幕数据,其实物如下图所示,图中的条状芯片就是负责更新显示屏的显示内容的芯片DDIC, 它一边通过mipi协议和SOC通信,一边把获取到的显示数据写入到显示存储器GRAM内, 屏幕(Panel)通过不停扫描GRAM来不停更新液晶显示点的颜色,实现画面的更新。

屏幕坐标系

显示屏幕采用如下图所示的二维坐标系,以屏幕左上角为原点,X方向向右,Y轴方向向下,屏幕上的显示单元(像素)以行列式整齐排列,如下图所示,如下图示中以六边形块来代表一个像素点,如无例外说明,本文中所有图示都将以该六边形块来代表屏幕上的一个像素点。

在一个典型的Android显示系统中,一般包括SOC、DDIC、Panel三个部分, SOC负责绘画与多图层的合成,把合成好的数据通过硬件接口按某种协议传输给DDIC,然后DDIC负责把buffer里的数据呈现到Panel上。如下图所示为高通平台上的画面更新简单示意图,首先CPU或GPU负责绘画,画出的多个layer交由MDP进行合成,合成的数据通过mipi协议和DSI总线传输给DDIC, DDIC将数据存到GRAM内(非video屏), Panel不断scanGRAM来显示内容。

那么对于DDIC来讲它的职责就是按mipi协议和SOC交互,获取到从SOC合成好的一帧画面的数据,然后将数据写入GRAM,对GRAM的写入要符合一定的时序。

2.3. LCD时序

这个写入时序要首先从过去的 CRT 显示器原理说起。CRT 的电子枪按照从上到下一行行扫描,扫描完成后显示器就呈现一帧画面,随后电子枪回到初始位置继续下一次扫描。为了把显示器的显示过程和系统的视频控制器进行同步,显示器(或者其他硬件)会用硬件时钟产生一系列的定时信号。当电子枪换到新的一行,准备进行扫描时,显示器会发出一个水平同步信号(horizonal synchronization),简称 HSync;而当一帧画面绘制完成后,电子枪回复到原位,准备画下一帧前,显示器会发出一个垂直同步信号(vertical synchronization),简称 VSync。显示器通常以固定频率进行刷新,这个刷新率就是 VSync 信号产生的频率。尽管现在的设备大都是液晶显示屏了,但原理仍然没有变。

CLK:像素时钟,像素数据只有在时钟上升或下降沿时才有效
ENB:是数据使能信号,当它为高时,CLK信号到达时输出有效数据。
HBP:行同步信号的前肩,水平同步信号的上升沿到ENABLE的上升沿的间隔。
HSW:水平同步信号的低电平(非有效电平)持续时间
HFP:行同步信号的后肩,ENABLE的下降沿到水平同步信号的下升沿的间隔 如下图所示

图中从HSYNC的下降沿开始,等待两个CLK产生一个上升沿,在等待一个HBP时间后开始传输一行的像素数据,像素数据只有在像素时钟和上升沿或下降沿时才会写入(这里我们只讨论原理,并不是某个特定平台的具体实现,所以HSW所对应的时钟数字并不是以图中所示为准,具体产品中都会有调整和变化),经过N个像素时钟后成功将一行像素数据写入D1-Dn

类似地,在两帧画面之间也存在一些间隔:

VSW: VSYNC信号下降沿到上升沿间的时间
VBP: 帧同步信号的前肩
VFP:帧同步信号的后肩
VPROCH: 被称为消隐区,它是指 VSW+VBP+VFP , 这个时间段内Panel不更新像素点的颜色

在一个Vsync周期内是由多个Hsync周期组成的,其个数就是屏幕在Y方向的像素点个数,也就是屏幕上有多少行像素点, 每个Hsync周期内传输一行内所有像素点的数据。通常屏厂给的spec文档还会给出类似下面这样的图,但都是表达一个意思,数据是以行为单位写入的,Hsync是协调行和行之间的同步信号,多个行依次写入构成一帧数据,帧和帧数据之间由Vsync信号来同步协调。

当多帧画面依次输出到屏幕的时候我们就可以看到运动的画面了,通常这个速度到达每秒60帧时人眼就已经感觉画面很流畅了。下图演示了在vsync和hsync同步下两帧画面间的切换时序,以及消隐区(VPorch)在其中的位置关系。在消隐区结束(或开始)时DDIC会向SOC发出一个中断信号,这个信号称为TE信号, SOC这边就是通过该中断信号来判断上一帧数据是否已被DDIC读走,进而决定是否可以将buffer写入下一帧数据。

2.4. LCD上的画面更新流程

让我们以下面这张图来说明从SOC到到DDIC再到Panel的画面更新过程,首先SOC准备画面A, DDIC上一帧画面更新完毕进入消隐区,同时向SOC侧发送TE信号,SOC收到TE信号后,A画面的数据开始通过DSI总线向DDIC传输(DSI Write),当消隐区时间结束时开始这一帧数据从数据变为像素点颜色的过程(Disp Scan), Disp Scan是以行为单位将GRAM内一行的数据内容通过改变电流电压等方式改变Panel上像素点的颜色。进而实现一行画面的更新,按下来Disp Scan将以一定速度逐行读取GRAM的内容,而于此同时DSI Write也还在进行中,由于DSI Write较Disp Scan早了一个Vporch的时间,所以Disp Scan扫描到的数据都是A画面的数据。那么人眼会看到画面“逐渐”出现到显示屏上,当A画面的所有行都经Disp Scan到达屏幕后,下一个Vporch开始,DDIC再次向SOC发出TE信号, 下帧B画面的数据开始经过DSI总线传输到DDIC, 如此循环往复可以将连续的A, B, C画面更新到屏幕上。

这里我们思考一个问题: 就像上图中所绘一样总会存在一段时间GRAM内的数据会出现一部分是新画面的数据,一部分是旧画面的数据,那么从上帝视角看GRAM里的画面是“撕裂”的,那Disp Scan会不会把这个“撕裂”的画面显示到Panel上呢? 用户有没有可能看到一个“撕裂”的画面呢?

答案是有可能会。

为讨论方便我们这里先把DSI write记作写, 把Disp Scan记作读, 正常情况下,我们会将读速度调到和写速度差不多,由于写是在进入vporch时就开始了,而读的动作是离开vproch时,所以在读和写的这场“百米跑”竞赛中总是写跑在前面,这样保证读始终读到的是同一帧画面的数据,这个过程如下面图1所示。

由于读和写的速度受到环境或各种电气因素影响并不是一成不变的,在实际运行过程中会有波动,当读和写两条线离的较近时由于速度波动的存在会出现两条线交叉的情况,如图2所示,那么这时读会先后读到前后两帧的数据,出现花屏现象。

有时我们为了避免由于速率波动引起花屏问题,会放大vporch的时间让读和写尽量拉开距离,这样可以减少花屏现象出现的概率,这里的原理如图3所示

继续思考下一问题: 从上面的分析可以看出Panel上的像素数据是一行行更新下来的,那人眼为什么没有看到更新了一半的画面呢?

这个问题我并不知道答案,这可能涉及到人眼的生物学构造,人眼对事物的成像原理等复杂的原理,总之是在这个时间尺度内人眼看不到。

接下来我们从另一角度来研究一下这个问题,我们把视角切换到上帝视角,假如存在上帝之眼的话,他应该能看到这个更新了一半的画面,我们尝试用高速摄影机来模拟“上帝之眼”。

首先我们先准备一些测试代码, 我们写一个测试用apk, 下面这段代码是向Android框架注册一个Choreographer的监听,Choreographer是Android提供的一个获取vsync信号的通道。当下图中doFrame被调用到时我们这里可以暂时粗略理解为是上面所讨论的TE信号, 这里收到Vsync信号后通过Pthread的Condition通知到另一线程。这用于模拟一个vsync的消息泵。

Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {
    @Override
    public void doFrame(long frameTimeNanos) {//当vsync信号来时会调用到这里
            Global.lock.lock();
            try {
                Global.syncCondition.signal();//通知另一条线程更新画面
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                Global.lock.unlock();
            }
            Choreographer.getInstance().removeFrameCallback(this);
            Choreographer.getInstance().postFrameCallback(this);
    }
});


下面代码中每收到一个vsync信号都会去画一帧画面,同时给帧编号编号加1(相当于给每一帧一个编号),如果当前的编号为奇数则画绿色,如果为偶数则画蓝色,那么画面应该是蓝绿交替出现:

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
    .......

    @Override
    public void run() {
        while(true) {
            Global.lock.lock();
            try {
                Global.syncCondition.await();//在这里等待vsync到来的通知消息
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                Global.lock.unlock();
            }
            draw();//画蓝色或绿色
        }
    }
    ........
    private void draw() {

        Canvas mCanvas = null;
        try {
            mCanvas = mSurfaceHolder.lockCanvas();
            if(autoNum %2 == 0) {
                mPaint.setColor(Color.BLUE);//如果为双数则画面画成蓝色
            } else {
                mPaint.setColor(Color.GREEN);//如果为单数则画面画成绿色
            }
            mCanvas.drawRect(0, 0, getRight(), getBottom(), mPaint);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (mCanvas != null) {
                mSurfaceHolder.unlockCanvasAndPost(mCanvas);
            }
        }
        autoNum++;//数字加1
    }

}


下面是高速摄影机看到的画面变化情况,从下图中可以看出来,画面从绿变蓝的过程中总是能看到先是上面部分变蓝色,接下来才会看到全部变蓝,由蓝变绿也是同样的现象,先是图像上面变成绿色接下来全部变绿色,在“上帝之眼”看来画面的变化是有前后两个画面各占一部分的情况的,这情况是上面是新画面下面是旧画面,但人眼是看不出来这种画面。

下面的图中发现画面是颜色渐变的,这是因为通过高速摄影机是画面再次感光形成的影像,由于物理世界中光线是有衍射及曝光时长因素的,所以最终在高速摄影机留下的图中是颜色渐变的。

Android高级架构师

由于篇幅问题,我呢也将自己当前所在技术领域的各项知识点、工具、框架等汇总成一份技术路线图,还有一些架构进阶视频、全套学习PDF文件、面试文档、源码笔记做整理一份资料。

需要的朋友可以**私信【学习】**我分享给你,希望里面的资料可以给你们一个更好的学习参考。

或者直接点击下面链接免费获取

Android学习PDF+架构视频+面试文档+源码笔记

  • 330页PDF Android学习核心笔记(内含上面8大板块)

  • Android学习的系统对应视频

  • Android进阶的系统对应学习资料

  • Android BAT部分大厂面试题(有解析)

好了,以上便是今天的分享,希望为各位朋友后续的学习提供方便。觉得内容不错,也欢迎多多分享给身边的朋友哈。