原创文章,转载注明出处,多谢合作。
代码使用Android 9.0, debug APP冷启动流程。
调试具体应用的冷启动: adb shell am set-debug-app -w
源码流程:
从ViewRootImpl #setView 开始:
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
...
enableHardwareAcceleration(attrs);//开启硬件加速
...
requestLayout();//开启traversal流程
...
}
这里RenderThread启动过程是从enableHardwareAcceleration开始的,下面一起来看看:
private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) {
...
//创建ThreadedRenderer
mAttachInfo.mThreadedRenderer = ThreadedRenderer.create(mContext, translucent,
attrs.getTitle().toString());
...
if (mAttachInfo.mThreadedRenderer != null) {
mAttachInfo.mHardwareAccelerated =
mAttachInfo.mHardwareAccelerationRequested = true; //mHardwareAccelerated赋值为true
}
}
}
}
通过attrs判断是否开启硬件加速, 如果要开启,从ThreadedRenderer.create开始
frameworks/base/core/java/android/view/ThreadedRenderer.java
public static ThreadedRenderer create(Context context, boolean translucent, String name) {
ThreadedRenderer renderer = null;
if (isAvailable()) {
renderer = new ThreadedRenderer(context, translucent, name);
}
return renderer;
}
create方法: 初始化了ThreadedRenderer。
再看ThreadedRenderer构造方法:
ThreadedRenderer(Context context, boolean translucent, String name) {
final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
...
long rootNodePtr = nCreateRootRenderNode(); //创建RenderNode
mRootNode = RenderNode.adopt(rootNodePtr);
mNativeProxy = nCreateProxy(translucent, rootNodePtr); //创建RenderProxy
...
}
这里要了解的是:
Window : ViewRootImpl : ThreadedRenderer : RootRenderNode : RenderProxy : CanvasContext : OpenGLRenderer 都是唯一的一一对应的.
UI元素traversal 过程是在应用主线程, 而真正绘制成多边形和纹理的过程是在RendoerThread中进行的, 并且一个拥有窗口的进程,必然有且只有一个RendoerThread子线程.
在ThreadedRenderer的构造方法中,着重分析下 nCreateRootRenderNode() 和 nCreateProxy(translucent, rootNodePtr)
nCreateRootRenderNode是个Native方法,对应:
frameworks/base/core/jni/android_view_ThreadedRenderer.cpp
static const JNINativeMethod gMethods[] = {
...
{ "nCreateRootRenderNode", "()J", (void*) android_view_ThreadedRenderer_createRootRenderNode },
{ "nCreateProxy", "(ZJ)J", (void*) android_view_ThreadedRenderer_createProxy },
...
}
分别对应的方法(JNI过程):
static jlong android_view_ThreadedRenderer_createRootRenderNode(JNIEnv* env, jobject clazz) {
RootRenderNode* node = new RootRenderNode(env);
node->incStrong(0);
node->setName("RootRenderNode");
return reinterpret_cast(node);
}
这里初始化了一个RootRenderNode
static jlong android_view_ThreadedRenderer_createProxy(JNIEnv* env, jobject clazz,
jboolean translucent, jlong rootRenderNodePtr) {
RootRenderNode* rootRenderNode = reinterpret_cast(rootRenderNodePtr);
ContextFactoryImpl factory(rootRenderNode);
return (jlong) new RenderProxy(translucent, rootRenderNode, &factory);
}
这里初始化了一个RenderProxy
frameworks/base/libs/hwui/renderthread/RenderProxy.cpp
RenderProxy::RenderProxy(bool translucent, RenderNode* rootRenderNode,
IContextFactory* contextFactory)
: mRenderThread(RenderThread::getInstance()), mContext(nullptr) {
mContext = mRenderThread.queue().runSync([&]() -> CanvasContext* {
return CanvasContext::create(mRenderThread, translucent, rootRenderNode, contextFactory);
});
mDrawFrameTask.setContext(&mRenderThread, mContext, rootRenderNode);
}
RenderThread::getInstance() 初始化:
RenderThread& RenderThread::getInstance() {
static RenderThread* sInstance = new RenderThread();
gHasRenderThreadInstance = true;
return *sInstance;
}
CanvasContext::create 创建CanvasContext:
CanvasContext* CanvasContext::create(RenderThread& thread, bool translucent,
RenderNode* rootRenderNode, IContextFactory* contextFactory) {
auto renderType = Properties::getRenderPipelineType();
switch (renderType) {
case RenderPipelineType::OpenGL:
return new CanvasContext(thread, translucent, rootRenderNode, contextFactory,
std::make_unique(thread));
case RenderPipelineType::SkiaGL:
return new CanvasContext(thread, translucent, rootRenderNode, contextFactory,
std::make_unique(thread));
case RenderPipelineType::SkiaVulkan:
return new CanvasContext(thread, translucent, rootRenderNode, contextFactory,
std::make_unique(thread));
default:
LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t)renderType);
break;
}
return nullptr;
}
9.0版本在这里走的是SkiaGL , 对应的RenderPipeline是SkiaOpenGLPipeline .
一张图总结下整个enableHardwareAcceleration过程如下所示:(一系列的初始化工作)
RenderThread: 渲染线程. 单例, 绘制操作都以RenderTask的形式post到RenderThread中完成。
CanvasContext: 绘制上下文 给到GPU的绘图命令都绘制在各自的上下文中,同步UIThread的绘制数据,以及执行绘制操作的工作都交给它来完成。.
RootRenderNode:应用层的View tree到Native层会由RenderNode tree来一一对应。RenderNode也就是Native层对View的封装。而RootRenderNode就是根。