Android SurfaceFlinger服务启动过程源码分析1



Android系统的SurfaceFlinger服务有两种启动方式:1)在SystemServer进程中以服务线程的方式提供服务;2)启动SurfaceFlinger独立的进程通过服务。第一种方式是在SystemServer进程启动过程中启动SurfaceFlinger服务的,而第二中方式是在Android启动脚本init.rc中配置SurfaceFlinger服务,通过init进程来启动的。下面就分别介绍SurfaceFlinger的两种启动方式。  1 服务线程启动方式  在Android 开关机动画显示源码分析中已经简要介绍过SurfaceFlinger服务的这种启动方式,在SystemServer进程的init1阶段,通过JNI调用system_init()函数来启动SurfaceFlinger:  frameworks\base\cmds\system_server\library\system_init.cpp  java代码

  1. extern "C" status_t system_init()

  2.   {
  3.   ALOGI("Entered system_init()");
  4.   sp proc(ProcessState::self());
  5.   sp sm = defaultServiceManager();
  6.   ALOGI("ServiceManager: %p\n", sm.get());
  7.   sp grim = new GrimReaper();
  8.   sm->asBinder()->linkToDeath(grim, grim.get(), 0);
  9.   char propBuf[PROPERTY_VALUE_MAX];
  10.   property_get("system_init.startsurfaceflinger", propBuf, "1");
  11.   if (strcmp(propBuf, "1") == 0) {
  12.   // Start the SurfaceFlinger
  13.   SurfaceFlinger::instantiate();
  14.   }
  15.   ....
  16.   }
复制代码   SurfaceFlinger继承于BinderService模板类,BinderService的instantiate函数实现:  java代码
  1. static void instantiate() { publish(); }
复制代码   java代码
  1. static status_t publish(bool allowIsolated = false) {

  2.   sp sm(defaultServiceManager());
  3.   return sm->addService(String16(SERVICE::getServiceName()), new
  4. SERVICE(), allowIsolated);
  5.   }
复制代码   函数首先得到ServiceManager的Binder代理对象,然后构造一个SurfaceFlinger对象,并注册到ServiceManager进程中。  在通过读取system_init.startsurfaceflinger属性值来决定是否在SystemServer进程中启动SurfaceFlinger服务,因此如果要在SystemServer中启动SurfaceFlinger,就必须设置system_init.startsurfaceflinger属性     如果system_init.startsurfaceflinger属性的值等于0,意味着SurfaceFlinger是以服务进程的方式启动的。  2.服务进程启动方式  当system_init.startsurfaceflinger属性的值设置为0时,就必须在init.rc中配置SurfaceFlinger服务,通过init进程启动。        当SurfaceFlinger以服务进程的方式启动时,必现提供进程入口函数main,在frameworks\native\cmds\surfaceflinger\main_surfaceflinger.cpp中实现:  java代码
  1. int main(int argc, char** argv) {

  2.   SurfaceFlinger::publishAndJoinThreadPool(true);
  3.   // When SF is launched in its own process, limit the number of
  4.   // binder threads to 4.
  5.   ProcessState::self()->setThreadPoolMaxThreadCount(4);
  6.   return 0;
  7.   }
复制代码   函数调用SurfaceFlinger类的publishAndJoinThreadPool方法启动构造SurfaceFlinger对象并注册到ServiceManager进程中,然后调用setThreadPoolMaxThreadCount函数来设置SurfaceFlinger进程的最大Binder线程数。  java代码
  1. static void publishAndJoinThreadPool(bool allowIsolated =
  2. false) {

  3.   sp sm(defaultServiceManager());
  4.   sm->addService(String16(SERVICE::getServiceName()), new SERVICE(),
  5. allowIsolated);
  6.   ProcessState::self()->startThreadPool();
  7.   IPCThreadState::self()->joinThreadPool();
  8.   }
