在Android 5.0之前,Android应用程序的主线程同时也是一个Open GL线程。但是从Android 5.0之后,Android应用程序的Open GL线程就独立出来了,称为Render Thread.

Android系统的UI从绘制到显示到屏幕是分两步进行的:第一步是在Android应用程序进程这一侧进行的;第二步是在SurfaceFlinger进程这一侧进行的。前一步将UI绘制到一个图形缓冲区中,并且将该图形缓冲区交给后一步进行合成以及显示在屏幕中。其中,后一步的UI合成一直都是以硬件加速方式完成的

注:在3.0前,Android应用程序UI绘制不支持硬件加速。不过从4.0开始,Android系统一直以“run fast, smooth, and responsively”为目标对UI进行优化。 注意,上面我们说Android系统不支持硬件加速的UI 绘制,针对的是Android应用程序2D UI绘制;  对于3D UI,例如游戏,一直是支持硬件加速渲染的。

在支持Android应用程序UI硬件加速渲染之前,Android应用程序UI的绘制是以软件方式进行的,为了更好地理解Android应用程序UI硬件加速渲染技术,我们先回顾在Android应用程序窗口(Activity)实现框架简要介绍和学习计划这个系列的文章提及的软件渲染技术,如图1所示:

图1 Android应用程序UI软件渲染过程

在Android应用程序进程这一侧,每一个窗口都关联有一个Surface。每当窗口需要绘制UI时,就会调用其关联的Surface的成员函数lock获得一个Canvas,其本质上是向SurfaceFlinger服务Dequeue一个Graphic Buffer。Canvas封装了由Skia提供的2D UI绘制接口,并且都是在前面获得的Graphic Buffer上面进行绘制的。绘制完成之后,Android应用程序进程再调用前面获得的Canvas的成员函数unlockAndPost请求显示在屏幕中,其本质上是向SurfaceFlinger服务Queue一个Graphic Buffer,以便SurfaceFlinger服务可以对Graphic Buffer的内容进行合成,以及显示到屏幕上去。

接下来我们再来看Android应用程序UI硬件加速渲染技术,如图2所示:

图2 Android应用程序UI硬件加速渲染过程

从图2可以看到,硬件加速渲染和软件渲染一样,在开始渲染之前,都是要先向SurfaceFlinger服务Dequeue一个Graphic Buffer。不过对硬件加速渲染来说,这个Graphic Buffer会被封装成一个ANativeWindow,并且传递给Open GL进行硬件加速渲染环境初始化。在Android系统中,ANativeWindow和Surface可以是认为等价的,只不过是ANativeWindow常用于Native层中,而Surface常用于Java层中。另外,我们还可以将ANativeWindow和Surface看作是像Skia和Open GL这样图形渲染库与操作系统底层的图形系统建立连接的一个桥梁。

Open GL获得了一个ANativeWindow,并且进行了硬件加速渲染环境初始化工作之后,Android应用程序就可以调用Open GL提供的API进行UI绘制了,绘制出来内容就保存在前面获得的Graphic Buffer中。当绘制完毕,Android应用程序再调用libegl库提供的一个eglSwapBuffer接口请求将绘制好的UI显示到屏幕中,其本质上与软件渲染过程是一样的,都是向SurfaceFlinger服务Queue一个Graphic Buffer,以便SurfaceFlinger服务可以对Graphic Buffer的内容进行合成,以及显示到屏幕上去。

这里我们首先要明确什么是硬件加速渲染,其实就是通过GPU来进行渲染。GPU作为一个硬件,用户空间是不可以直接使用的,它是由GPU厂商按照Open GL规范实现的驱动间接进行使用的。也就是说,如果一个设备支持GPU硬件加速渲染,那么当Android应用程序调用Open GL接口来绘制UI时,Android应用程序的UI就是通过硬件加速技术进行渲染的。因此,在接下来的描述中,我们提及到GPU、硬件加速和Open GL时,它们表达的意思都是等价的。

(一) Android应用程序UI硬件加速渲染技术简要介绍和学习计划

(二)Android应用程序UI硬件加速渲染环境初始化过程分析

