码迷,mamicode.com
首页 > 其他好文 > 详细

RenderThread学习笔记

时间:2015-04-19 21:26:05      阅读:739      评论:0      收藏:0      [点我收藏+]

标签:

文章记录自己对RenderThread学习过程,供日后回顾。

我们知道5.0上为每个进程新增了一个RenderThread线程,这是一个附加的UI线程?我们通过学习这块代码来熟悉它。

第一部分:RenderThread线程的启动

RenderThread线程的启动过程如下图所示。

技术分享

涉及相关的类关系如下图:

技术分享

有两个注意点:①每一个窗口对应一个ViewRootImpl,每个ViewRootImpl都对应唯一的一个ThreadedRenderer、一个RootRenderNode、一个RenderProxy对象。②一个拥有窗口的进程,必然有且只有一个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)) {
            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();
            requestVsync();
        }

        if (!mFrameCallbackTaskPending && !mVsyncRequested && mFrameCallbacks.size()) {
            // TODO: Clean this up. This is working around an issue where a combination
            // of bad timing and slow drawing can result in dropping a stale vsync
            // on the floor (correct!) but fails to schedule to listen for the
            // next vsync (oops), so none of the callbacks are run.
            requestVsync();
        }
    }

    return false;
}

initThreadLocals()函数主要做一些初始化工作,调用流程如下如。主要包括与SurfaceFlinger的EventThread线程建立起连接、构建出一个接收Display Event事件框架、通过Looper.addFd()添加一个Display Event事件处理函数RenderThread::displayEventReceiverCallback()等工作。

技术分享

涉及相关的类关系如下:

技术分享

待续。






RenderThread学习笔记

标签:

原文地址:http://blog.csdn.net/guoqifa29/article/details/45131099

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!