Choreographer_舞蹈编导

为什么叫舞蹈编导,因为舞蹈是由节奏的,节奏是每个点位动作的快慢控制,跳舞时节奏很重要,编舞者控制节奏。视图刷新也是如此,不是说你想刷就能刷,一切要按照底层信号要求的节奏来。

理解屏幕刷新频率

刷新频率:每秒钟刷新屏幕的次数,从缓存中取出每一帧,显示到屏幕上的速度。
帧率:GPU/CPU生成每一帧画面图像,存入缓存中的速度。
一般情况下帧率是大于刷新频率的,每个设备的刷新频率固定,与硬件相关,若帧率是刷新率的两倍,两张图像画面,只能有一个现实到屏幕上,也就是说生产画面的速度要大于显示画面的速度。典型的生产者-消费者模式。
屏幕刷新过程:从左到右刷新一行,然后垂直刷新,再一行..,直到屏幕刷新完毕。每一次刷新,都是这一个过程,刷新一次后,中间有一个期间,刷新率太高,每秒60帧左右,人眼无法感知。
tearing:若帧率大于刷新率,会导致在刷新前一帧还未开始时,缓存已经被新一帧覆盖一部分,那么在刷新前一帧时,现显示的一部分是新一帧内容。会导致画面前后帧上下重叠。这种情况技术上称之tearing,画面撕裂的意思。
解决方案:增加缓存到两个缓存,CPU生成帧存入一个缓存A,屏幕取出帧存入另一个缓存B,解决了一个缓存导致生产者与消费者不同步的问题。增加Vsync同步信号,负责调度将A缓存拷贝到B缓存,显示取出的就是一个完整帧的画面。Vsync信号在一帧刷新完的中间期间产生,A到B的复制(交换地址即可),进入下一次刷新,并通知生产者gpu/cpu继续生产帧,只有收到Vsync信号,生产者才会生产帧。因此,可使帧率与刷新率保持同步,消耗一次才生成一次。
掉帧:若Vsync信号发出时,A缓存正在被生产者锁住生产,gpu绘制生产帧时间超过信号发出时刻一点,此时不会复制。导致B缓存仍是老帧,下一次周期与前一次刷新相同的帧。当gpu生产结束后,此时刷新老数据的刷新周期中,还没有Vsync信号,则gpu空闲
掉帧解决方案:再增加一个缓存到三个缓存。当有缓存锁住时复制他前面的上一次被锁住的另一个缓存。

Android平台提供两种信号,一种是硬件信号,另一种是软件信号,由SurfaceFlinger进程的一个线程定时发出,硬件信号由硬件发出。
App进程若要通过gpu实现图像绘制,需要在接收到Vsync信号的条件下进行,因此,App进程访问SurfaceFlinger进程获取这个信号,再进行gpu绘制。

Choreographer就是负责获取Vsync同步信号并控制App线程(主要是主线程绘图)完成图像绘制的类。


Choreographer单例

在Android系统中主要是主线程负责UI绘制,其他线程也可以绘制,如SurfaceView,这里以主线程UI绘制进行介绍。

每个线程中保存一个Choreographer实例对象。

Choreographer#sThreadInstance静态对象。

private static final ThreadLocal<Choreographer> sThreadInstance =
new ThreadLocal<Choreographer>() {
@Override
protected Choreographer initialValue() {
Looper looper = Looper.myLooper();
if (looper == null) {
//抛出异常。
}
return new Choreographer(looper);
}
};

线程本地存储ThreadLocal变量,Choreographer类型,在线程中初始化变量时,创建Choreographer对象,绑定主线程Looper。

每个窗体旗下ViewRootImpl均使用同一个Choregrapher对象,它承担控制大部分视图绘制节奏的工作。

继续深入学习:https://www.jianshu.com/p/47c866f6fb67

