Android基础回顾】六:安卓显示机制Surface 、 SurfaceFlinger、Choreographer

在 Android 系统中,Surface 和 SurfaceFlinger 是图形渲染系统的核心组件,负责屏幕显示内容的合成与管理。它们协同工作,使各种 App 和系统界面能够高效地显示在屏幕上。

1 Surface 是什么?

Surface 是一个抽象的图形缓冲区接口,允许应用程序或系统组件将图像内容绘制进去,并最终显示在屏幕上。

我们可以把它理解为"一个可以绘图的画布",在内部由一系列 GraphicBuffer 组成(通常是3个),用于支持双缓冲/三缓冲机制。

1.1 典型使用场景

应用界面绘制(由 SurfaceView, TextureView 或 SurfaceHolder 提供)

视频播放(如 MediaPlayer 或 ExoPlayer 会使用 Surface)

摄像头预览

游戏引擎的 OpenGL 渲染输出

1.2 工作方式

Surface 提供 Canvas 或 OpenGL 接口供应用绘制。绘制完成后通过 unlockCanvasAndPost() 或 eglSwapBuffers() 提交 buffer。

提交的 buffer 会被传递给系统的 SurfaceFlinger 进行合成显示。

2 SurfaceFlinger 是什么?

SurfaceFlinger 是 Android 系统中的 系统服务(native daemon),负责合成所有应用窗口、系统窗口、状态栏、导航栏等图层,然后交由显示驱动(HWComposer)将最终图像送到屏幕。

它运行在 system_server 之外的 native 层(C++ 实现),是 Android 图形系统的大脑。

2.1 SurfaceFlinger 会做什么?

管理所有 Layer(每个应用窗口对应一个 Layer)

合成 Layer(可以用 GPU 或 HWC:Hardware Composer)

控制 VSYNC(垂直同步信号)

最终输出帧到显示屏幕

2.2 SurfaceFlinger 工作流程是什么样的?

3 Surface 与 SurfaceFlinger是怎么交互的?

这里重点是BufferQueue 机制,因为Surface 和 SurfaceFlinger 之间就是通过 BufferQueue 共享 buffer 数据的。

Producer:App 侧绘制内容,生产图像数据。

Consumer:SurfaceFlinger 侧消费图像数据,合成显示。

而BufferQueue 内部包含多缓冲机制,确保数据同步和绘制不卡顿。

从生产-消费角度看,整体流程是这样的:

4 Choreographer

Choreographer 是 Android 提供的一个类,用于监听 VSYNC 信号,并在合适的时机调度你的绘制、布局和动画操作。

它属于 Android 中非常关键的 帧调度器,负责协调应用绘制的时机,确保每一帧的动画或 UI 绘制都和 VSYNC 同步,从而实现流畅的用户体验。

整体流程

Q&A

Canvas 是什么?

Canvas 是 Android 提供的一套 2D 绘图 API,它允许开发者使用 Java/Kotlin 或 native C++ 来绘制图形,如线条、文字、图片、矩形、圆等。

可以把 Canvas 理解为一个"画布",你用画笔(Paint)在上面画图,最终会显示在屏幕上。

OpenGL 是什么?

OpenGL(Open Graphics Library) 是一个跨平台的 3D 图形绘制 API,Android 使用的是 OpenGL ES(嵌入式版本),用于实现更复杂、高性能的图形渲染,尤其是 3D 游戏和图形动画。

双缓冲/三缓冲机制是怎么样的?

显示系统绘制画面不是直接在屏幕上画,而是先画在内存中的缓冲区里,画完了再显示。这是为了避免中间画一半被用户看到(就是所谓的撕裂)。

什么是双缓冲,双缓冲 = 使用两个缓冲区来交替绘制和显示图像。

缓冲区 用途
前缓冲区(Front Buffer) 正在被显示器显示
后缓冲区(Back Buffer) 正在被应用绘制新的一帧

具体流程是这样的:

而三缓冲呢?

缓冲区 用途
Front Buffer 正在显示
Back Buffer 等待显示
Draw Buffer 正在绘制

流程:

VSYNC 信号是什么?有什么用?

VSYNC(Vertical Synchronization)信号 是显示器在每次刷新屏幕内容时发出的一个时钟信号,用来告诉图形系统:

"我马上要开始绘制下一帧了,你现在可以把新的画面准备好。"

假设如果没有 VSYNC(非同步),GPU 正在往屏幕写入新图像时,显示器可能已经开始显示帧A的一部分内容。下一帧B又来了,结果就是"撕裂(tearing)",屏幕上半部分显示的是上一帧,下半部分是下一帧。

有了 VSYNC(同步),系统所有绘制流程都会和显示器"节奏一致";画面更新整齐,滚动、动画更平滑。

但如果处理慢,可能会"掉帧(frame drop)"

持续更新中。。。

相关推荐
千里马学框架2 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台2 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone2 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc2 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo2 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077002 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼2 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone2 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen2 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone2 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui