Android 刷新与显示

目录

屏幕显示原理:

显示刷新的过程

VSYNC机制具体实现

小结:


屏幕显示原理:

过程描述:

应用向系统服务申请buffer

系统服务返回一个buffer给应用

应用开始绘制,绘制完成就提交buffer,系统服务把buffer数据提供给屏幕

这样,屏幕就能显示应用绘制的显示数据了

如果只有一个缓存,那么屏幕在还没有读完缓存数据的时候,系统服务又在写缓存数据,那么屏幕读取的这一帧数据其实就包含了两帧的数据,显示出来的可能一半是第一帧,一半是第二帧数据了。解决这个问题可以采用双缓冲区的方式。

这个操作过程大概是这样的,缓存1用于系统服务写数据,缓存2就用来给屏幕读取,

当屏幕需要读完缓存1的数据后需要读取下一帧数据,那么就把指针切换到缓存2来读取即可,同理系统服务就往缓存1来写数据,如此交替,就使得缓存的读写独立开来互不影响了。

显示刷新的过程

安卓定义的是60Hz的刷新率,就是每16ms屏幕的数据会刷新一次

那么我们分析一下显示刷新的过程:

应用进行绘制,然后由系统服务进行渲染并输出屏幕显示数据到缓存,屏幕读取缓存数据进行刷新显示。

第1帧:绘制渲染正常,所以屏幕能够正常显示第1帧数据

第2帧:没能在16ms内完成,因此就无法提供这一帧屏幕数据给缓存,所以屏幕也只能继续读取旧的数据,也就是第1帧数据。我们从视图描述看,第2帧的性能优化的不错,远远小于16ms,但是这一帧之所以会没能在16ms内完成绘制渲染提供缓存出来,是因为这一帧绘制的比较晚,导致这一帧还没有绘制完成就到了16ms了,这就是掉帧。如果这样的情况多了,就会让用户明显感受到卡顿。

该怎么解决这个问题呢?答案是:Vsync信号

如果有个Vsync信号,来通知应用绘制,那么这样就能实现每一帧都比较完美地在16ms内完成绘制渲染,提供显示数据了。

这就是Vsync给应用和服务进行绘制渲染提供同步信号的基本原理了

VSYNC机制具体实现

上面讲解vsync原理的时候为了简单起见,把绘制和渲染结合一起了,实际上绘制和渲染是由不同的进程,不同的硬件来处理的。在Android系统中,绘制是由应用app来做的,对应CPU的操作,合成与渲染是由SurfaceFlinger完成,对应的是GPU。现在的问题是一个Vsync信号只有1个,怎么来同时对两个进程提供同步信号呢?Android系统中的做法是一分为二,就是把信号分为vsync-app和vsync-sf,同时也引入一个指挥家Choreographer,进行操作指导。

我们先从请求绘制开始:

/frameworks/base/core/java/android/view/ViewRootImpl.java

1)往消息队列插入SyncBarrier:这是一个屏障,把消息插入队列里就不可以处理普通消息,等到这个屏障撤除了才可以进行普通消息的处理。对异步消息是不影响的。

一次Vsync周期只能触发一次requestLayout,只会绘制一次

2)往mChoreographer插入Callback,mTraversalRunnable就是一个异步消息,需要紧急处理

Choreographer是与ViewRootImpl一起创建的

sThreadInstance是一个ThreadLocal,在不同的线程去getInstance可以得到不同的Choreographer的对象

Callback是怎么加到Choreographer里面呢?

 /frameworks/base/core/java/android/view/Choreographer.java

final long now = SystemClock.uptimeMillis();获取下一vsync的时间戳

dueTime就是从这个时间后延迟多久

mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);

一个CallbackQueues队列,不同的callbackType有不同的队列,包含有3个参数

如果dueTime小于现在的时间戳那么就是说下一帧就要被处理的。直接调scheduleFrameLocked处理,如果是大于下一次vsync的时间,则需要通过handler发送一个异步消息,等待处理。

