Android 14 HWUI 源码研究 View Canvas RenderThread ViewRootImpl skia

HWUI 整体架构

HWUI主要功能是完成应用程序可视化元素绘制,核心代码位于framework c++层,承接Java层View绘制信息,开启进程唯一的渲染线程,借用skia绘制能力,完成渲染。

整体模块流程

Application-Activity-HWUI层级关系

注意:一个进程对应唯一的渲染线程,UI线程和渲染线程有个同步操作。

HWUI核心类和层级关系

容易混淆的Canvas关系

理解的核心:Canvas用来收集View的绘制信息,为了解耦才搞得这么多名字。

Canvas层级和对应关系

Java层两类Canvas:RecordingCanvas和Canvas。

  • RecordingCanvas直接对应C++层SkiaRecordingCanvas,SkiaRecordingCanvas实际使用RecordingCanvas记录指令
  • Canvas直接对应C++层SkiaCanvas,SkiaCanvas直接引用SkCanvas。
  • RecordingCanvas纯做指令记录

重要对象创建入口:

最左侧给出源码层面各主要对象调用入口。

()表示构造函数里创建右侧对象。

xx()表示正常函数里调用创建右侧对象。

其它:

RecordingCanvas负责指令记录动作,RenderNode 负责保存指令记录结果和渲染属性。

RenderProxy RenderThread CanvasContext IRenderPipeline负责指令渲染

全局大循环

协作关系:

细节待补充:Activity PhoneWindow WindowManagerGlobal DecorView ViewRootImpl

Window和View体系区别:

DecorView是View根节点,activity setContentView是DecorView子节点

ViewRootImpl衔接Window和View,并且负责View更新、渲染。

View相关的几大流程:

new Activity() -> attach() -> new PhoneWindow()待补充细化,对应"开始1 "

addView把View添加到渲染线程,待补充细节,对应"开始2"

performTranversals()

全局刷新流程,包含measure layout draw复杂子流程

performDraw()

触发指令记录和指令渲染流程

* beginRecording 创建Java::RecordingCanvas和C++::SkiaRecordingCanvas * updateRootDisplayList() 触发指令录制动作,用RecordingCanvas完成View到DisplayList转换 * endRecording() 把SkiaRecordingCanvas记录的指令,统一转存到RenderNode里

* syncAndDrawFrame() 指令线程同步和渲染。涉及到C++层RenderProxy RenderThread DrawFrameTask CanvasContext重要对象

渲染线程创建流程和核心对象

RenderProxy衔接Java层信息

RenderThread进程唯一的渲染线程

DrawFrameTask一帧绘制逻辑

CanvasContext负责一帧具体的绘制

指令记录流程

核心是把View的属性和绘制信息,通过C++层RecordingCanvas记录到DisplayList中

指令同步流程

指令渲染流程

Surface -> ANativeWindow -> EGLSurface画布创建流程

  • 初始化入口在ViewRootImpl.performTraversals()大函数里
  • 为什么用ReliableSurface封装一下,没深入研究
  • EGL和Skia环境创建主要在RenderThread.requireGlContext()函数
  • 从源码分析,一共三个地方地方调用requireGlContext()

View树和RenderNode树

类协作关系

协作

  • 一个Application进程,对应多个Activity,一个Activity一一对应PhoneWindow
  • PhoneWindow唯一持有一个DecorView
  • DecorView一一对应ViewRootImpl
  • ViewRootImpl创建并持有ThreadedRender
  • ThreadedRender与C++层RenderProxy一一对应
  • RenderProxy负责渲染代理,持有三个重要对象RenderThread、CanvasContext、DrawFrameTask
  • RenderThread是渲染线程,是单态模式,进程唯一
  • Activity.setContentView() -> PhoneWindow.setContentView(),把View挂到DecorView子节点上。
  • WindowManagerImpl.addView()设置给ViewRootImpl,并与ThreadedRender模块对接

RenderNode

  • 用于保存渲染属性和渲染指令
  • mStagingProperties和mStagingDisplayList只在MainThread修改
  • mProperties和mDisplayList只在RenderThread使用
  • 数据同步发生在DrawFrameTask的run()函数,详见"指令同步"小节

其它:

PhoneWindow DialogWindow SubMenuWindow ---> Window

PhoneWindow是Activity和View交互中间层,帮助Activity管理View

RenderPipeline模块

执行渲染模块相对结构清晰,重点关注:

  • makeCurrent()
  • draw()
  • swapBuffers()

Native Canvas关系

  • SkiaRecordingCanvas起到桥接作用,对上接收Java api调用
  • RecordingCanvas完成Op记录
  • DisplayListData真正存储Op的地方

skia核心资源三个使用场景

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