当前位置: 首页 > article >正文

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)”

在这里插入图片描述
持续更新中。。。

相关文章:

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

在 Android 系统中,Surface 和 SurfaceFlinger 是图形渲染系统的核心组件,负责屏幕显示内容的合成与管理。它们协同工作,使各种 App 和系统界面能够高效地显示在屏幕上。 1 Surface 是什么? Surface 是一个抽象的图形缓冲区接口…...

SpringBoot核心注解详解及3.0与2.0版本深度对比

SpringBoot核心注解详解及3.0与2.0版本深度对比 本文全面解析SpringBoot核心注解原理,深入对比3.0与2.0版本差异,助你掌握新一代SpringBoot开发精髓 一、SpringBoot核心注解全景解析 1.1 什么是SpringBoot核心注解 SpringBoot核心注解是构建SpringBoot…...

敏捷开发中如何避免过度加班

在敏捷开发过程中避免过度加班,需要明确敏捷原则、合理规划迭代任务、加强团队沟通、优化流程效率、设定合理的工作负荷、注重团队士气和成员健康。明确敏捷原则,即保证可持续发展的步调,避免频繁地变更需求、过度承诺任务量。合理规划迭代任…...

深入浅出多路归并:原理、实现与实战案例解析

文章目录 二路归并多路归并方法一:指针遍历(多指针比较法)方法二:小根堆法(最小堆归并) 实际场景外部排序 经典题目丑数Ⅱ方法一:三指针法方法二:优先队列法(K路归并&…...

Java八股文——集合「Map篇」

Map 面试官您好,关于 Java 中常见的 Map 集合,我可以从非线程安全和线程安全两个方面来介绍: 首先,我们来看一下非线程安全的 Map 实现,这些在单线程环境下性能通常更好,但在并发场景下需要外部同步&…...

第1章_数据分析认知_知识点笔记

来自:数据分析自学课程-戴戴戴师兄 逐字稿:【课程4.0】第1章_分析认知_知识点笔记 【课程4.0】第1章 分析认知 知识点总结 数据分析的核心价值不是工具,而是用数据驱动业务增长。 一、数据分析的本质认知 数据分析是什么? 不是酷…...

111页可编辑精品PPT | 华为业务变革框架及战略级项目管理华为变革管理华为企业变革华为的管理模式案例培训

这份文档是关于华为公司业务变革管理框架(BTMS)V2.0的详细介绍,涵盖从年度规划到项目执行的全流程管理。BTMS框架通过变革战略规划、年度规划流程、解决方案开发(PMOP流程)、运作管理流程等多个模块,系统地…...

Python使用总结之Mac安装docker并配置wechaty

Python使用总结之Mac安装docker并配置wechaty ✅ 一、安装 Docker Desktop for macOS 1. 下载 Docker Desktop 安装包 访问官网下载安装包: 👉 https://www.docker.com/products/docker-desktop 选择 macOS (Apple 芯片或 Intel 芯片) 版本下载。 …...

html文字红色粗体,闪烁渐变动画效果

1. 代码 <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>红色粗体闪烁文字表格</title><s…...

进阶配置与优化:配置 HTTPS 以确保数据安全传输

在生产环境中&#xff0c;确保用户与服务器之间的数据传输安全至关重要。配置 HTTPS&#xff08;HTTP Secure&#xff09;可以通过使用 SSL/TLS 协议对数据进行加密&#xff0c;防止数据在传输过程中被窃听或篡改。本文将详细介绍如何使用 Let’s Encrypt 免费获取 SSL 证书&am…...

Python使用clickhouse-local和MySQL表函数实现从MySQL到ClickHouse数据同步

下面是一个使用clickhouse-local和MySQL表函数实现从MySQL到ClickHouse数据同步的Python解决方案&#xff0c;包含全量同步、增量同步和测试用例。 此解决方案提供了生产级数据同步所需的核心功能&#xff0c;可根据具体场景扩展更多高级特性如&#xff1a;数据转换、字段映射…...

解锁Java线程池:性能优化的关键

一、引言 在 Java 并发编程的世界里&#xff0c;线程池是一个至关重要的概念。简单来说&#xff0c;线程池就是一个可以复用线程的 “池子”&#xff0c;它维护着一组线程&#xff0c;这些线程可以被重复使用来执行多个任务&#xff0c;而不是为每个任务都创建一个新的线程。​…...

如何自定义一个 Spring Boot Starter?

导语&#xff1a; 在后端 Java 面试中&#xff0c;Spring Boot 是绕不开的重点&#xff0c;而“如何自定义一个 Starter”作为进阶开发能力的体现&#xff0c;常被面试官用于考察候选人的工程架构思维与 Spring Boot 底层掌握程度。本文将带你深入理解自定义 Starter 的实现逻辑…...

Linux文件系统详解:从入门到精通

无论是开发高性能应用还是进行系统级编程&#xff0c;文件系统都是我们必须掌握的基础知识。今天&#xff0c;我将带大家深入浅出地了解Linux文件系统的核心概念和工作原理。 一、Linux文件系统概述 Linux文件系统是操作系统中负责管理持久存储设备上数据的子系统。它不仅仅是…...

Electron Fiddle使用笔记

文章目录 下载界面示意图保存和打开项目save 和 save as forge project 其他文档打包报错 RequestError: read ECONNRESET 想要打包前端程序&#xff0c;奈何本地环境总是报错&#xff0c;意外发现可以通过electron fiddle直接调试代码。 下载 百度网盘地址&#xff1a; 首次…...

【PhysUnits】16.1 完善Var 结构体及其运算(variable.rs)

一、源码 这段代码定义了一个泛型结构体 Var&#xff0c;并为它实现了各种数学运算。 /** 变量结构体 Var* 该结构体泛型参数 T 需满足 Numeric 约束*/use core::ops::{Neg, Add, Sub, Mul}; use crate::constant::Integer; /// 定义 Numeric trait&#xff0c;约束 T 必须实…...

企业培训学习考试系统源码 ThinkPHP框架+Uniapp支持多终端适配部署

在数字化转型浪潮下&#xff0c;企业对高效培训与精准考核的需求日益迫切。一套功能完备、多终端适配且易于定制的培训学习考试系统&#xff0c;成为企业提升员工能力、检验培训成果的关键工具。本文给大家分享一款基于 ThinkPHP 框架与 Uniapp 开发的企业培训学习考试系统&…...

C++ if语句完全指南:从基础到工程实践

一、选择结构在程序设计中的核心地位 程序流程控制如同城市交通网络&#xff0c;if语句则是这个网络中的决策枢纽。根据ISO C标准&#xff0c;选择结构占典型项目代码量的32%-47%&#xff0c;其正确使用直接影响程序的&#xff1a; 逻辑正确性 执行效率 可维护性 安全边界 …...

SpringBoot手动实现流式输出方案整理以及SSE规范输出详解

背景&#xff1a; 最近做流式输出时&#xff0c;一直使用python实现的&#xff0c;应需求方的要求&#xff0c;需要通过java应用做一次封装并在java侧完成系统鉴权、模型鉴权等功能后才能真正去调用智能体应用&#xff0c;基于此调研java实现流式输出的几种方式&#xff0c;并…...

深入解析I²C总线接口:从基础到应用

IC总线概述与基本概念 一句话概述&#xff1a;本章节将介绍IC总线的历史、定义及其在嵌入式系统中的作用&#xff0c;帮助读者建立对IC的基本理解。 IC&#xff08;Inter-Integrated Circuit&#xff09;总线是一种广泛应用于嵌入式系统中的串行通信协议&#xff0c;最初由飞利…...

Sklearn 机器学习 缺失值处理 检测数据每列的缺失值

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在代码与灵感交织的数字世界里和大家相遇~💖 ✨ 在这个技术浪潮奔涌的时代,我们既是探索者,也是分享者。我始终相信,每一行代码都是通往创新的钥匙,而分享则能让这把钥匙照亮更多人的…...

Unity基于GraphView的可视化关卡编辑器开发指南

一、GraphView技术基础与应用场景 1. GraphView核心组件 组件功能描述关卡编辑应用GraphView画布容器关卡拓扑结构编辑区Node基础节点房间/敌人/道具等关卡元素Edge节点连接线路径/依赖关系Port连接端口入口/出口标记Blackboard属性面板元素参数配置Minimap缩略图导航大型关卡…...

STL解析——list的使用

目录 1.简介 2.构造函数 3.迭代器 3.1封装 3.2迭代器分类 4.排序性能 4.1链式与数组 4.2缓存读取 1.简介 STL容器中提供的list容器也是一种顺序容器&#xff0c;底层实现方式是带头双向链表&#xff0c;这种实现方式能比单链表更高效的访问数据。 下面围绕部分重要接口…...

华为大规模——重塑生产力

华为大模型通过以下几个方面重塑生产力&#xff1a; 提供强大算力支持 华为致力于构建领先的昇腾人工智能算力平台&#xff0c;推出高性能昇腾AI集群&#xff0c;支持月级长期稳定训练&#xff0c;可靠性业界领先。同时打造开放的昇腾计算平台&#xff0c;兼容主流算子、框…...

【Go面试陷阱】对未初始化的chan进行读写为何会卡死?

Go面试陷阱&#xff1a;对未初始化的chan进行读写为何会卡死&#xff1f;深入解析nil channel的诡异行为 在Go的世界里&#xff0c;var ch chan int 看似人畜无害&#xff0c;实则暗藏杀机。它不会报错&#xff0c;不会panic&#xff0c;却能让你的程序悄无声息地"卡死&qu…...

SpringBoot自动化部署实战技术文章大纲

技术背景与目标 介绍SpringBoot在现代开发中的重要性自动化部署的价值&#xff1a;提升效率、减少人为错误、实现CI/CD适用场景&#xff1a;中小型Web应用、微服务架构 自动化部署核心方案 基于Docker的容器化部署 SpringBoot应用打包为Docker镜像使用Docker Compose编排多容…...

软件项目管理(3) 软件项目任务分解

一、相关概念 1.任务分解的方法和步骤 &#xff08;1&#xff09;方法 模板参照方法&#xff1a;参照有标准或半标准的任分解结构图类比方法&#xff1a;任务分解结构图经常被重复使用&#xff0c;具有相似性自顶向下方法&#xff1a;一般->特殊&#xff0c;演绎推理从大…...

MQTTX连接阿里云的物联网配置

本文的目标是通过MQTTX的客户端&#xff0c;连接到阿里云的物联网的平台&#xff0c;发送温度信息&#xff0c;在阿里云的平台中显示出来。阿里云免费注册&#xff0c;免费有一个MQTT的服务器。有数量限制&#xff0c;但是对于测试来讲&#xff0c;已经足够。 1、注册阿里云的物…...

20250606-C#知识:匿名函数、Lambda表达式与闭包

C#知识&#xff1a;匿名方法、Lambda表达式与闭包 闭包乍一听感觉很复杂&#xff0c;其实一点也不简单 1、匿名方法 没有方法名的方法一般用于委托和事件 Func<int, int, int> myAction delegate(int a, int b) { return a b; }; Console.WriteLine( myAction(1, 2)…...

数字证书_CA_详解

目录 一、数字证书简介 二、 CA&#xff08;证书颁发机构&#xff09; (一) 证书链&#xff08;信任链&#xff09; 1. 根证书 2. 中间证书 3. 网站证书 (二) 抓包软件的证书链与信任机制 1. 抓包通信流程 2. 证书链伪造与信任验证流程 (三) 关于移动设备的CA 一、数…...