代码可以看到,跑在所在looper的线程的时候就会立刻调度vsync,否则就尽快post一个消息去UI线程。所以就使用了Handler发送一个异步消息,

当vsync来的时候就会调用这个FrameDisplayEventReceiver,里面的timestampNanos就是这个vsync信号的时间戳,

绘制的时候jitterNanos如果大于一个时间周期,并且超过了SKIPPED_FRAME_WARNING_LIMIT的警告值就会给出一个警告,应用主线程耗时操作。

上面是属于计算时间的阶段,那么下一阶段就是一系列的回调阶段,包括:

从callbackqueue里面取出带有时间戳的callback进行处理

小结:

应用层的View调用了requestLayout要重绘,其实就是new了一个Choreographer丢到消息队列里面,然后Choreographer没有马上去处理消息,而是先是调用requestNextVsync函数向SurfaceFlinger请求下一个的vsync信号。然后SurfaceFlinger就会在下一个vsync信号来的时候通过postSyncEvent 向Choreographer发送一个通知,Choreographer接收到通知后就会去处理消息队列里面的消息,之前真正处理requestLayout的就是performTraversal这个方法,开始进行遍历等一系列操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/78387.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

移动开发最佳实践:为 Android 和 iOS 构建成功应用的策略

您可以将本文作为指南,确保您的应用程序符合可行的最重要标准。请注意,这份清单远非详尽无遗;您可以加以利用,并添加一些自己的见解。 了解您的目标受众 要制作一个成功的应用程序,你需要了解你是为谁制作的。从创建…

接口自动化测试Mock Get和Post请求

Mock可以模拟一个http接口的后台响应,可以模拟request,response 下载 moco-runner-0.11.0-standalone.jar 下载链接: https://pan.baidu.com/s/1bmFzvJPRnDlQ-cmuJ_3iRg 提取码: kpjv 确保安装了jdk,cmd下可以运行java -version 一、模拟不带参的get请求…

AQL品质抽样标准

AQL抽样标准 - 百度文库 Acceptance Quality Limit 接收质量限的缩写,即当一个连续系列批被提交验收时,可允许的最差过程平均质量水平。 AQL普遍应用于各行业产品的质量检验,不同的AQL标准应用于不同物质的检验上。在AQL 抽样时,…

VUE框架:vue2转vue3全面细节总结(3)路由组件传参

大家好,我是csdn的博主:lqj_本人 这是我的个人博客主页: lqj_本人_python人工智能视觉(opencv)从入门到实战,前端,微信小程序-CSDN博客 最新的uniapp毕业设计专栏也放在下方了: https://blog.csdn.net/lbcy…

idea添加翻译插件并配置有道翻译

1、安装Translation插件 2、 创建有道云应用 有道智云控制台 3、设置idea 4、效果(选中文本右键翻译,默认快捷键CtrlShiftY)

图文演示:如何三分钟极速搭建一个元宇宙3D虚拟展厅

引言: 元宇宙3D虚拟展厅时代已经来临。元宇宙是一个虚拟的、立体的数字空间,可以让用户沉浸在其中进行交互操作,并体验无限可能。如何快速搭建一个属于自己的虚拟展厅则受到越来越多人的关注。 一.虚拟展厅类型 1.党建展馆 实现…

Linux 匿名页的生命周期

目录 匿名页的生成 匿名页生成时的状态 do_anonymous_page缺页中断源码 从匿名页加入Inactive lru引出 一个非常重要内核patch 匿名页何时回收 本文以Linux5.9源码讲述 匿名页的生成 用户空间malloc/mmap(非映射文件时)来分配内存,在内核空间发生…

前端笔记html-layer使用

