热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

android双缓冲技术,AndroidVSYNC与图形系统中的撕裂、双缓冲、三缓冲浅析

android双缓冲技术,AndroidVSYNC与图形系统中的撕裂、双缓冲、三缓冲浅析先接触两个图形概念:帧率(FrameRate,单位FPS)--GPU显卡生成帧的速率,也可以

先接触两个图形概念: 帧率(Frame Rate,单位FPS)–GPU显卡生成帧的速率,也可以认为是数据处理的速度), 屏幕刷新频率 (Refresh Rate单位赫兹/HZ):是指硬件设备刷新屏幕的频率。屏幕刷新率一般是固定的,比如60Hz的每16ms就刷一次屏幕,可以类比一下黑白电视的电子扫描枪,每16ms电子枪从上到下从左到右一行一行逐渐把图片绘制出来,如果GPU显卡性能非常强悍,帧率可以非常高,甚至会高于屏幕刷新频率。

单缓存画面撕裂与(垂直同步+双缓冲)

什么是画面撕裂?如下:用两帧的部分数据合成一帧。

相比较画面撕裂场景如下:

再来看下VSYNC,屏幕刷新从左到右水平扫描(Horizontal Scanning),从上到下垂直扫描Vertical Scanning,垂直扫描完成则整个屏幕刷新完毕,这便是告诉外界可以绘制下一帧的时机,在这里发出VSync信号,通知GPU给FrameBuffer传数据,完成后,屏幕便可以开始刷新,所以或许称之为帧同步更合适。VSYNC强制帧率和显示器刷新频率同步,如果当前帧没绘制完,即使下一帧准备好了,也禁止使用下一帧,直到显示器绘制完当前帧,等下次刷新的时候,才会用下一帧。比如:如果显示器的刷新频率是60HZ显示器,开了垂直同步后,显示帧率就会被锁60,即使显卡输出高,也没用。对Android系统而言,垂直同步信号除了强制帧率和显示器刷新频率同步外,还有其他很多作用,VSYNC是APP端重绘、SurfaceFlinger图层合成的触发点,只有收到VSYNC信号,它们才会工作,以上便是个人对引入VSYNC与双缓冲的见解。

双缓冲的进阶:三缓冲

在Android系统里,除了双缓冲,还有个三缓冲,不过这个三缓冲是对于屏幕硬件刷新之外而言,它关注的是整个Android图形系统的消费者模型,跟Android自身的VSYNC用法有关系,在 Jelly Bean 中Android扩大了VSYNC使用场景与效果,不仅用在屏幕刷新防撕裂,同时也用在APP端绘制及SurfaceFlinger合成那,此时对VSYNC利用有点像Pipeline流水线,贯穿整个绘制流程,对比下VSYNC扩展使用的区别:

对于没采用VSYNC做调度的系统来说,比如Project Butter之前的系统(4.1以下),CPU的对于显示帧的处理是凌乱的,优先级也没有保障,处理完一帧后,CPU可能并不会及时处理下一帧,可能会优先处理其他消息,等到它开始处理UI生成帧的时候,可能已经处于VSYNC的中间,这样就很容易跨两个VYSNC信号,导致掉帧。在Jelly Bean中,下一帧的处理被限定在VSync信号到达时,并且看Android的处理UI重绘消息的优先级是比较高的,其他的同步消息均不会执行,从而保证每16ms处理一帧有序进行,同时由于是在每个VSYNC信号到达时就处理帧,可以尽量避免跨越两帧的情况出现。

上面的流程中,Android已经采用了双缓冲,双缓冲不仅仅是两份存储,它是一个概念,双缓冲是一条链路,不是某一个环节,是整个系统采用的一个机制,需要各个环节的支持,从APP到SurfaceFlinger、到图像显示都要参与协作。对于APP端而言,每个Window都是一个双缓冲的模型,一个Window对应一个Surface,而每个Surface里至少映射两个存储区,一个给图层合成显示用,一个给APP端图形处理,这便是应于上层的双缓冲。Android4.0之后基本都是默认硬件加速,CPU跟GPU都是并发处理任务的,CPU处理完之后就完工,等下一个VSYNC到来就可以进行下一轮操作。也就是CPU、GPU、显示都会用到Buffer,VSYNC+双缓冲在理想情况下是没有问题的,但如果某个环节出现问题,那就不一样了如下(帧耗时超过16ms):

7cc6995165f5

双缓冲jank

可以看到在第二个阶段,存在CPU资源浪费,为什么呢?双缓冲Surface只会提供两个Buffer,一个Buffer被DisPlay占用(SurfaceFlinger用完后不会释放当前的Buffer,只会释放旧的Buffer,直观的想一下,如果新Buffer生成受阻,那么肯定要保留一个备份给SF用,才能不阻碍合成显示,就必定要一直占用一个Buffer,新的Buffer来了才释放老的),另一个被GPU处理占用,所以,CPU就无法获取到Buffer处理当前UI,在Jank的阶段空空等待。一般出现这种场景都是连续的:比如复杂视觉效果每一帧可能需要20ms(CPU 8ms +GPU 12ms),GPU可能会一直超负荷,CPU跟GPU一直抢Buffer,这样带来的问题就是滚雪球似的掉帧,一直浪费,完全没有利用CPU与GPU并行处理的效率,成了串行处理,如下所示

如上图所示,虽然即使每帧需要20ms(CPU 8ms +GPU 12ms),但是由于多加了一个Buffer,实现了CPU跟GPU并行,便可以做到了只在开始掉一帧,后续却不掉帧,双缓冲充分利用16ms做到低延时,三缓冲保障了其稳定性,为什么4缓冲没必要呢?因为三个既可保证并行,四个徒增资源浪费。

双缓冲保证低延时,三缓冲保证稳定性,双缓冲不在16ms中间开始,有足够时间绘制 三缓冲增加其韧性。

总结

同步是防止画面撕裂的关键,VSYNC同步能防止画面撕裂

VSYNC+双缓冲在Android中能有序规划渲染流程,降低延时

Android已经采用了双缓冲,双缓冲不仅仅是两份存储,它是一个概念,双缓冲是一条链路,不是某一个环节,是整个系统采用的一个机制,需要各个环节的支持,从APP到SurfaceFlinger、到图像显示都要参与协作

三缓冲在UI复杂情况下能保证画面的连续性,提高柔韧性

作者:看书的小蜗牛

仅供参考,欢迎指正


推荐阅读
  • 本文将详细介绍多个流行的 Android 视频处理开源框架,包括 ijkplayer、FFmpeg、Vitamio、ExoPlayer 等。每个框架都有其独特的优势和应用场景,帮助开发者更高效地进行视频处理和播放。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 理解存储器的层次结构有助于程序员优化程序性能,通过合理安排数据在不同层级的存储位置,提升CPU的数据访问速度。本文详细探讨了静态随机访问存储器(SRAM)和动态随机访问存储器(DRAM)的工作原理及其应用场景,并介绍了存储器模块中的数据存取过程及局部性原理。 ... [详细]
  • 深入解析Android自定义View面试题
    本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • 深入理解C++中的KMP算法:高效字符串匹配的利器
    本文详细介绍C++中实现KMP算法的方法,探讨其在字符串匹配问题上的优势。通过对比暴力匹配(BF)算法,展示KMP算法如何利用前缀表优化匹配过程,显著提升效率。 ... [详细]
  • SQLite 动态创建多个表的需求在网络上有不少讨论,但很少有详细的解决方案。本文将介绍如何在 Qt 环境中使用 QString 类轻松实现 SQLite 表的动态创建,并提供详细的步骤和示例代码。 ... [详细]
  • 深入解析:阿里实战 SpringCloud 微服务架构与应用
    本文将详细介绍 SpringCloud 在微服务架构中的应用,涵盖入门、实战和案例分析。通过丰富的代码示例和实际项目经验,帮助读者全面掌握 SpringCloud 的核心技术和最佳实践。 ... [详细]
  • 并发编程:深入理解设计原理与优化
    本文探讨了并发编程中的关键设计原则,特别是Java内存模型(JMM)的happens-before规则及其对多线程编程的影响。文章详细介绍了DCL双重检查锁定模式的问题及解决方案,并总结了不同处理器和内存模型之间的关系,旨在为程序员提供更深入的理解和最佳实践。 ... [详细]
  • 网易严选Java开发面试:MySQL索引深度解析
    本文详细记录了网易严选Java开发岗位的面试经验,特别针对MySQL索引相关的技术问题进行了深入探讨。通过本文,读者可以了解面试官常问的索引问题及其背后的原理。 ... [详细]
  • 分享一个简化版的Silverlight链接图项目:Link Map Simplified
    本文介绍了一个使用Silverlight开发的可视化工具,主要用于展示和操作复杂的实体关系图(Graph)。该工具在犯罪调查系统中得到了广泛应用,帮助用户直观地获取和理解相关信息。 ... [详细]
  • 本文探讨了如何在日常工作中通过优化效率和深入研究核心技术,将技术和知识转化为实际收益。文章结合个人经验,分享了提高工作效率、掌握高价值技能以及选择合适工作环境的方法,帮助读者更好地实现技术变现。 ... [详细]
  • 本文探讨了Java编程的核心要素,特别是其面向对象的特性,并详细介绍了Java虚拟机、类装载器体系结构、Java类文件和Java API等关键技术。这些技术使得Java成为一种功能强大且易于使用的编程语言。 ... [详细]
  • 利用Selenium与ChromeDriver实现豆瓣网页全屏截图
    本文介绍了一种使用Selenium和ChromeDriver结合Python代码,轻松实现对豆瓣网站进行完整页面截图的方法。该方法不仅简单易行,而且解决了新版Selenium不再支持PhantomJS的问题。 ... [详细]
  • yikesnews第11期:微软Office两个0day和一个提权0day
    点击阅读原文可点击链接根据法国大选被黑客干扰,发送了带漏洞的文档Trumps_Attack_on_Syria_English.docx而此漏洞与ESET&FireEy ... [详细]
author-avatar
johnnyLei
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有