页面绘制的来龙去脉

createh54个月前 (01-06)技术教程57

一、概述

1.Android 中,用户编写的应用程序(Client)测量和计算布局,SurfaceFlinger(Server)用来渲染绘制界面,Client和Server通过匿名共享内存(Anonymous Shared Memory)通信。

2.每个应用和 SurfaceFlinger 之间都会创建一个SharedClient,一个 SharedClient 最多可以创建31 个 SharedBufferStack,每个 Surface 对应一个 SharedBufferStack,也就是一个 Window。即每个应用最多可以创建 31 个窗口。


二、原理

1.Android 4.1 之后,Android OS 团队对 Android Display 进行了进化和改变,引入了三个核心元素:Vsync,Triple Butter,Choreographer。

2.图形界面的绘制,是由 CPU 准备数据,然后通过驱动层把数据交给 GPU 进行绘制。图形 API 不允许 CPU 和 GPU直接通信,所以就有了图形驱动(Graphics Driver)来进行通信。图形驱动 维护了一个序列(Display List),CPU 不断把需要显示的数据放进去,GPU 不断地将数据取出来进行显示。其中 Choreographer 起调度的作用,统一绘制图像到 Vsync 的某个时间点。

Choreographer在收到Vsync信号时,调用用户设置的回调函数。函数的先后顺序如下:

1)CALLBACK_INPUT:与输入事件有关

2)CALLBACK_ANIMATION:与动画有关

3)CALLBACK_TRAVERSAL:与 UI 绘制有关

3.Android中开发者可以通过SurfaceHolder来访问和操作缓冲区,在绘制每一帧之前调用lockCanvas()来获取缓冲区,并在绘制完成后调用unlockCanvasAndPost()来提交更改。


三、多重缓冲

1.概述

1)多重缓冲允许程序在后台缓冲区准备数据,在前台缓冲区显示页面,从而避免了在更新数据时造成的屏幕闪烁或卡顿。

2)OpenGL ES、Android Canvas绘制和视频播放时为避免等待数据时的卡顿,也会使用多重缓冲。

2.双重缓冲

在 Linux 上,通常使用 FrameBuffer 来做显示输出。

双重缓冲会创建一个 FrontBuffer 和一个 BackBuffer,FrontBuffer 是当前显示的页面,BackBuffer是下一个要显示的画面。然后前后缓存依次交替显示数据。

这样的特点为:

1)如果是单重缓冲,页面可能会有这种情况:A 数据需要显示,然后是 B 数据显示,B 数据显示需要耗费一定时间,但是这个时间里,C 数据也请求了展示,我们可能会看到,在展示 C 数据的时候,还有 B 数据的残影。而双重缓冲会更好得避免这个问题。

2)双重缓冲仍然可能会卡。

3)CPU 和 GPU 的刷新时间,和Display的FPS是一致的。因为只有到发出 Vsync 命令的时候,CPU 和GPU才会进行刷新或显示的动作。

3.三重缓冲

1)在渲染过程中,一个缓冲区用于显示,一个用于渲染,一个用于备用。当渲染完成时,备用缓冲区变为渲染缓冲区,渲染缓冲区变为显示缓冲区,原来的显示缓冲区变为备用缓冲区。

2)除了 A 和 B 两个图层在交替显示,还有一个第三者 C 图层在不断帮A和B可能需要展示的数据进行缓冲。实际中只有在需要时,才会进行三重缓冲。正常情况下,只使用二重缓冲。

2)缓冲区不是越多越好。

4.当GPU的帧率高于显示器的刷新率时,可能出现一个刷新周期内GPU生成多帧数据的情况,从而造成画面撕裂。为解决这一问题,使用多重缓冲来同步GPU帧率和显示器刷新率。






微风不燥,阳光正好,你就像风一样经过这里,愿你停留的片刻温暖舒心。

我是程序员小迷(致力于C、C++、Java、Kotlin、Android、iOS、Shell、JavaScript、TypeScript、Python等编程技术的技巧经验分享),若作品对您有帮助,请关注、分享、点赞、收藏、在看、喜欢,您的支持是我们为您提供帮助的最大动力。

欢迎关注。助您在编程路上越走越好!

相关文章

JavaGUI——Java图形用户界面

1、Java GUI 概述GUI(Graphical User Interface,简称 GUI,图形用户界面)是指采用图形方式显示的计算机操作用户界面,与早期计算机使用的命令行界面相比,图形界面对于...

8款主流Java开发工具详解(99%人都在使用)

优秀的Java开发工具可以极大的提升我们的开发效率,所以今天给大家推荐一波必备Java开发工具@mikechen本篇已收于mikechen原创超30万字《阿里架构师进阶专题合集》里面。Java开发环境...

Java设计模式之外观模式

一、外观模式介绍1.1 外观模式定义外观模式( Facade Pattern),也叫门面模式, 外观模式的原始定义是:为子系统中的一组接口提供统一的接口。它定义了一个更高级别的接口,使子系统更易于使用...

一些JDK自带的性能分析利器

有时候碰到服务器CPU飙升或者程序卡死之类的问题,一般都不太好定位。这类bug一般都隐藏的比较深并且还可能是偶发性的,比较棘手。对于此类问题,一般我们都有固定的分析流程。借助于JDK自带的一些分析工具...

字节跳动一面,介绍一下什么是观察者模式?如何实现观察者模式?

观察者模式,属于行为模式的一种,定义了一种一对多的依赖关系,可以让多个观察者同时监听某个主题对象,当这个主题对象的状态发生变化的时候,就会通知所有的观察者对象,然后这些观察者对象就会自动更新自己。观察...

Portainer-ce图形化界面

注意:Portainer官方是没有中文界面的官方地址:https://www.portainer.io/ 项目地址:https://github.com/portainer/portainer# 拉取...