Android 从Android3.0(API Level 11)开始就支持了硬件加速,在target api >= 14会默认开启,利用GPU代替CPU绘制,软加速是利用Skia,而硬件加速是利用OpenGL绘制。缺点是增加了内存占用。
本文只是在java层去看硬件加速,没有深究jni层如何绘制。
-
RenderNode 每个View都有一个RenderNode与之对应
-
RenderThread jin层会创建一个对应的线程,loop循环接收RenderNode
-
DisplayList jin层将DisplayListCanvas的操作转化到DisplayList
-
DisplayListCanvas java层上canvas缓存所有绘制操作,设置到RenderNode中
基本流程:
- UI线程负责构建操作DisplayList
- RenderThread线程利用OpenGL去绘制DisplayList的操作
参考之前的文章《View/ViewGroup 绘制流程和疑惑(一)》 可以了解整个View/ViewGroup/ViewRootImpl整体的绘制流程。
硬件加速的绘制流程基本上是一致的,只不过在draw流程上有不同的分歧点。
我们知道,子View的invalidate标记dirty区域,借由着ViewParent的invalidateChildInParent(int[] location, Rect dirty),到顶层的DecorView,最后触发了ViewRootImpl的invalidateChildInParent(),引起schedualTraversals()。
在文章《Android 屏幕刷新机制》讲过Vsync信号到来的时候,才会引起ViewRootImpl的preformTraversals()流程到draw()。
ThreadedRender初始化
在添加窗口WindowManagerGlobal.addView()会调用ViewRootlImpl的setView()
// WindowManagerGlobal
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
root.setView(view, wparams, panelParentView);
}
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
if (mSurfaceHolder == null) {
enableHardwareAcceleration(attrs);
}
}
private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) {
mAttachInfo.mHardwareAccelerated = false;
mAttachInfo.mHardwareAccelerationRequested = false;
// 根据标记位,判断是否要硬件加速
final boolean hardwareAccelerated =
(attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
if (hardwareAccelerated) {
// 是否支持硬件加速:判断是否支持OpenGL
if (!ThreadedRenderer.isAvailable()) {
return;
}
if (!ThreadedRenderer.sRendererDisabled
|| (ThreadedRenderer.sSystemRendererDisabled && forceHwAccelerated)) {
if (mAttachInfo.