Android9.0 硬件加速(二)-RenderThread线程的启动

原创文章,转载注明出处,多谢合作。

代码使用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
...
}

这里要了解的是:

  1. Window : ViewRootImpl : ThreadedRenderer : RootRenderNode : RenderProxy : CanvasContext : OpenGLRenderer 都是唯一的一一对应的.

  2. 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过程如下所示:(一系列的初始化工作)

Android9.0 硬件加速(二)-RenderThread线程的启动_第1张图片
RenderThread线程的启动过程

RenderThread: 渲染线程. 单例, 绘制操作都以RenderTask的形式post到RenderThread中完成。
CanvasContext: 绘制上下文 给到GPU的绘图命令都绘制在各自的上下文中,同步UIThread的绘制数据,以及执行绘制操作的工作都交给它来完成。.
RootRenderNode:应用层的View tree到Native层会由RenderNode tree来一一对应。RenderNode也就是Native层对View的封装。而RootRenderNode就是根。

你可能感兴趣的:(Android9.0 硬件加速(二)-RenderThread线程的启动)