Choreographer解析的更多相关文章

  1. Choreographer全解析

    前言 今天继续屏幕刷新机制的知识讲解,上文说到vsync的处理,每一帧UI的绘制前期处理都在Choreographer中实现,那么今天就来看看这个神奇的舞蹈编舞师是怎么将UI变化反应到屏幕上的. 代码 ...

  2. Android属性动画源代码解析(超详细)

    本文假定你已经对属性动画有了一定的了解,至少使用过属性动画.下面我们就从属性动画最简单的使用开始. ObjectAnimator .ofInt(target,propName,values[]) .s ...

  3. 【凯子哥带你学Framework】Activity界面显示全解析

    前几天凯子哥写的Framework层的解析文章<Activity启动过程全解析>,反响还不错,这说明“写让大家都能看懂的Framework解析文章”的思想是基本正确的. 我个人觉得,深入分 ...

  4. Android 属性动画 源码解析 深入了解其内部实现

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/42056859,本文出自:[张鸿洋的博客] 我参加了博客之星评选,如果你喜欢我的博 ...

  5. View 动画 Animation 运行原理解析

    这次想来梳理一下 View 动画也就是补间动画(ScaleAnimation, AlphaAnimation, TranslationAnimation...)这些动画运行的流程解析.内容并不会去分析 ...

  6. 属性动画 ValueAnimator 运行原理全解析

    最近下班时间都用来健身还有看书了,博客被晾了一段时间了,原谅我~~~~ 提问环节 好,废话不多说,之前我们已经分析过 View 动画 Animation 运行原理解析,那么这次就来学习下属性动画的运行 ...

  7. Activtiy完全解析(三、View的显示过程measure、layout、draw)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/52840065 本文出自:[openXu的博客]   在Activity完全解析的第一篇文章A ...

  8. 【转】GT 的性能测试方案解析

    前言 本文将整理腾讯GT各个性能测试项的测试方法,目的是为了帮助移动性能专项测试同学快速过一遍腾讯GT各个性能数据是如何获取的.另外对腾讯GT还不了解或者不知道它能做什么的同学可以看看这篇文章:htt ...

  9. 【凯子哥带你学Framework】Activity界面显示全解析(下)

    咱们接着上篇继续讲,上篇没看的请戳:[凯子哥带你学Framework]Activity界面显示全解析(上) 如何验证上一个问题 首先,说明一下运行条件: //主题 name="AppThem ...

随机推荐

  1. zabbix问题-非常少的网络故障失败或罕见:Proxy超时的问题

    解决方案 在zabbix_agentd.conf中添加这些. BufferSend = 10 BufferSize = 150 MaxLinesPerSecond = 100 Timeout = 29 ...

  2. python之shutil

    ''' shutil 用来处理 文件 文件夹 压缩包 的模块 ''' import shutil # 拷贝文件内容 shutil.copyfileobj(open('old.xml', 'r'), o ...

  3. Filebeat配置参考手册

    Filebeat的配置参考 指定要运行的模块 前提: 在运行Filebeat模块之前,需要安装并配置Elastic堆栈: 安装Ingest Node GeoIP和User Agent插件.这些插件需要 ...

  4. Redis详解(四)------ redis的底层数据结构

    上一篇博客我们介绍了 redis的五大数据类型详细用法,但是在 Redis 中,这几种数据类型底层是由什么数据结构构造的呢?本篇博客我们就来详细介绍Redis中五大数据类型的底层实现. 1.演示数据类 ...

  5. opentack-openstack组件及功能(1)

    一. OpenStack各组件间的关系 图22.1 OpenStack各组件间的关系 1.基础管理服务包含Keystone,Glance,Nova,Neutron,Horizon五个服务 (1)Key ...

  6. CentOS自定义快捷键,以终端为例

    和Ubuntu不同的是,CentOS默认情况下没有Terminal的快捷键.因此,用户需要自定义. 具体操作: 一.打开设置,搜索keyboard 二.点击+号定义快捷键 名称随意填,查询终端程序所在 ...

  7. 关于dubbo+zookeeper微服务的一些认识记录

    借鉴架构示意图: 实例介绍: 公司某项目架构 服务器A:nginx 服务器BC:tomcat1.tomcat2 服务器D:Dubbo+zookeeper 服务器EF:db1+zookeeper.db2 ...

  8. BEX5下增加sessionStorage监听器实现页面间数据刷新

    场景: A页面修改了数据,希望B页面能进行及时的同步前端数据,但是假如当A页面修改保存后,去获得B页面的model对象,会增加开发的难度,同时A页面也不能重复利用:假如在B页面的激活事件里面写刷新代码 ...

  9. python之路7-正则表达式

    正则表达式用于做字符串匹配,在python中用re模块来操作 生成正则的在线工具:http://tool.chinaz.com/regex

  10. Hack The Box 获取邀请码

    TL DR; 使用curl请求下面的地址 curl -X POST https://www.hackthebox.eu/api/invite/generate {"success" ...