BootAnimation使用surfaceflinger分析


首先,从BootAnimation开始分析,BootAnimation在启动脚本init。Rc被配置成一个服务

  1. 1.service bootanim /system/bin/bootanimation    
  2. 2.    class main    
  3. 3.    user graphics    
  4. 4.    group system audio graphics cw_access    
  5. 5.    disabled    
  6. 6.    oneshot    

而其代码在 frameworks/cmds/bootanimation

int main(int argc, char** argv)

{

#if defined(HAVE_PTHREADS)

    setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);

#endif

 

    char value[PROPERTY_VALUE_MAX];

    property_get("debug.sf.nobootanimation", value, "0");

    int noBootAnimation = atoi(value);

    ALOGI_IF(noBootAnimation,  "boot animation disabled");

    if (!noBootAnimation) {

 

        sp<ProcessState> proc(ProcessState::self());

        ProcessState::self()->startThreadPool();

 

        // create the boot animation object

        sp<BootAnimation> boot new BootAnimation();

 

        IPCThreadState::self()->joinThreadPool();

 

    }

    return 0;

}


从代码可以看出,bootanimation的启动是通过new一个BootAnimation



  1. BootAnimation::BootAnimation() : Thread(false)  
  2. {  
  3.     mSession = new SurfaceComposerClient();  
  4. }  


首先 创建 SurfaceFilinger Client


========================================


  1. void BootAnimation::onFirstRef() {  
  2.     status_t err = mSession->linkToComposerDeath(this);  
  3.     ALOGE_IF(err, "linkToComposerDeath failed (%s) ", strerror(-err));  
  4.     if (err == NO_ERROR) {  
  5.         run("BootAnimation", PRIORITY_DISPLAY);  
  6.     }  

可以看出BootAnimation最终继承了RefBase在main函数里的boot 是一个sp 的智能指针,

第一次对 BootAnimation 引用调用sp<BootAnimation>时 会调用 BootAnimation 的onFirstRef()方法;

最后 调用run,让BootAnimation线程跑起来,Thread会先跑到readyToRun(),然后再跑:threadLoop()




SurfaceComposerClientlinkToComposerDeath函数获取了SurfaceFlinger服务,

linkTocomposerDeath的作用是 当surfaceflinger死掉时,当前Bootanimation service 就会得到通知,会自动调用 BootAnimation::binderDied。  



  1. tatus_t BootAnimation::readyToRun() {  
  2.     mAssets.addDefaultAssets();  
  3.   
  4.     sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(  
  5.             ISurfaceComposer::eDisplayIdMain));  
  6.     DisplayInfo dinfo;  
  7.     status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);  
  8.     if (status)  
  9.         return -1;  
  10.   
  11.     // create the native surface  
  12.     sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),  
  13.             dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);  
  14.   
  15.     SurfaceComposerClient::openGlobalTransaction();  
  16.     control->setLayer(0x40000000);  //设置图层;
  17.     SurfaceComposerClient::closeGlobalTransaction();  
  18.   
  19.     sp<Surface> s = control->getSurface();  
  20.   
  21.     // initialize opengl and egl  
  22.     const EGLint attribs[] = {  
  23.             EGL_RED_SIZE,   8,  
  24.             EGL_GREEN_SIZE, 8,  
  25.             EGL_BLUE_SIZE,  8,  
  26.             EGL_DEPTH_SIZE, 0,  
  27.             EGL_NONE  
  28.     };  
  29.     EGLint w, h, dummy;  
  30.     EGLint numConfigs;  
  31.     EGLConfig config;  
  32.     EGLSurface surface;  
  33.     EGLContext context;  
  34.   
  35.     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);  
  36.   
  37.     eglInitialize(display, 0, 0);  
  38.     eglChooseConfig(display, attribs, &config, 1, &numConfigs);  
  39.     surface = eglCreateWindowSurface(display, config, s.get(), NULL);  
  40.     context = eglCreateContext(display, config, NULL, NULL);  
  41.     eglQuerySurface(display, surface, EGL_WIDTH, &w);  
  42.     eglQuerySurface(display, surface, EGL_HEIGHT, &h);  
  43.   
  44.     if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)  
  45.         return NO_INIT;  
  46.    mDisplay = display;  
  47.     mContext = context;  
  48.     mSurface = surface;  
  49.     mWidth = w;  
  50.     mHeight = h;  
  51.     mFlingerSurfaceControl = control;  
  52.     mFlingerSurface = s;  
  53.   
  54.     mAndroidAnimation = true;  
  55.   
  56.     // If the device has encryption turned on or is in process   
  57.     // of being encrypted we show the encrypted boot animation.  
  58.     char decrypt[PROPERTY_VALUE_MAX];  
  59.     property_get("vold.decrypt", decrypt, "");  
  60.   
  61.     bool encryptedAnimation = atoi(decrypt) != 0 || !strcmp("trigger_restart_min_framework", decrypt);  
  62.   
  63.     if ((encryptedAnimation &&  
  64.             (access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0) &&  
  65.             (mZip.open(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE) == NO_ERROR)) ||  
  66.   
  67.             ((access(USER_BOOTANIMATION_FILE, R_OK) == 0) &&  
  68.             (mZip.open(USER_BOOTANIMATION_FILE) == NO_ERROR)) ||  
  69.   
  70.             ((access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0) &&  
  71.             (mZip.open(SYSTEM_BOOTANIMATION_FILE) == NO_ERROR))) {  
  72.         mAndroidAnimation = false;  
  73.     }  
  74.   
  75.     return NO_ERROR;  
  76. }  

