Android应用开发之Android源码之SurfaceFlinger的启动(二)
白羽 2018-08-10 来源 :网络 阅读 805 评论 0

摘要:本文将带你了解Android应用开发之Android源码之SurfaceFlinger的启动(二),希望本文对大家学Android有所帮助

        本文将带你了解Android应用开发之Android源码之SurfaceFlinger的启动(二),希望本文对大家学Android有所帮助


page6
 我们看一下Thread的run函数的实现:
    1 status_t Thread::run(const char* name, int32_t priority, size_t stack)
    2 {
    3     Mutex::Autolock _l(mLock);
    4
    5     if (mRunning) {
    6         // thread already started
    7         return INVALID_OPERATION;
    8     }
    9
    10     // reset status and exitPending to their default value, so we can
    11     // try again after an error happened (either below, or in readyToRun())
    12     mStatus = NO_ERROR;
    13     mExitPending = false;
    14     mThread = thread_id_t(-1);
    15
    16     // hold a strong reference on ourself
    17     mHoldSelf = this;
    18
    19     mRunning = true;
    20
    21     bool res;
    22     if (mCanCallJava) {
    23         res = createThreadEtc(_threadLoop,
    24                 this, name, priority, stack, &mThread);
    25     } else {
    26         res = androidCreateRawThreadEtc(_threadLoop,
    27                 this, name, priority, stack, &mThread);
    28     }
    29
    30     if (res == false) {
    31         mStatus = UNKNOWN_ERROR;   // something happened!
    32         mRunning = false;
    33         mThread = thread_id_t(-1);
    34         mHoldSelf.clear();  // "this" may have gone away after this.
    35
    36         return UNKNOWN_ERROR;
    37     }
    38
    39     // Do not refer to mStatus here: The thread is already running (may, in fact
    40     // already have exited with a valid mStatus result). The NO_ERROR indication
    41     // here merely indicates successfully starting the thread and does not
    42     // imply successful termination/execution.
    43     return NO_ERROR;
    44
    45     // Exiting scope of mLock is a memory barrier and allows new thread to run
    46 }

    第22-24行(Thread->run)会调用createThreadEtc函数来创建一个
    第25-28行(Thread->run)会调用androidCreateRawThreadEtc函数来创建一个线程. 关于androidCreateRawThreadEtc函数的详细分析可以参考page7文件.
    当创建完一个新线程之后, 这个线程就会以_threadLoop函数作为入口来执行, 关于Thread的_threadLoop函数的详细分析可以参考page8文件.
    由_threadLoop函数的分析可以知道, 这里会首先调用SurfaceFlinger的readyToRun函数, 关于SurfaceFlinger的readyToRun函数的详细分析可以参考page9文件.
page7
 在这里, 我们看一下Thread的androidCreateRawThreadEtc函数的实现:
    1 int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
    2                                void *userData,
    3                                const char* threadName,
    4                                int32_t threadPriority,
    5                                size_t threadStackSize,
    6                                android_thread_id_t *threadId)
    7 {
    8     pthread_attr_t attr;
    9     pthread_attr_init(&attr);
    10     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    11
    12 #ifdef HAVE_ANDROID_OS  /* valgrind is rejecting RT-priority create reqs */
    13     if (threadPriority != PRIORITY_DEFAULT || threadName != NULL) {
    14         // Now that the pthread_t has a method to find the associated
    15         // android_thread_id_t (pid) from pthread_t, it would be possible to avoid
    16         // this trampoline in some cases as the parent could set the properties
    17         // for the child.  However, there would be a race condition because the
    18         // child becomes ready immediately, and it doesn't work for the name.
    19         // prctl(PR_SET_NAME) only works for self; prctl(PR_SET_THREAD_NAME) was
    20         // proposed but not yet accepted.
    21         thread_data_t* t = new thread_data_t;
    22         t->priority = threadPriority;
    23         t->threadName = threadName ? strdup(threadName) : NULL;
    24         t->entryFunction = entryFunction;
    25         t->userData = userData;
    26         entryFunction = (android_thread_func_t)&thread_data_t::trampoline;
    27         userData = t;
    28     }
    29 #endif
    30
    31     if (threadStackSize) {
    32         pthread_attr_setstacksize(&attr, threadStackSize);
    33     }
    34
    35     errno = 0;
    36     pthread_t thread;
    37     int result = pthread_create(&thread, &attr,
    38                     (android_pthread_entry)entryFunction, userData);
    39     pthread_attr_destroy(&attr);
    40     if (result != 0) {
    41         ALOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, errno=%d)\n"
    42              "(android threadPriority=%d)",
    43             entryFunction, result, errno, threadPriority);
    44         return 0;
    45     }
    46
    47     // Note that *threadID is directly available to the parent only, as it is
    48     // assigned after the child starts.  Use memory barrier / lock if the child
    49     // or other threads also need access.
    50     if (threadId != NULL) {
    51         *threadId = (android_thread_id_t)thread; // XXX: this is not portable
    52     }
    53     return 1;
    54 }

 第37-38行(Thread->androidCreateRawThreadEtc)会调用pthread_create函数来创建一个线程, 并以entryFunction作为线程的入口函数.
