首页 > 代码库 > I.MX6 Surfaceflinger 机制

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().\n");        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;    }    

 

I.MX6 Surfaceflinger 机制