复制代码   和前面的publish函数一样,首先得到ServiceManager的Binder代理对象,然后构造一个SurfaceFlinger对象,并注册到ServiceManager进程中,只不过这里额外调用了ProcessState::self()->startThreadPool()来启动Binder线程池,并且将当前进程的主线程注册到Binder线程池中,对于SurfaceFlinger服务进程来说,为了接收客户端的请求,SurfaceFlinger服务进程必现启动Binder线程池。如果SurfaceFlinger以服务线程的方式在SystemServer进程中启动的话,就无需启动Binder线程,因为SurfaceFlinger服务驻留在SystemServer进程中,而SysteServer进程自己维护了一个Binder线程池。  3.启动SurfaceFlinger  java代码
  1. SurfaceFlinger::SurfaceFlinger()

  2.   : BnSurfaceComposer(), Thread(false),
  3.   mTransactionFlags(0),
  4.   mTransationPending(false),
  5.   mLayersRemoved(false),
  6.   mBootTime(systemTime()),
  7.   mVisibleRegionsDirty(false),
  8.   mHwWorkListDirty(false),
  9.   mElectronBeamAnimationMode(0),
  10.   mDebugRegion(0),
  11.   mDebugDDMS(0),
  12.   mDebugDisableHWC(0),
  13.   mDebugDisableTransformHint(0),
  14.   mDebugInSwapBuffers(0),
  15.   mLastSwapBufferTime(0),
  16.   mDebugInTransaction(0),
  17.   mLastTransactionTime(0),
  18.   mBootFinished(false),
  19.   mSecureFrameBuffer(0)
  20.   {
  21.   init();
  22.   }
复制代码   构造过程仅仅初始化了SurfaceFlinger的成员变量,同时调用了父类BnSurfaceComposer的构造函数。最后使用init方法来作一些初始化工作。  cpp代码
  1. void SurfaceFlinger::init()

  2.   {
  3.   ALOGI("SurfaceFlinger is starting");
  4.   char value[PROPERTY_VALUE_MAX];
  5.   property_get("debug.sf.showupdates", value, "0");
  6.   mDebugRegion = atoi(value);
  7.   property_get("ro.bootmode", value, "mode");
  8.   if (!(strcmp(value, "engtest")
  9.   && strcmp(value, "special")
  10.   && strcmp(value, "wdgreboot")
  11.   && strcmp(value, "unknowreboot")
  12.   && strcmp(value, "panic"))) {
  13.   SurfaceFlinger::sBootanimEnable = false;
  14.   }
  15.   }
复制代码   读取开机模式属性ro.bootmode来决定是否要显示开机动画,关于开机动画在Android 开关机动画显示源码分析中介绍了。由于SurfaceFlinger继承于RefBase类,同时实现了RefBase的onFirstRef()方法,因此在第一次引用SurfaceFlinger对象时,onFirstRef()函数自动被调用:  cpp代码
  1. void SurfaceFlinger::onFirstRef()

  2.   {
  3.   mEventQueue.init(this);
  4.   run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
  5.   // Wait for the main thread to be done with its initialization
  6.   mReadyToRunBarrier.wait();
  7.   }
复制代码   mEventQueue是MessageQueue类型变量,定义在frameworks\native\services\surfaceflinger\MessageQueue.h这里调用init函数初始化mEventQueue消息队列  cpp代码
  1. void MessageQueue::init(const sp&
  2. flinger)

  3.   {
  4.   mFlinger = flinger;
  5.   mLooper = new Looper(true);
  6.   mHandler = new Handler(*this);
  7.   }
复制代码   mReadyToRunBarrier为Barrier类型的变量,用于阻塞,启动线程运行,对象构造时,状态初始化为CLOSED,因此在调用它的wait方法时,当前SurfaceFlinger线程睡眠等待SystemServer主线程调用readyToRun()函数完成SurfaceFlinger运行前的初始化工作。  cpp代码
  1. inline Barrier() : state(CLOSED) { }

  2.   void wait() const {
  3.   Mutex::Autolock _l(lock);
  4.   while (state == CLOSED) {
  5.   cv.wait(lock);
  6.   }
  7.   }
