SurfaceFlinger 分析 一

来源:互联网 发布:风行直播软件下载 编辑:程序博客网 时间:2024/06/05 19:17

SurfaceFlinger 

 

1. SurfaceFlinger启动流程

 

SurfaceFlinger 线程启动是由kenerl加载init.rc文件后执行system/bin文件夹下的可执行文件: surfaceflinger, 启动main函数:

先见时序图:

 

 

启动main函数后创建自己的线程并限定binder线程最大为4初始话后加入线程池:

    ProcessState::self()->setThreadPoolMaxThreadCount(4); // 设置最大线程数    sp<ProcessState> ps(ProcessState::self());    ps->startThreadPool();


 

初始化的第一部分:

Main函数调用surface flingerinit函数EGL, RenderEngine 等初始化:

    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);     eglInitialize(mEGLDisplay, NULL, NULL); // EGL 的初始化动作    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync, vsyncPhaseOffsetNs, true, "app"); // 虚拟化Vsync App UI部分    mEventThread = new EventThread(vsyncSrc);    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync, sfVsyncPhaseOffsetNs, true, "sf"); // 虚拟化Vsync SF合成部分    mSFEventThread = new EventThread(sfVsyncSrc);    mEventQueue.setEventThread(mSFEventThread);     // Initialize the H/W composer object.  There may or may not be an    // actual hardware composer underneath.    mHwc = DisplayUtils::getInstance()->getHWCInstance(this,  *static_cast<HWComposer::EventHandler *>(this));  // 初始化hardwarecomposer    // get a RenderEngine for the given display / config (can't fail)    mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID());    // retrieve the EGL context that was selected/created    mEGLContext = mRenderEngine->getEGLContext();    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,  "couldn't create EGLContext");


(1) . EGL的初始就不说了有意思的是 google 实例了两个不同的VsyncSource : vsyncSrc 与 sfvsyncSrc 一个是app uivsync另一个是surfaceflinger合成的vsync, 他们只是将hardware层传过来的vsync虚拟化了.

他们根据sfVsyncPhaseOffsetNs 与 vsyncPhaseOffsetNs 两个相对偏移量将

 app UI绘制 与 SF合成区分

 

其中Phase Offset 1, 2 的值可以改变这样做的目的是避免了因同时唤醒app UI 渲染和SF合成是造成对CPU资源的抢占.

 

(2) . 接下来启动上述EventThread. 

EventThread的构造函数只是初始化一些数据重要的是它的onFirstRef函数(使用强指针时就会触发onFirstRef函数 )

 void EventThread::onFirstRef() {    run("EventThread", PRIORITY_URGENT_DISPLAY+PRIORITY_MORE_FAVORABLE);}

Run 启动threadloop: 其中一个重要的函数: waitForEvent, 

 

( 3 ) . HWcomposer初始化:

 

