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

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.   }
复制代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值