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;
    }
    

 

时间: 2024-09-29 11:13:41

I.MX6 Surfaceflinger 机制的相关文章

Android GUI系统之SurfaceFlinger(15) handlePageFlip

1.1.1 handlePageFlip PageFlip可以理解为"翻页".从这个意思上来看,它应该与图层缓冲区有关系--因为是多缓冲机制,在适当的时机,我们就需要做"翻页"的动作. void SurfaceFlinger::handlePageFlip() {-    const DisplayHardware&hw = graphicPlane(0).displayHardware();//编号为0的Display    const Regionscr

Android GUI系统之SurfaceFlinger(12) VSync信号的产生和处理

1.1 VSync的产生和处理 前面小节ProjectButter中我们学习了Android 4.1显示系统中的新特性,其中一个就是加入了VSync同步.我们从理论的角度分析了采用这一机制的必要性和运作机理,那么SurfaceFlinger具体是如何实施的呢? 先来想一下有哪些东西要考虑: · VSync信号的产生和分发 如果有硬件主动发出这一信号,那是最好的了;否则就得通过软件定时模拟来产生 · VSync信号的处理 当信号产生后,SurfaceFlinger如何在最短的时间内响应,具体处理流

Android GUI系统之SurfaceFlinger(9) Project Butter黄油计划

1.1 SurfaceFlinger 从这一小节开始,我们正式切入SurfaceFlinger的分析.为了保持讲解的连贯性,部分内容可能在前面的章节中已经有所涉及了,接下来将会对其中的细节做更多的扩展讲解. 内容组织如下: l  首先介绍Android 4.1引入的新特性(Project Butter),理解这个项目是必要的,可以说SurfaceFlinger有很大一部分的内容就是围绕它来的 l  SurfaceFlinger的启动过程及工作方式 l  SurfaceFlinger与Buffer

Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析_Android

        在前面几篇文章中,我们详细介绍了Android系统进程间通信机制Binder的原理,并且深入分析了系统提供的Binder运行库和驱动程序的源代码.细心的读者会发现,这几篇文章分析的Binder接口都是基于C/C++语言来实现的,但是我们在编写应用程序都是基于Java语言的,那么,我们如何使用Java语言来使用系统的Binder机制来进行进程间通信呢?这就是本文要介绍的Android系统应用程序框架层的用Java语言来实现的Binder接口了.        熟悉Android系统

I.MX6 Linux eGTouch TouchScreen porting

I.MX6 Linux eGTouch TouchScreen porting 一.Download Driver: http://www.eeti.com.tw/drivers_Linux.html 二.阅读:EETI eGTouch Linux Programming Guide 三.系统启动配置: ...... # 本人直接将驱动放在内核里了,并没有做成模块 # insmod /module/hid-multitouch.ko # 使用eGTouch_v2.5.4330.L-ma/eGTo

I.MX6 su.c 测试

/************************************************************************* * I.MX6 su.c 测试 * 说明: * 今天突然想分析一下su的源代码,看一下其工作机制. * * 2016-8-10 深圳 南山平山村 曾剑锋 ************************************************************************/ 一.su源代码修改: /* ** ** Copy

I.MX6 android BatteryService jni hacking

/**************************************************************************** * I.MX6 android BatteryService jni hacking * 声明: * 本文主要是为了知道Android的获取的电源管理的数据的jni是从Linux系统的 * 什么位置获取的,获取的机制是什么. * * 2016-2-22 深圳 南山平山村 曾剑锋 ********************************

I.MX6 mkuserimg.sh hacking

/*********************************************************************** * I.MX6 mkuserimg.sh hacking * 说明: * 上次发现Android源码使用mkuserimg.sh来打包Android文件系统,现在来 * 跟踪一下其内部的工作机制. * * 2016-6-28 深圳 南山平山村 曾剑锋 ***************************************************

I.MX6 按键开关机 PMIC 检测

/************************************************************************* * I.MX6 按键开关机 PMIC 检测 * 说明: * 最近一直在被i.MX6的开机.关机流程控制,其内部是如何检测到1秒按钮, * 2秒按钮,4秒按钮的,这其中的工作机制是如何实现,由于发现这部分工作并 * 不是在PMIC上实现了,现在终于在数据手册上找到这部分相关介绍. * * 2016-9-3 深圳 南山平山村 曾剑锋 *********