Android GPU硬件加速渲染流程(上)

本文是Android GPU硬件加速渲染流程的上篇,主要介绍了基本概念,包括Window、View及其关系,详细阐述了软件绘制的流程,包括Activity窗口的绘制步骤和软件绘制过程。此外,探讨了何时使用软件绘制,并分析了硬件加速渲染环境的初始化,特别是SurfaceView、SurfaceTexture、TextureView和GLSurfaceView的区别与联系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录
收起
1、基本概念
1.1 Window(窗口):
1.2 View(视图):
1.3 Window与View之间关系
2. 软件绘制
2.1 Actvity窗口绘制流程
2.2软件绘制流程
2.3何时使用软件绘制
3硬件绘制
3.1 硬件绘制流程
3.2 硬件加速渲染的环境初始化过程分析
3.2.1 MainThread和RenderThread的分离
3.2.1.1 SurfaceView简介
3.2.1.2 SurfaceTexture、TextureView、GLSurfaceview的区别与联系
3.2.2 OpenGL环境初始化
3.2.3 系统预加载资源地图集
本文希望通过两篇文章,详细介绍Android上层的硬件加速渲染流程,大约2万字,此为上篇。

1、基本概念
1.1 Window(窗口):
Android窗口主要分为两种:

1)一是应用窗口:一个activity有一个主窗口,弹出的对话框也有一个窗口,Menu菜单也是一个窗口。在同一个activity中,主窗口、对话框、Menu窗口之间通过该activity关联起来。

和应用相关的窗口表示类是PhoneWindow,其继承于Window,针对手机屏幕做了一些优化工作,里面核心的是mDecorView这个变量,mDecorView是一个顶层的View,窗口的添加就是通过调用getDecorView()获取到mDecorView并且调WindowManager.addView()把该View添加到WindowManager中。但也有例外,比如悬浮窗口虽然与activity相关联,但并不是PhoneWindow,直接调用通过WindowManager.addView()添加。

如果我们想给所有的应用都加一个比如最大、最小化、关闭的导航条,那只需更改mDecorView即可(Android N为支持多窗口将DecorView从PhoneWindow中分离成一个单独的文件)。

2)二是公共界面的窗口:如最近运行对话框、关机对话框、状态栏下拉栏、锁屏界面等。这些窗口都是系统级别的窗口,不从属于任何应用,和activity没有任何关系。这种窗口没有任何窗口类来封装,也是直接调用WindowManager.addView()来把一个view添加到WindowManager中。

1.2 View(视图):

  1. <RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
  2. xmlns:tools=“http://schemas.android.com/tools”
  3. android:layout_width=“match_parent”
  4. android:layout_height=“match_parent”
  5. tools:context=“com.example.firstapp.MainActivity” >
  6. <TextView
  7. android:layout_width=“wrap_content”
  8. android:layout_height=“wrap_content”
  9. android:text=“@string/hello_world” />

从一个简单的layout说起,其包含2个View:RelativeLayout、TextView,其中RelativeLayout为ViewGroup,TextView为窗口控件,直接继承View,它们是以树形结构组织在一起形成整个窗口的UI的。(如果作为应用窗口,还隐形包括一个DecorView)

图1 应用窗口结构示意图以及DecorView、TextView的类关系图
1.3 Window与View之间关系
应用客户端:Window(可包含多个View,一个PhoneWindow对应一个DecorView)

Framework客户端: ViewRootImpl,(同一应用多个窗口可能共用WindowManager,比如dialog的mWindowManager变量其实就是Activity对象的mWindowManager变量,从而获得mParentWindow,从而与Activity相关联http://blog.csdn.net/mr_liabill/article/details/49966479 )

Framework服务端:WindowState

SurfaceFlinger 客户端:Surface(SurfaceControl与Surface 一一对应,是其内部变量)

SurfaceFlinger 服务端:Layer

上述Window -> ViewRootImpl -> WindowState -> Surface -> Layer 是一一对应的。

一般的Activity包括的多个View会组成View hierachy的树形结构,只有最顶层的DecorView,也就是根结点视图,才是对WMS可见的,即有对应的Window和WindowState

一个应用程序窗口分别位于应用程序进程和WindowManagerService服务中的两个Surface对象有什么区别呢?虽然它们都是用来操作位于SurfaceFlinger服务中的同一个Layer对象的,不过,它们的操作方式却不一样。具体来说,就是位于应用程序进程这一侧的Surface对象负责绘制应用程序窗口的UI,即往应用程序窗口的图形缓冲区填充UI数据,而位于WindowManagerService服务这一侧的Surface对象负责设置应用程序窗口的属性,例如位置、大小等属性。这两种不同的操作方式分别是通过C++层的Surface对象和SurfaceControl对象来完成的,因此,位于应用程序进程和WindowManagerService服务中的两个Surface对象的用法是有区别的。之所以会有这样的区别,是因为绘制应用程序窗口是独立的,由应用程序进程来完即可,而设置应用程序窗口的属性却需要全局考虑,即需要由WindowManagerService服务来统筹安排。

SurfaceFlinger中Layer主要的任务是合成,其内容已经由客户端绘制完成,使用GPU合成则调用其OnDraw函数,使用Display合成该函数是不会调用的,仅仅设置一下位置大小传递给hwcomposer即可。Layer内容更新由Layer的成员变量mSurfaceFlingerCounsumer->updateTexImage完成(GLCounsumer的默认updateTexImage是需要绑定纹理的),SurfaceFlingerCounsumer覆盖了该函数,其只是通过acquireBuffer更新一下buffer,具体绑定纹理是在OnDraw完成的,对于非GPU合成的Layer来说OnDraw不会调用也就不会绑定纹理,其在SurfaceFlinger中的工作量相对是很少的。

其中一个窗口从添加到显示可用以下时序图2表示:

图2 窗口显示时序图
其中addView的调用流程如图3,其中scheduleTraversals会注册一个VSYNC等待刷帧:

  1. mChoreographer.postCallback(
  2. Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
    Vsync的回调函数最终会调用performTraversals,其分为三步,分别是测量performMesure、布局performLayout和绘制performDraw。

图3 addView时序图
通过系统的Systrace我们可以看下Setting应用的简单调用关系,其中Choreographer#doFrame即是Vsync的回调函数,真正负责绘制的也并不是主线程,而是RenderThread,这也是硬件绘制的一个标志,后面会详细介绍。

图4 Setting应用启动的Systrace
2. 软件绘制
2.1 Actvity窗口绘制流程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值