主线程MainThread与渲染线程RenderThread的更多相关文章

  1. Libgdx多线程与渲染线程

    http://www.leestorm.com/post/115.html ——————————————————————————————————————————————————————————‘ 大部 ...

  2. UE4里的渲染线程

    记的上次看过UniRx里的源代码,说是参考微软的响应式编程框架,响应式编程里的一些理论不细说,只单说UniRx里的事件流里的事件压入与执行,与UE4的渲染线程设计有很多相同之处,如果有了解响应式编程相 ...

  3. (转\整)UE4游戏优化 多人大地型游戏的优化(二)渲染线程的优化

    施主分享随缘,评论随心,@author:白袍小道 小道暗语: 1.因为小道这里博客目录没自己整,暂时就用随笔目录结构,所以二级目录那啥就忽略了.标题格式大致都是(原or转) 二级目录 (标题) 2.因 ...

  4. (转)electron主线程中通过mainWindow.webContents.send发送事件,渲染线程接收不到

    转自 https://segmentfault.com/q/1010000015599245/ 准备实现的功能: 页面1(渲染进程1)中点击按钮,发送事件给到主进程.主进程成功接收事件后,通过main ...

  5. UE4-PS4开发渲染线程优化方法及记录

    先说方法: Launch 到 PS4 Devkit上,在PS4上输入Stat unit 看瓶颈在哪里.我们发现Frame 和Draw数值几乎一样,其余两项相对较小,这表明瓶颈在渲染线程上. 关于渲染线 ...

  6. python 线程(其他方法,队列,线程池,协程 greenlet模块 gevent模块)

    1.线程的其他方法 from threading import Thread,current_thread import time import threading def f1(n): time.s ...

  7. Python之线程 2 - Python实现线程

    一 python与线程 1.全局解释器锁GIL(用一下threading模块之后再来看~~) 2.python线程模块的选择 二 Threading模块 1.线程创建 2.多线程与多进程 3.多线程实 ...

  8. RxJava 操作符 on和doOn 线程切换 调度 Schedulers 线程池 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  9. Java中的线程状态转换和线程控制常用方法

    Java 中的线程状态转换: [注]:不是 start 之后就立刻开始执行, 只是就绪了(CPU 可能正在运行其他的线程). [注]:只有被 CPU 调度之后,线程才开始执行, 当 CPU 分配给你的 ...

随机推荐

  1. Y2161 Hibernate第三次考试 2016年8月18日 试卷分析

  2. avalon.js路由

    之前自己写了一个AJAX加载页面的方法:有时候一个页面里面会分区域加载不同的东西(div,html),但是IE的回退按钮,就失去任何意义了: 这两天研究了一下avalon.js的路由: 需要准备: 1 ...

  3. Mysql连接错误:Lost connection to Mysql server at 'waiting for initial communication packet'

    在远程连接mysql的时候,连接不上,出现如下报错:Lost connection to MySQL server at 'waiting for initial communication pack ...

  4. cpu负载和利用率

    理解Linux系统负荷 linux里的CPU负载

  5. Power of Two

    Given an integer, write a function to determine if it is a power of two. bool isPowerOfTwo(int n) { ...

  6. crontab小结

    crontab是linux下的计划任务,可以用来定时或者按计划运行命令. 创建计划任务: 1.使用crontab -e命令,直接创建计划任务 2.使用编辑器编写好计划任务的文件后,再使用crontab ...

  7. Android -- ActivityLifeCycleCallbacks

    ActivityLifeCycleCallbacks Application通过此接口提供了一套回调方法,用于让开发者对Activity的生命周期事件进行集中处理. 为什么用ActivityLifec ...

  8. swift调用oc语言文件,第三方库文件或者自己创建的oc文件——简书作者

    Swift是怎样调用OC的第三方库的呢?请看下面详情: 情况一: 1.首先打开Xcode,iOS->Application->Single View Application, 选Next. ...

  9. 爱春秋之戏说春秋 Writeup

    爱春秋之戏说春秋 Writeup 第一关 图穷匕见 这一关关键是给了一个图片,将图片下载到本地后,打开以及查看属性均无任何发现,尝试把图片转换为.txt格式.在文本的最后发现这样一串有规律的代码: 形 ...

  10. DTCMS插件的制作实例电子资源管理(二)Admin后台页面编写

    总目录 插件目录结构(一) Admin后台页面编写(二) 前台模板页编写(三) URL重写(四) 本实例旨在以一个实际的项目中的例子来介绍如何在dtcms中制作插件,本系列文章非入门教程,部分逻辑实现 ...