文章记录自己对RenderThread学习过程,供日后回顾。
我们知道5.0上为每个进程新增了一个RenderThread线程,这是一个附加的UI线程?我们通过学习这块代码来熟悉它。
第一部分:RenderThread线程的启动
RenderThread线程的启动过程如下图所示。
涉及相关的类关系如下图:
有两个注意点:①每一个窗口对应一个ViewRootImpl,每个ViewRootImpl都对应唯一的一个ThreadedRenderer、一个RootRenderNode、一个RenderProxy对象。②一个RenderProxy对象又对应一个CanvasContext对象。③一个CanvasContext又对应一个OpenGLRenderer对象。④一个拥有窗口的进程,必然有且只有一个RenderThread子线程。
第二部分:RenderThread.threadLoop()分析
代码在 frameworks\base\libs\hwui\renderthread\RenderThread.cpp中。
bool RenderThread::threadLoop() {
setpriority(PRIO_PROCESS, 0, PRIORITY_DISPLAY);
initThreadLocals(); //初始化必要的环境信息。
int timeoutMillis = -1;
for (;;) {
int result = mLooper->pollOnce(timeoutMillis);
LOG_ALWAYS_FATAL_IF(result == Looper::POLL_ERROR,
"RenderThread Looper POLL_ERROR!");
nsecs_t nextWakeup;
// Process our queue, if we have anything
while (RenderTask* task = nextTask(&nextWakeup)) { //这个while循环会将当前时间点及之前的所有本该触发调用的RenderTask全部执行run()。nextWakeup为下一个RenderTask的触发调用时间点。
task->run();
// task may have deleted itself, do not reference it again
}
if (nextWakeup == LLONG_MAX) {
timeoutMillis = -1;
} else {
nsecs_t timeoutNanos = nextWakeup - systemTime(SYSTEM_TIME_MONOTONIC);
timeoutMillis = nanoseconds_to_milliseconds(timeoutNanos);
if (timeoutMillis < 0) {
timeoutMillis = 0;
}
}
if (mPendingRegistrationFrameCallbacks.size() && !mFrameCallbackTaskPending) {
drainDisplayEventQueue();
mFrameCallbacks.insert(
mPendingRegistrationFrameCallbacks.begin(), mPendingRegistrationFrameCallbacks.end());
mPendingRegistrationFrameCallbacks.clear();
版权声明:本文为guoqifa29原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。