复制代码   SurfaceFlinger继承于Thread类,因此构造一个SurfaceFlinger对象,其实就是创建一个线程,当调用其run方法时,就是启动该线程的运行,在SurfaceFlinger线程运行前,需要主线程初始化OpenGL库,因此在主线程完成初始化工作前,需要让SurfaceFlinger线程睡眠等待,主线程初始化工作:  cpp代码
  1. status_t SurfaceFlinger::readyToRun()

  2.   {
  3.   ALOGI( "SurfaceFlinger's main thread ready to run. ""Initializing graphics
  4. H/W...");
  5.   // we only support one display currently
  6.   int dpy = 0;
  7.   {
  8.   //初始化主显示屏,即从SurfaceFlinger中取出第0号GraphicPlane
  9.   GraphicPlane& plane(graphicPlane(dpy));
  10.   //创建DisplayHardware,并和显示屏绑定
  11.   DisplayHardware* const hw = new DisplayHardware(this, dpy);
  12.   plane.setDisplayHardware(hw);
  13.   }
  14.   //创建一块大小为4k的匿名共享内存,用于共享显示屏幕信息
  15.   mServerHeap = new MemoryHeapBase(4096,MemoryHeapBase::READ_ONLY,
  16. "SurfaceFlinger read-only heap");
  17.   ALOGE_IF(mServerHeap==0, "can't create shared memory dealer");
  18.   //将该匿名共享内存的首地址转换为surface_flinger_cblk_t类型的指针,表明该共享内存存储surface_flinger_cblk_t结构体数据
  19.   mServerCblk =
  20. static_cast(mServerHeap->getBase());
  21.   ALOGE_IF(mServerCblk==0, "can't get to shared control block's
  22. address");
  23.   new(mServerCblk) surface_flinger_cblk_t;
  24.   //从显示屏的DisplayHardware中得到屏幕的宽高,并设置为当前主显示屏
  25.   const GraphicPlane& plane(graphicPlane(dpy));
  26.   const DisplayHardware& hw = plane.displayHardware();
  27.   const uint32_t w = hw.getWidth();
  28.   const uint32_t h = hw.getHeight();
  29.   const uint32_t f = hw.getFormat();
  30.   hw.makeCurrent();
  31.   //将屏幕信息保存到匿名共享内存中,从而共享给所有进程
  32.   mServerCblk->connected |= 1<
  33.   display_cblk_t* dcblk = mServerCblk->displays + dpy;
  34.   memset(dcblk, 0, sizeof(display_cblk_t));
  35.   dcblk->w = plane.getWidth();
  36.   dcblk->h = plane.getHeight();
  37.   dcblk->format = f;
  38.   dcblk->orientation = ISurfaceComposer::eOrientationDefault;
  39.   dcblk->xdpi = hw.getDpiX();
  40.   dcblk->ydpi = hw.getDpiY();
  41.   dcblk->fps = hw.getRefreshRate();
  42.   dcblk->density = hw.getDensity();
  43.   //初始化OpenGL|ES
  44.   glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
  45.   glPixelStorei(GL_PACK_ALIGNMENT, 4);
  46.   glEnableClientState(GL_VERTEX_ARRAY);
  47.   glShadeModel(GL_FLAT);
  48.   glDisable(GL_DITHER);
  49.   glDisable(GL_CULL_FACE);
  50.   const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
  51.   const uint16_t g1 = pack565(0x17,0x2f,0x17);
  52.   const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 };
  53.   glGenTextures(1, &mWormholeTexName);
  54.   glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
  55.   glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  56.   glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  57.   glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  58.   glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  59.   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,GL_RGB,
  60. GL_UNSIGNED_SHORT_5_6_5, wormholeTexData);
  61.   const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
  62.   glGenTextures(1, &mProtectedTexName);
  63.   glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
  64.   glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  65.   glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  66.   glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  67.   glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  68.   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,GL_RGB,
  69. GL_UNSIGNED_SHORT_5_6_5, protTexData);
  70.   glViewport(0, 0, w, h);
  71.   glMatrixMode(GL_PROJECTION);
  72.   glLoadIdentity();
  73.   // put the origin in the left-bottom corner
  74.   glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
  75.   // 启动EventThread线程
  76.   mEventThread = new EventThread(this);
  77.   mEventQueue.setEventThread(mEventThread);
  78.   hw.startSleepManagement();
  79.   //主线程已经完成初始化工作,唤醒睡眠等待中的SurfaceFlinger线程接收客户端的请求
  80.   mReadyToRunBarrier.open();
  81.   //启动开机动画
  82.   startBootAnim();
  83.   return NO_ERROR;
  84.   }
复制代码

更多相关文章

  1. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
  2. android通过线程实现逐行显示信息
  3. Android(安卓)Intent.FLAG_NEW_TASK详解,包括其他的标记的一些解
  4. Android(安卓)Binder机制(2) ContextManager注册过程分析
  5. Android实例练习-可爱的小闹钟
  6. 【边做项目边学Android】手机安全卫士04_01:界面(Activity)之间的切
  7. Ubuntu下Genymotion模拟器启动卡死
  8. Android开发常用命令整理
  9. Android(安卓)GLSurfaceView详解

随机推荐

  1. 选择器权重,伪类选择器计算
  2. 字符串api和数组api及遍历
  3. Yii2中组件的注册与创建方法
  4. MTK Android(安卓)6.0 上新增KeyCode
  5. Android(安卓)倒车影像车道线,3D效果
  6. android 使用Activity类布局时怎样让图片
  7. Android系统开发—对View的clipChildren,
  8. 替换Android自带apk
  9. 新手学Android
  10. Android(安卓)SDK Manager 更新方法