layer.open方法 layer.open({type:2, //可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层)title: title,content:[…

网络安全之原型链污染

目录: 目录: 一、概念 二、举例 三、 实操了解 总结 四、抛出原题,历年原题复现 第一题: 五、分析与原理 第二题: 八、分析与原理 九、具体操作,payload与结果 结果: 一、概念 Java…

《面试1v1》ElasticSearch基础

🍅 作者简介:王哥,CSDN2022博客总榜Top100🏆、博客专家💪 🍅 技术交流:定期更新Java硬核干货,不定期送书活动 🍅 王哥多年工作总结:Java学习路线总结&#xf…

阿里云快速部署开发环境 (Apache + Mysql8.0)

本文章的内容截取于云服务器管理控制台提供的安装步骤,再整合前人思路而成,文章末端会提供原文连接 ApacheMysql 8.0部署MySQL数据库(Linux)步骤一:安装MySQL步骤二:配置MySQL步骤三:远程访问My…

Redis压缩列表

区分一下 3.2之前 Redis中的List有两种编码格式 一个是LINKEDLIST 一个是ZIPLIST 这个ZIPLIST就是压缩列表 3.2之后来了一个QUICKLIST QUICKLIST是ZIPLIST和LINKEDLIST的结合体 也就是说Redis中没有ZIPLIST和LINKEDLIST了 然后在Redis5.0引入了LISTPACK用来替换QUiCKLIST中的…

vue整合脑图编辑管理系统-kitymind百度脑图

前言 项目为前端vue项目,把kitymind百度脑图整合到前端vue项目中,显示了脑图的绘制,编辑,到处为json,png,text等格式的功能 文章末尾有相关的代码链接,代码只包含前端项目,在原始的…

线性代数 | 机器学习数学基础

前言 线性代数(linear algebra)是关于向量空间和线性映射的一个数学分支。它包括对线、面和子空间的研究,同时也涉及到所有的向量空间的一般性质。 本文主要介绍机器学习中所用到的线性代数核心基础概念,供读者学习阶段查漏补缺…

Visual Studio 2022的MFC框架——应用程序向导

我是荔园微风,作为一名在IT界整整25年的老兵,今天我们来重新审视一下Visual Studio 2022开发工具下的MFC框架知识。 MFC(Microsoft Foundation Class,微软基础类库)是微软为了简化程序员的开发工作所开发的一套C类的集合&#xf…

roop 视频换脸

roop: one click face swap. 只用一张人脸图片,就能完成视频换脸。 项目地址: https://github.com/s0md3v/roopColab 部署: https://github.com/dream80/roop_colab 本文是本地部署的实践记录。 环境基础 OS: Ubuntu 22.04.2 LTSKernel: 5…

GPIO实验

一、GPIO GPIO(General-purpose input/output)即通用型输入输出,GPIO可以控制连接在其之上的引脚实现信号的输入和输出 芯片的引脚与外部设备相连,从而实现与外部硬件设备的通讯、控制及信号采集等功能 LED实验步骤 最终目的&am…

2020-2023中国高等级自动驾驶产业发展趋势研究

1.1 概念界定 2020-2023中国高等级自动驾驶产业发展趋势研究Trends in China High-level Autonomous Driving from 2020 to 2023自动驾驶发展过程中,中国出现了诸多专注于研发L3级以上自动驾驶的公司,其在业界地位也越来越重要。本报告围绕“高等级自动…

vue2-diff算法

1、diff算法是什么? diff算法是一种通过同层的树节点进行比较的高效算法。 其有两个特点: 比较只会在同层级进行,不会跨层级进行。 在diff比较的过程中,循环从两边向中间比较。 diff算法在很多场景中都有应用,在vue中&…

mac电脑访问windows共享文件夹连接不上(设置445端口)

前提:首先需要保证mac和windows都在同一局域网内,如果不在肯定是连不上的,就不用往下看了。 事情是这样的,公司入职发了mac电脑,但是我是window重度用户,在折腾mac的过程中,有许多文件需要从wi…