page8
    在这篇文章里, 我们分析一下Thread的_threadLoop函数的实现:
 1 int Thread::_threadLoop(void* user)
    2 {
    3     Thread* const self = static_cast<Thread*>(user);
    4
    5     sp<Thread> strong(self->mHoldSelf);
    6     wp<Thread> weak(strong);
    7     self->mHoldSelf.clear();
    8
    9 #ifdef HAVE_ANDROID_OS
    10     // this is very useful for debugging with gdb
    11     self->mTid = gettid();
    12 #endif
    13
    14     bool first = true;
    15
    16     do {
    17         bool result;
    18         if (first) {
    19             first = false;
    20             self->mStatus = self->readyToRun();
    21             result = (self->mStatus == NO_ERROR);
    22
    23             if (result && !self->exitPending()) {
    24                 // Binder threads (and maybe others) rely on threadLoop
    25                 // running at least once after a successful ::readyToRun()
    26                 // (unless, of course, the thread has already been asked to exit
    27                 // at that point).
    28                 // This is because threads are essentially used like this:
    29                 //   (new ThreadSubclass())->run();
    30                 // The caller therefore does not retain a strong reference to
    31                 // the thread and the thread would simply disappear after the
    32                 // successful ::readyToRun() call instead of entering the
    33                 // threadLoop at least once.
    34                 result = self->threadLoop();
    35             }
    36         } else {
    37             result = self->threadLoop();
    38         }
    39
    40         // establish a scope for mLock
    41         {
    42         Mutex::Autolock _l(self->mLock);
    43         if (result == false || self->mExitPending) {
    44             self->mExitPending = true;
    45             self->mRunning = false;
    46             // clear thread ID so that requestExitAndWait() does not exit if
    47             // called by a new thread using the same thread ID as this one.
    48             self->mThread = thread_id_t(-1);
    49             // note that interested observers blocked in requestExitAndWait are
    50             // awoken by broadcast, but blocked on mLock until break exits scope
    51             self->mThreadExitedCondition.broadcast();
    52             break;
    53         }
    54         }
    55
    56         // Release our strong reference, to let a chance to the thread
    57         // to die a peaceful death.
    58         strong.clear();
    59         // And immediately, re-acquire a strong reference for the next loop
    60         strong = weak.promote();
    61     } while(strong != 0);
    62
    63     return 0;
    64 }
    第18-38行(Thread->_threadLoop)会判断如果线程第一次执行会首先执行readyToRun函数, 紧接着会不停地执行threadLoop函数.