HWComposer::HWComposer(       const sp<SurfaceFlinger>& flinger, EventHandler& handler)    : mFlinger(flinger),mFbDev(0),  mHwc(0),  mNumDisplays(1),    mCBContext(new cb_context), mEventHandler(handler), mDebugForceFakeVSync(false){    ...  ...     // Note: some devices may insist that the FB HAL be opened before HWC.    int fberr = loadFbHalModule();  // 加载准备framebuffer hal模块, 最终加载gralloc.XX.so动态库    loadHwcModule();   // 加载准备硬件加速模块 最终会加载各平台对应的hwcomposer.XX.so动态库     ... ...    if (needVSyncThread) {        // we don't have VSYNC support, we need to fake it        mVSyncThread = new VSyncThread(*this);  // Vsync周期控制    }}

HWcomposer 的初始化其中两个很重要的工作就是加载FB HAL与 Hwc 模块它们为数据在硬件合成方面做准备工作

 

( 4 ) . 根据EGL display与 像素格式创建RenderEngine, 并获取当前EGLContext

 

接下来看初始化的第二部分:

   // initialize our non-virtual displays    for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {        DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);        // set-up the displays that are already connected        if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {            // All non-virtual displays are currently considered secure.            bool isSecure = true;            createBuiltinDisplayLocked(type);            wp<IBinder> token = mBuiltinDisplays[i];             sp<IGraphicBufferProducer> producer;            sp<IGraphicBufferConsumer> consumer;            BufferQueue::createBufferQueue(&producer, &consumer,                    new GraphicBufferAlloc());             sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i,                    consumer);            int32_t hwcId = allocateHwcDisplayId(type);            sp<DisplayDevice> hw = new DisplayDevice(this,                    type, hwcId, mHwc->getFormat(hwcId), isSecure, token,                    fbs, producer,                    mRenderEngine->getEGLConfig());            if (i > DisplayDevice::DISPLAY_PRIMARY) {                // FIXME: currently we don't get blank/unblank requests                // for displays other than the main display, so we always                // assume a connected display is unblanked.                ALOGD("marking display %zu as acquired/unblanked", i);                hw->setPowerMode(HWC_POWER_MODE_NORMAL);            }            // When a non-virtual display device is added at boot time,            // update the active config by querying HWC otherwise the            // default config (config 0) will be used.            int activeConfig = mHwc->getActiveConfig(hwcId);            if (activeConfig >= 0) {                hw->setActiveConfig(activeConfig);            }            mDisplays.add(token, hw);        }    }

( 1 ) . 初始化BufferQueue, 这个Queue是生产者IGraphicBufferProducer 与 消费者IGraphicBufferConsumer 的关键桥梁

( 2 ) . 创建一个FramebufferSurface

( 3 ) . 初始化各个DisplayDevice, 每个显示设备都会封装为一个DisplayDevice, HDMI等 

DisplayDevice::DisplayDevice(        const sp<SurfaceFlinger>& flinger,        DisplayType type,        int32_t hwcId,        int format,        bool isSecure,        const wp<IBinder>& displayToken,        const sp<DisplaySurface>& displaySurface,        const sp<IGraphicBufferProducer>& producer,        EGLConfig config)    : lastCompositionHadVisibleLayers(false),      mFlinger(flinger),      mType(type), mHwcDisplayId(hwcId),      mDisplayToken(displayToken),      mDisplaySurface(displaySurface),      mDisplay(EGL_NO_DISPLAY),      mSurface(EGL_NO_SURFACE),      mDisplayWidth(), mDisplayHeight(), mFormat(),      mFlags(),      mPageFlipCount(),      mIsSecure(isSecure),      mSecureLayerVisible(false),      mLayerStack(NO_LAYER_STACK),      mOrientation(),      mPowerMode(HWC_POWER_MODE_OFF),      mActiveConfig(0){    Surface* surface;    mNativeWindow = surface = new Surface(producer, false);  // 创建一个surface    ANativeWindow* const window = mNativeWindow.get(); // 获取一个本地窗口    char property[PROPERTY_VALUE_MAX];     /*     * Create our display's surface     */     EGLSurface eglSurface;    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);    if (config == EGL_NO_CONFIG) {        config = RenderEngine::chooseEglConfig(display, format);    }    eglSurface = eglCreateWindowSurface(display, config, window, NULL);    eglQuerySurface(display, eglSurface, EGL_WIDTH,  &mDisplayWidth);    eglQuerySurface(display, eglSurface, EGL_HEIGHT, &mDisplayHeight);     // Make sure that composition can never be stalled by a virtual display    // consumer that isn't processing buffers fast enough. We have to do this    // in two places:    // * Here, in case the display is composed entirely by HWC.    // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the    //   window's swap interval in eglMakeCurrent, so they'll override the    //   interval we set here.    if (mType >= DisplayDevice::DISPLAY_VIRTUAL)        window->setSwapInterval(window, 0);     mConfig = config;    mDisplay = display;    mSurface = eglSurface;    mFormat  = format;    mPageFlipCount = 0;    mViewport.makeInvalid();    mFrame.makeInvalid();     // virtual displays are always considered enabled    mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ?                  HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;     // Name the display.  The name will be replaced shortly if the display    // was created with createDisplay().    switch (mType) {        case DISPLAY_PRIMARY:            mDisplayName = "Built-in Screen";            break;        case DISPLAY_EXTERNAL:            mDisplayName = "HDMI Screen";            break;        default:            mDisplayName = "Virtual Screen";    // e.g. Overlay #n            break;    }     mPanelInverseMounted = false;    // Check if panel is inverse mounted (contents show up HV flipped)    property_get("persist.panel.inversemounted", property, "0");    mPanelInverseMounted = !!atoi(property);     // initialize the display orientation transform.    setProjection(DisplayState::eOrientationDefault, mViewport, mFrame); #ifdef NUM_FRAMEBUFFER_SURFACE_BUFFERS    surface->allocateBuffers();#endif}


初始化第三部分:

    // make the GLContext current so that we can create textures when creating Layers    // (which may happens before we render something)    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);     mEventControlThread = new EventControlThread(this);    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);     // set a fake vsync period if there is no HWComposer    if (mHwc->initCheck() != NO_ERROR) {        mPrimaryDispSync.setPeriod(16666667);    }     // initialize our drawing state    mDrawingState = mCurrentState;     // set initial conditions (e.g. unblank default device)    initializeDisplays();  // 设置初始的layer数据     // start boot animation    startBootAnim();  // 开机动画设置


SurfaceFlinger init完成之后会执行它的run函数使之进入死循环,去等待vsync信号: waitForEvent()


总结:

至此SurfaceFlinger的初始话工作完成但这才是开始, androidsurface系统值得我们去深究去探索.

1 0
原创粉丝点击