首先,通过向surfaceflinger service发送

  1. sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(  
  2.             ISurfaceComposer::eDisplayIdMain));  

告诉surfaceflinger service 获取DisplayIdBinder

rameworks/native/libs/gui/ISurfaceComposer.cpp

  1. class BpSurfaceComposer : public BpInterface<ISurfaceComposer>  
  2. {  
  3.    ...  
  4. virtual sp<IBinder> getBuiltInDisplay(int32_t id)  
  5.     {  
  6.         Parcel data, reply;  
  7.         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());  
  8.         data.writeInt32(id);  
  9.         remote()->transact(BnSurfaceComposer::GET_BUILT_IN_DISPLAY, data, &reply);  
  10.         return reply.readStrongBinder();  
  11.     }  
  12.  ....  
  13. };  
  14.   
  15. status_t BnSurfaceComposer::onTransact(  
  16.     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
  17. {  
  18. switch(code) {  
  19. case GET_BUILT_IN_DISPLAY: {  
  20.             CHECK_INTERFACE(ISurfaceComposer, data, reply);  
  21.             int32_t id = data.readInt32();  
  22.             sp<IBinder> display(getBuiltInDisplay(id));  
  23.             reply->writeStrongBinder(display);  
  24.             return NO_ERROR;  
  25.         } break;  
  26. }  
  27. }  

接着获取一个 DisplayInfo dinfo;

  1. status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);  

同样看SurfaceFlinger.cpp

  1. status_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info)  
  2. {  
  3.     int32_t type = NAME_NOT_FOUND;  
  4.     for (int i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) {  
  5.         if (display == mBuiltinDisplays[i]) {  
  6.             type = i;  
  7.             break;  
  8.         }  
  9.     }  
  10.   
  11.     if (type < 0) {  
  12.         return type;  
  13.     }  
  14.   
  15.     const HWComposer& hwc(getHwComposer());  
  16.     float xdpi = hwc.getDpiX(type);  
  17.     float ydpi = hwc.getDpiY(type);  
  18.   
  19.     // TODO: Not sure if display density should handled by SF any longer  
  20.     class Density {  
  21.         static int getDensityFromProperty(char const* propName) {  
  22.             char property[PROPERTY_VALUE_MAX];  
  23.             int density = 0;  
  24.             if (property_get(propName, property, NULL) > 0) {  
  25.                 density = atoi(property);  
  26.             }  
  27.             return density;  
  28.         }  
  29.     public:  
  30.         static int getEmuDensity() {  
  31.             return getDensityFromProperty("qemu.sf.lcd_density"); }  
  32.         static int getBuildDensity()  {  
  33.             return getDensityFromProperty("ro.sf.lcd_density"); }  
  34.     };  
  35.   
  36.     if (type == DisplayDevice::DISPLAY_PRIMARY) {  
  37.         // The density of the device is provided by a build property  
  38.         float density = Density::getBuildDensity() / 160.0f;  
  39.         if (density == 0) {  
  40.             // the build doesn't provide a density -- this is wrong!  
  41.             // use xdpi instead  
  42.             ALOGE("ro.sf.lcd_density must be defined as a build property");  
  43.             density = xdpi / 160.0f;  
  44.         }  
  45.         if (Density::getEmuDensity()) {  
  46.             // if "qemu.sf.lcd_density" is specified, it overrides everything  
  47.             xdpi = ydpi = density = Density::getEmuDensity();  
  48.             density /= 160.0f;  
  49.         }  
  50.         info->density = density;  
  51.   
  52.         // TODO: this needs to go away (currently needed only by webkit)  
  53.         sp<const DisplayDevice> hw(getDefaultDisplayDevice());  
  54.         info->orientation = hw->getOrientation();  
  55.         getPixelFormatInfo(hw->getFormat(), &info->pixelFormatInfo);  
  56.     } else {  
  57.         // TODO: where should this value come from?  
  58.         static const int TV_DENSITY = 213;  
  59.         info->density = TV_DENSITY / 160.0f;  
  60.         info->orientation = 0;  
  61.     }  
  62.   
  63.     info->w = hwc.getWidth(type);  
  64.     info->h = hwc.getHeight(type);  
  65.     info->xdpi = xdpi;  
  66.     info->ydpi = ydpi;  
  67.     info->fps = float(1e9 / hwc.getRefreshPeriod(type));  
  68.   
  69.     // All non-virtual displays are currently considered secure.  
  70.     info->secure = true;  
  71.   
  72.     return NO_ERROR;  
  73. }  