page9
    在这篇文章里, 我们分析一下SurfaceFlinger的readyToRun函数的实现:
 1 status_t SurfaceFlinger::readyToRun()
    2 {
    3     ALOGI(  "SurfaceFlinger's main thread ready to run. "
    4             "Initializing graphics H/W...");
    5
    6     // initialize EGL for the default display
    7     mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    8     eglInitialize(mEGLDisplay, NULL, NULL);
    9
    10     // Initialize the H/W composer object.  There may or may not be an
    11     // actual hardware composer underneath.
    12     mHwc = new HWComposer(this,
    13             *static_cast<HWComposer::EventHandler *>(this));
    14
    15     // initialize the config and context
    16     EGLint format = mHwc->getVisualID();
    17     mEGLConfig  = selectEGLConfig(mEGLDisplay, format);
    18     mEGLContext = createGLContext(mEGLDisplay, mEGLConfig);
    19
    20     LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
    21             "couldn't create EGLContext");
    22
    23     // initialize our non-virtual displays
    24     for (size_t i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) {
    25         DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
    26         mDefaultDisplays[i] = new BBinder();
    27         wp<IBinder> token = mDefaultDisplays[i];
    28
    29         // set-up the displays that are already connected
    30         if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
    31             // All non-virtual displays are currently considered secure.
    32             bool isSecure = true;
    33             mCurrentState.displays.add(token, DisplayDeviceState(type));
    34             sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i);
    35             sp<SurfaceTextureClient> stc = new SurfaceTextureClient(
    36                         static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue()));
    37             sp<DisplayDevice> hw = new DisplayDevice(this,
    38                     type, isSecure, token, stc, fbs, mEGLConfig);
    39             if (i > DisplayDevice::DISPLAY_PRIMARY) {
    40                 // FIXME: currently we don't get blank/unblank requests
    41                 // for displays other than the main display, so we always
    42                 // assume a connected display is unblanked.
    43                 ALOGD("marking display %d as acquired/unblanked", i);
    44                 hw->acquireScreen();
    45             }
    46             mDisplays.add(token, hw);
    47         }
    48     }
    49
    50     //  we need a GL context current in a few places, when initializing
    51     //  OpenGL ES (see below), or creating a layer,
    52     //  or when a texture is (asynchronously) destroyed, and for that
    53     //  we need a valid surface, so it's convenient to use the main display
    54     //  for that.
    55     sp<const DisplayDevice> hw(getDefaultDisplayDevice());
    56
    57     //  initialize OpenGL ES
    58     DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);
    59     initializeGL(mEGLDisplay);
    60
    61     // start the EventThread
    62     mEventThread = new EventThread(this);
    63     mEventQueue.setEventThread(mEventThread);
    64
    65     // initialize our drawing state
    66     mDrawingState = mCurrentState;
    67
    68
    69     // We're now ready to accept clients...
    70     mReadyToRunBarrier.open();
    71
    72     // set initial conditions (e.g. unblank default device)
    73     initializeDisplays();
    74
    75     // start boot animation
    76     startBootAnim();
    77
    78     return NO_ERROR;
    79 }
    第12-13行(SurfaceFlinger->readyToRun)会创建一个HWComposer对象来初始化成员变量mHwc, mHwc是底层操作Fb文件的.
    第24-48行(SurfaceFlinger->readyToRun)会为每一个显示设备申请一个DisplayDevice对象,
    第62行(SurfaceFlinger->readyToRun)会创建一个EventThread对象, 并初始化成员变量mEventThread. 关于EventThread的创建过程可以参考page10文件.
    因为mEventThread是一个Sp类型的成员变量, 因此这里会导致EventThread的onFirstRef函数的调用, 关于EventThread的onFirstRef函数的详细分析可以参考page11文件.
 
    第63行(SurfaceFlinger->readyToRun)会调用MessageQueue的setEventThread函数来和EventThread创建连接, 关于MessageQueue的setEventThread函数的详细分析可以参考page12文件.
page10
    在这篇文章里, 我们来看一下EventThread的创建过程.我们先来看一下EventThread类的继承体系:
    class EventThread : public Thread
    很显然, EventThread只是一个线程.

    EventThread类的构造函数的定义如下:
    1 EventThread::EventThread(const sp<SurfaceFlinger>& flinger)
    2     : mFlinger(flinger),
    3       mUseSoftwareVSync(false),
    4       mDebugVsyncEnabled(false) {
    5
    6     for (int32_t i=0 ; i<HWC_DISPLAY_TYPES_SUPPORTED ; i++) {
    7         mVSyncEvent[i].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
    8         mVSyncEvent[i].header.id = 0;
    9         mVSyncEvent[i].header.timestamp = 0;
    10         mVSyncEvent[i].vsync.count =  0;
    11     }
    12 }    

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!

本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程