I.MX6 Surfaceflinger 机制

/****************************************************************************
 *                      I.MX6 Surfaceflinger 机制
 * 说明:
 *     最近需要去分析一下Surfaceflinger工作机制,记录一下相关的文档和主要的
 * 处理函数。
 *
 *                                          2016-9-14 深圳 南山平山村 曾剑锋
 ***************************************************************************/

一、参考文档:
    1. Android SurfaceFlinger服务启动过程源码分析
        http://blog.csdn.net/yangwen123/article/details/11890941
    2. Android 开关机动画显示源码分析
        http://blog.csdn.net/yangwen123/article/details/11680759
    3. 深入学习EGL 
        http://blog.sina.com.cn/s/blog_602f87700100p1e7.html
    4. Android hwcomposer模块接口
        http://blog.sina.com.cn/s/blog_7213e0310102wmc0.html
    5. Android VSync信号产生过程源码分析
        http://blog.csdn.net/yangwen123/article/details/16969907
    6. android HAL浅探
        http://www.cnblogs.com/mr-nop/archive/2013/02/27/2935131.html
    7. Android: 显示系统模块加载以及调用流程
        http://blog.csdn.net/hongzg1982/article/details/49681705

二、cat frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
    ......
    status_t SurfaceFlinger::readyToRun()
    {
        ALOGI(  "SurfaceFlinger's main thread ready to run. "
                "Initializing graphics H/W...");
    
        // initialize EGL for the default display
        mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
        eglInitialize(mEGLDisplay, NULL, NULL);
    
        // Initialize the H/W composer object.  There may or may not be an
        // actual hardware composer underneath.
        mHwc = new HWComposer(this,
               *static_cast<HWComposer::EventHandler *>(this));
    
        // initialize the config and context
        EGLint format = mHwc->getVisualID();
        mEGLConfig  = selectEGLConfig(mEGLDisplay, format);
        mEGLContext = createGLContext(mEGLDisplay, mEGLConfig);
    
        LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
                "couldn't create EGLContext");
    
        // initialize our non-virtual displays
        for (size_t i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) {
            DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
            mDefaultDisplays[i] = new BBinder();
            wp<IBinder> token = mDefaultDisplays[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;
                bool isSecure = true;
                mCurrentState.displays.add(token, DisplayDeviceState(type));
                sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i);
                sp<SurfaceTextureClient> stc = new SurfaceTextureClient(
                            static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue()));
                sp<DisplayDevice> hw = new DisplayDevice(this,
                        type, isSecure, token, stc, fbs, mEGLConfig);
                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 %d as acquired/unblanked", i);
                    hw->acquireScreen();
                }
                mDisplays.add(token, hw);
            }
        }
    
        //  we need a GL context current in a few places, when initializing
        //  OpenGL ES (see below), or creating a layer,
        //  or when a texture is (asynchronously) destroyed, and for that
        //  we need a valid surface, so it's convenient to use the main display
        //  for that.
        sp<const DisplayDevice> hw(getDefaultDisplayDevice());
    
        //  initialize OpenGL ES
        DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);
        initializeGL(mEGLDisplay);
    
        // start the EventThread
        mEventThread = new EventThread(this);
        mEventQueue.setEventThread(mEventThread);
    
        // initialize our drawing state
        mDrawingState = mCurrentState;
    
    
        // We're now ready to accept clients...
        mReadyToRunBarrier.open();
    
        // set initial conditions (e.g. unblank default device)
        initializeDisplays();
    
        // start boot animation
        startBootAnim();
    
        return NO_ERROR;
    }
    ......

三、cat frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp
    ......
    // Load and prepare the hardware composer module.  Sets mHwc.
    void HWComposer::loadHwcModule()
    {
        hw_module_t const* module;
    
        if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) {
            ALOGE("%s module not found", HWC_HARDWARE_MODULE_ID);
            return;
        }
    
        int err = hwc_open_1(module, &mHwc);
        if (err) {
            ALOGE("%s device failed to initialize (%s)",
                  HWC_HARDWARE_COMPOSER, strerror(-err));
            return;
        }
    
        if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0) ||
                hwcHeaderVersion(mHwc) < MIN_HWC_HEADER_VERSION ||
                hwcHeaderVersion(mHwc) > HWC_HEADER_VERSION) {
            ALOGE("%s device version %#x unsupported, will not be used",
                  HWC_HARDWARE_COMPOSER, mHwc->common.version);
            hwc_close_1(mHwc);
            mHwc = NULL;
            return;
        }
    }
    ......

四、cat hardware/imx/mx6/hwcomposer/hwcomposer.cpp
    static int hwc_device_open(const struct hw_module_t* module, const char* name,
            struct hw_device_t** device)
    {
    
        printf("fsl hwc_device_open().
");
        int status = -EINVAL;
        if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
            struct hwc_context_t *dev;
            dev = (hwc_context_t*)malloc(sizeof(*dev));
    
            /* initialize our state here */
            // memset(dev, 0, sizeof(*dev));
    
            /* initialize the procs */
            dev->device.common.tag = HARDWARE_DEVICE_TAG;
            dev->device.common.module = const_cast<hw_module_t*>(module);
            dev->device.common.close = hwc_device_close;
    
            dev->device.prepare = hwc_prepare;
            dev->device.set = hwc_set;
            dev->device.common.version = HWC_DEVICE_API_VERSION_1_1;
            dev->device.registerProcs = hwc_registerProcs;
            dev->device.eventControl = hwc_eventControl;
            dev->device.query = hwc_query;
            dev->device.blank = hwc_blank;
            dev->device.getDisplayConfigs = hwc_getDisplayConfigs;
            dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
    
            /* our private state goes below here */
            dev->m_vsync_thread = new VSyncThread(dev);
            dev->m_vsync_thread = new VSyncThread(dev);
            dev->m_uevent_thread = new UeventThread(dev);
            hwc_get_display_info(dev);
    
            hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &dev->m_gralloc_module);
            struct private_module_t *priv_m = (struct private_module_t *)dev->m_gralloc_module;
    
            for(int dispid=0; dispid<HWC_NUM_DISPLAY_TYPES; dispid++) {
                if(dev->mDispInfo[dispid].connected && dev->m_gralloc_module != NULL) {
                    int fbid = dev->mDispInfo[dispid].fb_num;
                    char fbname[HWC_STRING_LENGTH];
                    memset(fbname, 0, sizeof(fbname));
                    sprintf(fbname, "fb%d", fbid);
                    ALOGI("hwcomposer: open framebuffer %s", fbname);
                    dev->mFbDev[dispid] = (framebuffer_device_t*)fbid;
                    dev->m_gralloc_module->methods->open(dev->m_gralloc_module, fbname,
                               (struct hw_device_t**)&dev->mFbDev[dispid]);
                }
            }
    
            const hw_module_t *hwc_module;
            if(hw_get_module(HWC_VIV_HARDWARE_MODULE_ID,
                            (const hw_module_t**)&hwc_module) < 0) {
                ALOGE("Error! hw_get_module viv_hwc failed");
                goto nor_exit;
            }
    
            if(hwc_open_1(hwc_module, &(dev->m_viv_hwc)) != 0) {
                ALOGE("Error! viv_hwc open failed");
                goto nor_exit;
            }
    nor_exit:
    
            *device = &dev->device.common;
        ALOGI("%s,%d", __FUNCTION__, __LINE__);
            return 0;
    err_exit:
        if(dev){
            free(dev);
        }
            /****************************************/
        }
        return status;
    }
    
原文地址:https://www.cnblogs.com/zengjfgit/p/5873039.html