接着,按返回的DisplayInfo创建一个native surface

  1. / create the native surface  
  2.     sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),  
  3.             dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);  

接着

  1. SurfaceComposerClient::openGlobalTransaction();  //增加一个 全局Transaction计数
  2.     control->setLayer(0x40000000);  //设置图层;
  3. SurfaceComposerClient::closeGlobalTransaction();  //减少一个全局Transaction计数,当这个全局Transaction计数减少至0的时候,把mStates发送给SurfaceFlinger处理

setLayer从代码里看是设置z-order,层级越高越接近客户

设置完Z-order

  1. sp<Surface> s = control->getSurface();  

  1. 通过SurfaceControl获取了一个Surface  

  1. sp<Surface> SurfaceControl::getSurface() const  
  2. {  
  3.     Mutex::Autolock _l(mLock);  
  4.     if (mSurfaceData == 0) {  
  5.         mSurfaceData = new Surface(mGraphicBufferProducer);  
  6.     }  
  7.     return mSurfaceData;  
  8. }  

Surface的创建则通过createsurface时创建的mGraphicBufferProducer(SurfaceTextureLayer)来初始化

  1. Surface::Surface(  
  2.         const sp<IGraphicBufferProducer>& bufferProducer)  
  3.     : mGraphicBufferProducer(bufferProducer)  
  4. {  
  5.     // Initialize the ANativeWindow function pointers.  
  6.     ANativeWindow::setSwapInterval  = hook_setSwapInterval;  
  7.     ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;  
  8.     ANativeWindow::cancelBuffer     = hook_cancelBuffer;  
  9.     ANativeWindow::queueBuffer      = hook_queueBuffer;  
  10.     ANativeWindow::query            = hook_query;  
  11.     ANativeWindow::perform          = hook_perform;  
  12.   
  13.     ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;  
  14.     ANativeWindow::cancelBuffer_DEPRECATED  = hook_cancelBuffer_DEPRECATED;  
  15.     ANativeWindow::lockBuffer_DEPRECATED    = hook_lockBuffer_DEPRECATED;  
  16.     ANativeWindow::queueBuffer_DEPRECATED   = hook_queueBuffer_DEPRECATED;  
  17.   
  18.     const_cast<int&>(ANativeWindow::minSwapInterval) = 0;  
  19.     const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;  
  20.   
  21.     mReqWidth = 0;  
  22.     mReqHeight = 0;  
  23.     mReqFormat = 0;  
  24.     mReqUsage = 0;  
  25.     mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;  
  26.     mCrop.clear();  
  27.     mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;  
  28.     mTransform = 0;  
  29.     mDefaultWidth = 0;  
  30.     mDefaultHeight = 0;  
  31.     mUserWidth = 0;  
  32.     mUserHeight = 0;  
  33.     mTransformHint = 0;  
  34.     mConsumerRunningBehind = false;  
  35.     mConnectedToCpu = false;  
  36. }  

  1. 接着通过这个surface对象初始化egl  

surface = eglCreateWindowSurface(display, config, s.get(), NULL);

其他都是走egl流程

然后,继续分析BootAnimation,跑完systemReadyRun,则会跑threadloop循环

  1. bool BootAnimation::threadLoop()  
  2. {  
  3.     bool r;  
  4.     if (mAndroidAnimation) {  
  5.         r = android();  
  6.     } else {  
  7.         r = movie();  
  8.     }  
  9.   
  10.     // No need to force exit anymore  
  11.     property_set(EXIT_PROP_NAME, "0");  
  12.   
  13.     eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);  
  14.     eglDestroyContext(mDisplay, mContext);  
  15.     eglDestroySurface(mDisplay, mSurface);  
  16.     mFlingerSurface.clear();  
  17.     mFlingerSurfaceControl.clear();  
  18.     eglTerminate(mDisplay);  
  19.     IPCThreadState::self()->stopProcess();  
  20.     return r;  
  21. }  


可以看出,如果mAndroidAnimationtrue则跑Android,不成功则跑movie


















posted @ 2017-03-06 18:41  点点爱梦  阅读(517)  评论(0编辑  收藏  举报