• 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;
        }
        
  • 相关阅读:
    【33】避免遮掩继承而来的名称
    调用异步方法
    Python 调用C++
    【37】绝不重新定义继承而来的缺省参数值
    【36】绝不重新定义继承而来的non-virtual方法
    【38】通过复合塑模出Has-A 或根据某物实现出
    【转】C++ function、bind以及lamda表达式
    mongodb
    mongodb
    mongodb
  • 原文地址:https://www.cnblogs.com/zengjfgit/p/5873039.html
Copyright © 2020-2023  润新知