转载时请注明出处和作者 文章出处: http://www.cnblogs.com/xl19862005 作者:Xandy
用的是android2.3的代码
这些天来一直在看android display相关的代码和资料并作了一些尝试,现在将这些天来的工作记录如下,有错误的地方希望广大同行指正,谢谢!
经过阅读代码和查到的相关一些资料,对android双屏的支持总体思路如下图所示:

由于目前跟踪代码只跟到了surfaceflinger这一层,下面先从surfaceflinger说起:

在frameworks\base\services\surfaceflinger\surfaceflinger.cpp这个文件中有如下代码片断:

status_t SurfaceFlinger::readyToRun(){    LOGI("SurfaceFlinger's main thread ready to run. Initializing graphics H/W...\n");    // we only support one display currently    int dpy = 0;    {        // initialize the main display        GraphicPlane& plane(graphicPlane(dpy));        DisplayHardware* const hw = new DisplayHardware(this, dpy);                DisplayHardware* const hw1 = new DisplayHardware(this, 1); //这个是我加入测试HAL层用的,下面将介绍到                plane.setDisplayHardware(hw);    }    // create the shared control-block    mServerHeap = new MemoryHeapBase(4096,MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");        mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");        new(mServerCblk) surface_flinger_cblk_t;    // initialize primary screen    // (other display should be initialized in the same manner, but    // asynchronously, as they could come and go. None of this is supported    // yet).    const GraphicPlane& plane(graphicPlane(dpy));    const DisplayHardware& hw = plane.displayHardware();    const uint32_t w = hw.getWidth();    const uint32_t h = hw.getHeight();    const uint32_t f = hw.getFormat();    hw.makeCurrent();    // initialize the shared control block    mServerCblk->connected |= 1<<dpy;    display_cblk_t* dcblk = mServerCblk->displays + dpy;    memset(dcblk, 0, sizeof(display_cblk_t));    dcblk->w            = plane.getWidth();    dcblk->h            = plane.getHeight();    dcblk->format       = f;    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;    dcblk->xdpi         = hw.getDpiX();    dcblk->ydpi         = hw.getDpiY();    dcblk->fps          = hw.getRefreshRate();    dcblk->density      = hw.getDensity();    // Initialize OpenGL|ES    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);    glPixelStorei(GL_PACK_ALIGNMENT, 4);     glEnableClientState(GL_VERTEX_ARRAY);    glEnable(GL_SCISSOR_TEST);    glShadeModel(GL_FLAT);    glDisable(GL_DITHER);    glDisable(GL_CULL_FACE);    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);    const uint16_t g1 = pack565(0x17,0x2f,0x17);    const uint16_t textureData[4] = { g0, g1, g1, g0 };    glGenTextures(1, &mWormholeTexName);    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData);    glViewport(0, 0, w, h);    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    glOrthof(0, w, h, 0, 0, 1);   LayerDim::initDimmer(this, w, h);    mReadyToRunBarrier.open();    /*     *  We're now ready to accept clients...     */    // start boot animation    property_set("ctl.start", "bootanim");        return NO_ERROR;}

  重点看上面用黄色标出的那两行,其中DisplayHardware* const hw1 = new DisplayHardware(this, 1);是我加入用来测试HAL层的buffer分配用的,DisplayHardware这个是在frameworks\base\services\surfaceflinger\DisplayHardware\DisplayHardware.cpp这个文件中定义的,如以下代码片断:

/* * Initialize the display to the specified values. * */DisplayHardware::DisplayHardware(const sp<SurfaceFlinger>& flinger,uint32_t dpy)    : DisplayHardwareBase(flinger, dpy),mFlags(0){    init(dpy);}

  而在同文件中有如下代码片断:

void DisplayHardware::init(uint32_t dpy){    mNativeWindow = new FramebufferNativeWindow(dpy);        framebuffer_device_t const * fbDev = mNativeWindow->getDevice();    mDpiX = mNativeWindow->xdpi;    mDpiY = mNativeWindow->ydpi;    mRefreshRate = fbDev->fps;    mOverlayEngine = NULL;    hw_module_t const* module;    if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0)     {        overlay_control_open(module, &mOverlayEngine);    }    EGLint w, h, dummy;    EGLint numConfigs=0;    EGLSurface surface;    EGLContext context;    // initialize EGL    EGLint attribs[] =     {            EGL_SURFACE_TYPE,              EGL_WINDOW_BIT,            EGL_NONE,                    0,            EGL_NONE    };    // debug: disable h/w rendering    char property[PROPERTY_VALUE_MAX];    if (property_get("debug.sf.hw", property, NULL) > 0)     {        if (atoi(property) == 0)         {            LOGW("H/W composition disabled");            attribs[2] = EGL_CONFIG_CAVEAT;            attribs[3] = EGL_SLOW_CONFIG;        }    }    // TODO: all the extensions below should be queried through    // eglGetProcAddress().    // set to EGL wrapper to load SW OpenGLES only     if (property_get("debug.sf.enable_hgl", property, "1") > 0)     {        if (atoi(property) == 0)         {            eglSetImplementationAndroid(EGL_TRUE);        }    }/*下面这些都是和egl相关的,目前正在研究中,由于代码量太大,一起不好发上来,这里简单介绍一下,frameworks\base\opengl\libagl目录下是agl相关的一些代码,这些代码会生成libGLES_android.so 这个动态库,这点可以从此目录下的Android.mk文件里看出:LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/eglLOCAL_MODULE:= libGLES_android    在frameworks\base\opengl\libs目录下是egl相关的一些代码,这些代码主要把agl这个库作了个封装,并向外提供相关接口*/    EGLDisplay display = eglGetDisplay((NativeDisplayType)dpy);//(EGL_DEFAULT_DISPLAY);    LOGI("******DisplayHardware.cpp display:%d******\n",(int)display);    eglInitialize(display, NULL, NULL);    eglGetConfigs(display, NULL, 0, &numConfigs);    EGLConfig config;    status_t err = EGLUtils::selectConfigForNativeWindow(display, attribs, mNativeWindow.get(), &config);    LOGE_IF(err, "couldn't find an EGLConfig matching the screen format");        EGLint r,g,b,a;    eglGetConfigAttrib(display, config, EGL_RED_SIZE,   &r);    eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &g);    eglGetConfigAttrib(display, config, EGL_BLUE_SIZE,  &b);    eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &a);    if (mNativeWindow->isUpdateOnDemand())         mFlags |= PARTIAL_UPDATES;        if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE)     {        if (dummy == EGL_SLOW_CONFIG)            mFlags |= SLOW_CONFIG;    }    /*     * Create our main surface     */    surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL);    eglQuerySurface(display, surface, EGL_WIDTH,  &mWidth);    eglQuerySurface(display, surface, EGL_HEIGHT, &mHeight);    if (mFlags & PARTIAL_UPDATES)     {        // if we have partial updates, we definitely don't need to        // preserve the backbuffer, which may be costly.        eglSurfaceAttrib(display, surface,EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);    }    if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE)     {        if (dummy == EGL_BUFFER_PRESERVED)         {            mFlags |= BUFFER_PRESERVED;        }    }        /* Read density from build-specific ro.sf.lcd_density property     * except if it is overridden by qemu.sf.lcd_density.     */    if (property_get("qemu.sf.lcd_density", property, NULL) <= 0)    {        if (property_get("ro.sf.lcd_density", property, NULL) <= 0)        {            LOGW("ro.sf.lcd_density not defined, using 160 dpi by default.");            strcpy(property, "160");        }    }    else     {        /* for the emulator case, reset the dpi values too */        mDpiX = mDpiY = atoi(property);    }    mDensity = atoi(property) * (1.0f/160.0f);    /*     * Create our OpenGL ES context     */        EGLint contextAttributes[] =     {#ifdef EGL_IMG_context_priority#ifdef HAS_CONTEXT_PRIORITY#warning "using EGL_IMG_context_priority"        EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,#endif#endif        EGL_NONE, EGL_NONE    };    context = eglCreateContext(display, config, NULL, contextAttributes);    mDisplay = display;    mConfig  = config;    mSurface = surface;    mContext = context;    mFormat  = fbDev->format;    mPageFlipCount = 0;    /*     * Gather OpenGL ES extensions     */    eglMakeCurrent(display, surface, surface, context);    GLExtensions& extensions(GLExtensions::getInstance());    extensions.initWithGLStrings(glGetString(GL_VENDOR),                                                 glGetString(GL_RENDERER),                                                 glGetString(GL_VERSION),                                                 glGetString(GL_EXTENSIONS),                                                 eglQueryString(display, EGL_VENDOR),                                                 eglQueryString(display, EGL_VERSION),                                                 eglQueryString(display, EGL_EXTENSIONS));    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, &mMaxViewportDims);#ifdef EGL_ANDROID_swap_rectangle    if (extensions.hasExtension("EGL_ANDROID_swap_rectangle"))     {        if (eglSetSwapRectangleANDROID(display, surface,0, 0, mWidth, mHeight) == EGL_TRUE)         {            // This could fail if this extension is not supported by this            // specific surface (of config)            mFlags |= SWAP_RECTANGLE;        }    }    // when we have the choice between PARTIAL_UPDATES and SWAP_RECTANGLE    // choose PARTIAL_UPDATES, which should be more efficient#ifdef FSL_EPDC_FB#else    if (mFlags & PARTIAL_UPDATES)        mFlags &= ~SWAP_RECTANGLE;#endif#endif    LOGI("EGL informations:");    LOGI("# of configs : %d", numConfigs);    LOGI("vendor    : %s", extensions.getEglVendor());    LOGI("version   : %s", extensions.getEglVersion());    LOGI("extensions: %s", extensions.getEglExtension());    LOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");    LOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, config);    LOGI("OpenGL informations:");    LOGI("vendor    : %s", extensions.getVendor());    LOGI("renderer  : %s", extensions.getRenderer());    LOGI("version   : %s", extensions.getVersion());    LOGI("extensions: %s", extensions.getExtension());    LOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);    LOGI("GL_MAX_VIEWPORT_DIMS = %d", mMaxViewportDims);    LOGI("flags = %08x", mFlags);    // Unbind the context from this thread    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);}

  上面代码黄色标出的将会new一个framebufferNativeWindow,其实就是通过HAL层的Gralloc这个库映射到kernel层中的framebuffer

  在frameworks\base\libs\ui\FramebufferNativeWindow.cpp这个文件中有如下代码片断:

FramebufferNativeWindow::FramebufferNativeWindow(uint32_t dpy)    : BASE(), fbDev(0), grDev(0), mUpdateOnDemand(false){    hw_module_t const* module;    char GRALLOC_MODE[10];    char GRALLOC_FB[10];    char GRALLOC_GPU[10];    if(dpy == DISPLAY0)    {        strcpy(GRALLOC_MODE,GRALLOC_HARDWARE_MODULE_ID0);        strcpy(GRALLOC_FB,GRALLOC_HARDWARE_FB0);        strcpy(GRALLOC_GPU,GRALLOC_HARDWARE_GPU0);    }    else if(dpy == DISPLAY1)    {        strcpy(GRALLOC_MODE,GRALLOC_HARDWARE_MODULE_ID1);        strcpy(GRALLOC_FB,GRALLOC_HARDWARE_FB1);        strcpy(GRALLOC_GPU,GRALLOC_HARDWARE_GPU1);    }    else    {        strcpy(GRALLOC_MODE,GRALLOC_HARDWARE_MODULE_ID0);        strcpy(GRALLOC_FB,GRALLOC_HARDWARE_FB0);        strcpy(GRALLOC_GPU,GRALLOC_HARDWARE_GPU0);    }/*这个函数的原型是没有传入参数的,为了增加对second display的支持自行加入的,上面这些代码也是后来加入的,为的是根据传入的dpy(display 0/1)打开相应的Gralloc和GPU的库文件*/        if (hw_get_module(GRALLOC_MODE, &module) == 0)     {        int stride;        int err;        int i;        err = framebuffer_open(module,GRALLOC_FB, &fbDev);        LOGE_IF(err, "couldn't open framebuffer HAL (%s)", strerror(-err));                err = gralloc_open(module,GRALLOC_GPU, &grDev);        LOGE_IF(err, "couldn't open gralloc HAL (%s)", strerror(-err));        // bail out if we can't initialize the modules        if (!fbDev || !grDev)            return;                mUpdateOnDemand = (fbDev->setUpdateRect != 0);                // initialize the buffer FIFO mNumBuffers = fbDev->reserved[0];        if (mNumBuffers != 3 && mNumBuffers != 2)         {            LOGE("The framebuffer number got from HAL is not supported(%d)", mNumBuffers);            return;        }        mNumFreeBuffers = mNumBuffers;        mBufferHead = mNumBuffers-1;        for (i = 0; i < mNumBuffers; i++) buffers[i] = new NativeBuffer(fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB); for (i = 0; i < mNumBuffers; i++) { err = grDev->alloc(grDev,fbDev->width, fbDev->height, fbDev->format,GRALLOC_USAGE_HW_FB, &buffers[i]->handle, &buffers[i]->stride); LOGE_IF(err, "fb buffer %d allocation failed w=%d, h=%d, err=%s",i, fbDev->width, fbDev->height, strerror(-err)); }        const_cast<uint32_t&>(ANativeWindow::flags) = fbDev->flags;         const_cast<float&>(ANativeWindow::xdpi) = fbDev->xdpi;        const_cast<float&>(ANativeWindow::ydpi) = fbDev->ydpi;        const_cast<int&>(ANativeWindow::minSwapInterval) = fbDev->minSwapInterval;        const_cast<int&>(ANativeWindow::maxSwapInterval) = fbDev->maxSwapInterval;    }     else     {        LOGE("Couldn't get gralloc module");    }    ANativeWindow::setSwapInterval = setSwapInterval;    ANativeWindow::dequeueBuffer = dequeueBuffer;    ANativeWindow::lockBuffer = lockBuffer;    ANativeWindow::queueBuffer = queueBuffer;    ANativeWindow::query = query;    ANativeWindow::perform = perform;}

  重点在上面用黄色标出的这几行代码,hw_get_module会根据传入的dpy选择打开gralloc0还是gralloc1,framebuffer_open会根据传入的dpy选择打开fb0还是fb1,gralloc_open会根据传入的dpy选择打开gpu0还是gpu1;接下来的几行代码都是和buffer相关,mNumBuffers在这里等于3,先new NativeBuffer得到相应的buffers[i](i=0/1/2),grDev->alloc将会为这些buffers分配内存。

  在hardware\libhardware\include\hardware\Gralloc.h文件中有如下定义,为了加入second display我这里作了一些修改

/** * The id of this module */#define GRALLOC_HARDWARE_MODULE_ID0   "gralloc0"#define GRALLOC_HARDWARE_MODULE_ID1  "gralloc1"/** * Name of the graphics device to open */#define GRALLOC_HARDWARE_FB0 "fb0"#define GRALLOC_HARDWARE_FB1 "fb1"#define GRALLOC_HARDWARE_GPU0 "gpu0"#define GRALLOC_HARDWARE_GPU1 "gpu1"..../** convenience API for opening and closing a supported device 下面这些封装都是在得到了module这个结构体之后得到相应的函数入口*/static inline int gralloc_open(const struct hw_module_t* module, const char * name,struct alloc_device_t** device) {    return module->methods->open(module, name, (struct hw_device_t**)device);}static inline int gralloc_close(struct alloc_device_t* device) {    return device->common.close(&device->common);}static inline int framebuffer_open(const struct hw_module_t* module,const char * name, struct framebuffer_device_t** device) {    return module->methods->open(module,name, (struct hw_device_t**)device);}static inline int framebuffer_close(struct framebuffer_device_t* device) {    return device->common.close(&device->common);}

  上面这些代码就是通过打开不同的gralloc模块,得到不同的函数入口地址,这里我对gralloc分别新建了两个,一个映射到fb0,一个映射到fb1,如下文件列表:


  

其中libgralloc_sec_display是我后来加入的,先看libgralloc里面的内容:

在gralloc.cpp这个文件里有如下代码片断:

/*这里的open就是打开gralloc这个模块之后与在gralloc.h中module->methods->open相对应了*/static struct hw_module_methods_t gralloc_module_methods = {        open: gralloc_device_open};struct private_module_t HAL_MODULE_INFO_SYM = {    base:     {        common:         {            tag: HARDWARE_MODULE_TAG,            version_major: 1,            version_minor: 0,            id: GRALLOC_HARDWARE_MODULE_ID0,            name: "Graphics Memory Allocator Module",            author: "The Android Open Source Project",            methods: &gralloc_module_methods        },        registerBuffer: gralloc_register_buffer,        unregisterBuffer: gralloc_unregister_buffer,        lock: gralloc_lock,        unlock: gralloc_unlock,    },    framebuffer: 0,    flags: 0,    numBuffers: 0,    bufferMask: 0,    lock: PTHREAD_MUTEX_INITIALIZER,    currentBuffer: 0,    pmem_master: -1,    pmem_master_base: 0,    master_phys: 0};

  open的实现代码如下:

int gralloc_device_open(const hw_module_t* module, const char* name,hw_device_t** device){    int status = -EINVAL;    //name = GRALLOC_HARDWARE_FB0 or GRALLOC_HARDWARE_GPU0    GRALLLOGI0("*********gralloc_devide_open : name = %s********\n",name);    if (!strcmp(name, GRALLOC_HARDWARE_GPU0))     {        gralloc_context_t *dev;        dev = (gralloc_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.version = 0;        dev->device.common.module = const_cast<hw_module_t*>(module);        dev->device.common.close = gralloc_close;        dev->device.alloc   = gralloc_alloc;        dev->device.free    = gralloc_free;        *device = &dev->device.common;        status = 0;    }     else     {        status = fb_device_open(module, name, device);/* 这里是调用了同目录下framebuffer.cpp文件中的函数*/    }    return status;}

  同样在gralloc_sec_display这个里面也会有如上一样的内容,这里不再列出,其实以上说的这些都是在为framebuffer在内存中的分配作准备包括GPU在内存中的空间。

在framebuffer.cpp文件中有如下代码片断:

int fb_device_open(hw_module_t const* module, const char* name,hw_device_t** device){    int status = -EINVAL;    char value[PROPERTY_VALUE_MAX];    if (!strcmp(name, GRALLOC_HARDWARE_FB0))     {        alloc_device_t* gralloc_device;        framebuffer_device_t *fbdev;        nr_framebuffers = NUM_BUFFERS;        property_get("ro.product.device", value, "");        if (0 == strcmp(value, "imx50_rdp")) {            nr_framebuffers = 2;            no_ipu = 1;        }        status = gralloc_open(module,GRALLOC_HARDWARE_GPU0, &gralloc_device);        if (status < 0)            return status;        /* initialize our state here */        fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev));        memset(dev, 0, sizeof(*dev));        /* initialize the procs */        dev->device.common.tag = HARDWARE_DEVICE_TAG;        dev->device.common.version = 0;        dev->device.common.module = const_cast<hw_module_t*>(module);        dev->device.common.close = fb_close;        dev->device.setSwapInterval = fb_setSwapInterval;        dev->device.post = fb_post;        #ifndef FSL_EPDC_FB        dev->device.setUpdateRect = 0;        #else        dev->device.setUpdateRect = fb_setUpdateRect;        #endif        dev->device.compositionComplete = fb_compositionComplete;        #ifdef TVOUT_DISPLAY_SUPPORT        dev->device.setSecRotation = fb_setSecRotation;        #endif        private_module_t* m = (private_module_t*)module;        status = mapFrameBuffer(m);        if (status >= 0)         {            int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3);            const_cast<uint32_t&>(dev->device.flags) = 0xfb0;            const_cast<uint32_t&>(dev->device.width) = m->info.xres;            const_cast<uint32_t&>(dev->device.height) = m->info.yres;            const_cast<int&>(dev->device.stride) = stride;            if(m->info.bits_per_pixel != 32)             {                const_cast<int&>(dev->device.format) = HAL_PIXEL_FORMAT_RGB_565;            }            else            {                const_cast<int&>(dev->device.format) = HAL_PIXEL_FORMAT_BGRA_8888;            }            const_cast<float&>(dev->device.xdpi) = m->xdpi;            const_cast<float&>(dev->device.ydpi) = m->ydpi;            const_cast<float&>(dev->device.fps) = m->fps;            const_cast<int&>(dev->device.minSwapInterval) = 1;            const_cast<int&>(dev->device.maxSwapInterval) = 1;            *device = &dev->device.common;            fbdev = (framebuffer_device_t*) *device;            fbdev->reserved[0] = nr_framebuffers;        }    /* initialize the IPU lib IPC */        if (!no_ipu)            mxc_ipu_lib_ipc_init();    }    return status;}

  这里重点在上面黄色标出的两处,fb_post和刷屏相关,只要FB0里面的数据有变化,就会行动这里面的代码,mapFrameBuffer会把内核空间的fb0映射到用户空间,这样上层就能使用fb0了 。

  gralloc1与gralloc0的不同之处主要在于对fb的映射,gralloc0是把fb0映射到了用户空间并与LCD0绑定,而gralloc1则是把fb1映射到了用户空间并与LCD1绑定,在framebuffer_sec.cpp有如下代码片断:

/*********************************************************name:mapTVFrameBufferLocked*param:module*author:Xandy*说明:此函数经过改装过,把fb1映射给了LCD1********************************************************/int mapTVFrameBufferLocked(struct TV_fb_module_t* module){    // already initialized...    if (module->TVframebuffer)     {        return 0;    }    int TV_fd = -1;    struct mxcfb_color_key key;     set_graphics_fb_mode(1, 1);    TV_fd = open("/dev/graphics/fb1", O_RDWR, 0);    if (TV_fd < 0)        return -errno;    struct fb_fix_screeninfo finfo;    if (ioctl(TV_fd, FBIOGET_FSCREENINFO, &finfo) == -1)        return -errno;    struct fb_var_screeninfo info;    if (ioctl(TV_fd, FBIOGET_VSCREENINFO, &info) == -1)        return -errno;    info.reserved[0] = 0;    info.reserved[1] = 0;    info.reserved[2] = 0;    info.xoffset = 0;    info.yoffset = 0;    info.activate = FB_ACTIVATE_NOW;                

  而framebuffer.cpp相同的地方则如下:

int mapFrameBufferLocked(struct private_module_t* module){    // already initialized...    if (module->framebuffer)     {        return 0;    }            char const * const device_template[] = {            "/dev/graphics/fb%u",            "/dev/fb%u",            0 };    int fd = -1;    int i=0;    char name[64];    char value[PROPERTY_VALUE_MAX];    property_get("ro.UI_TVOUT_DISPLAY", value, "");    if (strcmp(value, "1") != 0)     {        set_graphics_fb_mode(0, 0);        while ((fd==-1) && device_template[i]) {            snprintf(name, 64, device_template[i], 0);            fd = open(name, O_RDWR, 0);            i++;        }    }    else    {        set_graphics_fb_mode(1, 0);        while ((fd==-1) && device_template[i]) { snprintf(name, 64, device_template[i], 1); fd = open(name, O_RDWR, 0); i++; }    }    if (fd < 0)        return -errno;    struct fb_fix_screeninfo finfo;    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)        return -errno;    struct fb_var_screeninfo info;    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)        return -errno;

  下面看看串口打印出来的信息:

/*系统起来后,开启ServiceManager,这是因为SurfaceFlinger是一个service*/
I/sysproc ( 2098): Entered system_init()I/sysproc ( 2098): ServiceManager: 0x11d9f8I/SurfaceFlinger( 2098): SurfaceFlinger is starting  /*SurfaceFlinger启动,这个service将会一直运行*/I/SurfaceFlinger( 2098): SurfaceFlinger's main thread ready to run. Initializing graphics H/W...I/imx5x.gralloc0( 2098): *********gralloc_devide_open : name = fb0********  /*打开gralloc0之后,得到得到相应的函数入口并为fb0与gpu0分配内存*/I/imx5x.gralloc0( 2098): *********gralloc_devide_open : name = gpu0********
/*fb0初始化之后的一些信息*/
I/imx5x.gralloc0( 2098): 16bpp setting of Framebuffer catched!I/imx5x.gralloc0( 2098): using (fd=24)I/imx5x.gralloc0( 2098): id           = DISP3 BGI/imx5x.gralloc0( 2098): xres         = 800 pxI/imx5x.gralloc0( 2098): yres         = 480 pxI/imx5x.gralloc0( 2098): xres_virtual = 800 pxI/imx5x.gralloc0( 2098): yres_virtual = 1536 pxI/imx5x.gralloc0( 2098): bpp          = 16I/imx5x.gralloc0( 2098): r            = 11:5I/imx5x.gralloc0( 2098): g            =  5:6I/imx5x.gralloc0( 2098): b            =  0:5I/imx5x.gralloc0( 2098): width        = 127 mm (160.000000 dpi)I/imx5x.gralloc0( 2098): height       = 76 mm (160.421051 dpi)I/imx5x.gralloc0( 2098): refresh rate = 62.02 HzI/imx5x.gralloc0( 2098): *********gralloc_devide_open : name = gpu0********I/imx5x.gralloc0( 2098): ******Gralloc.cpp numBuffers:3******I/imx5x.gralloc0( 2098): ******Gralloc.cpp numBuffers:3******I/imx5x.gralloc0( 2098): ******Gralloc.cpp numBuffers:3******I/FslOverlay( 2098): hardware/mx5x/liboverlay/overlay.cpp: overlay_device_openI/FslOverlay( 2098): overlay_device_open control pid 2098,tid 2106I/FslOverlay( 2098): hardware/mx5x/liboverlay/overlay.cpp: overlay_init_fbdevI/FslOverlay( 2098): /dev/graphics/fb0 fb_var: bits_per_pixel 16,xres 800,yres 480,xres_virtual 800,yres_virtual 1536I/FslOverlay( 2098): hardware/mx5x/liboverlay/overlay.cpp: create_control_shared_dataI/FslOverlay( 2098): ***************create_control_shared_data mmap in*********************I/FslOverlay( 2098): ***************create_control_shared_data mmap out:0x2ea3e000****************I/FslOverlay( 2098): hardware/mx5x/liboverlay/overlay_thread.h: onFirstRefI/FslOverlay( 2098): Overlay HAL control device Created successfully
/*load egl库*/I/libEGL  ( 2098): ******eglGetDisplay in egl : 0******I/FslOverlay( 2098): Overlay thread running pid 2098 tid 2108D/libEGL  ( 2098): loaded /system/lib/egl/libGLES_android.soI/libagl  ( 2098): ******eglGetDisplay in libagl : 0******I/libEGL  ( 2098): ******Egl.cpp IMPL_SOFTWARE dpy=1D/libEGL  ( 2098): loaded /system/lib/egl/libEGL_imx51.soD/libEGL  ( 2098): loaded /system/lib/egl/libGLESv1_CM_imx51.soD/libEGL  ( 2098): loaded /system/lib/egl/libGLESv2_imx51.soI/libEGL  ( 2098): ******Egl.cpp IMPL_HARDWARE dpy=1I/SurfaceFlinger( 2098): ******DisplayHardware.cpp display:1******I/libEGL  ( 2098): ******egl.cpp eglInitialize******I/libEGL  ( 2098): ******egl.cpp IMX5X,dp->disp[0].dpy=0x2******I/libEGL  ( 2098): initialized 0 dpy=0x2, ver=1.4, cnx=0x6be08b54I/libEGL  ( 2098): ******egl.cpp IMX5X,dp->disp[1].dpy=0x1******I/libagl  ( 2098): ******libagl.cpp eglInitialize******I/libEGL  ( 2098): initialized 1 dpy=0x1, ver=1.2, cnx=0x6be08c0cI/libEGL  ( 2098): ******egl egl.cpp eglCreateWindowSurface******W/SurfaceFlinger( 2098): ro.sf.lcd_de*****************mxcfb_set_par*****************
/*ipu相关,这些都是在kernel和HAL进行的*/mxc_ipu mxc_ipu: Channel already disabled 7mxc_ipu mxc_ipu: Channel already uninitialized 7TVE: fb mode change event: xres=1280, yres=1024nsity not defined, using 160 dpi**********************fb mmap in:0x2f8c1000******************* by default.I/SurfaceFlinger( *****************************ipuv3 fb mmap in 0x2f8c1000*************************2098): EGL informations:I/SurfaceFlinger( 2098): # of configs : 35I/SurfaceFlinger( 2098): vendor    : Advanced Micro Devices, IncI/SurfaceFlinger( 2098): version   : 1.4 Internal version 1.4.1I/SurfaceFlinger( 2098): extensions: eglCreatePbufferFromClientBuffer EGL_KHR_image EGL_KHR_image_base EGL_KHR_image_pixmap EGL_ANDROID_image_native_buffer EGL_AMD_create_imageI/SurfaceFlinger( 2098): Client API: NULLI/SurfaceFlinger( 2098): EGLSurface: 5-6-5-0, config=0x6I/SurfaceFlinger( 2098): OpenGL informations:I/SurfaceFlinger( 2098): vendor    : Advanced Micro Devices, Inc.I/SurfaceFlinger( 2098): renderer  : AMD Z430I/SurfaceFlinger( 2098): version   : OpenGL ES-CM 1.1I/SurfaceFlinger( 2098): extensions: GL_AMD_compressed_3DC_texture GL_AMD_compressed_ATC_texture GL_AMD_performance_monitor GL_ATI_compressed_texture_atitc GL_ATI_texture_compression_atitc GL_OES_blend_equation_separate GL_OES_blend_func_separate GL_OES_blend_subtract GL_OES_compressed_ETC1_RGB8_texture GL_OES_compressed_paletted_texture GL_OES_draw_texture GL_OES_extended_matrix_palette GL_OES_EGL_image GL_OES_EGL_image_external GL_OES_framebuffer_object GL_OES_matrix_palette GL_OES_point_size_array GL_OES_point_sprite GL_OES_read_format GL_OES_stencil_wrap GL_OES_texture_cube_map GL_OES_texture_env_crossbar GL_OES_texture_mirrored_repeat I/SurfaceFlinger( 2098): GL_MAX_TEXTURE_SIZE = 2048I/SurfaceFlinger( 2098): GL_MAX_VIEWPORT_DIMS = 2048I/SurfaceFlinger( 2098): flags = 00000000
/*上面是在surfaceflinger.cpp上DisplayHardware* const hw = new DisplayHardware(this, dpy);这个所创建的,下面的则是我自己加入的DisplayHardware* const hw1 = new DisplayHardware(this, 1);这句所创建的,由于目前做的是车载双屏系统,后台一个电视,这里把xres与yres设置成了1280x1024px*/
I/imx5x.gralloc1( 2098): *********gralloc_devide_open : name = fb1********I/imx5x.gralloc1( 2098): *********gralloc_devide_open : name = gpu1********I/imx5x.gralloc1( 2098): using (TV_fd=34)I/imx5x.gralloc1( 2098): id           = DISP3 BG - DI1I/imx5x.gralloc1( 2098): xres         = 1280 pxI/imx5x.gralloc1( 2098): yres         = 1024 pxI/imx5x.gralloc1( 2098): xres_virtual = 1280 pxI/imx5x.gralloc1( 2098): yres_virtual = 3072 pxI/imx5x.gralloc1( 2098): bpp          = 16I/imx5x.gralloc1( 2098): r            = 11:5I/imx5x.gralloc1( 2098): g            =  5:6I/imx5x.gralloc1( 2098): b            =  0:5I/imx5x.gralloc1( 2098): width        = 203 mm (160.157639 dpi)I/imx5x.gralloc1( 2098): height       = 163 mm (159.568100 dpi)I/imx5x.gralloc1( 2098): refresh rate = 60.56 HzI/imx5x.gralloc1( 2098): *********gralloc_devide_open : name = gpu1********I/imx5x.gralloc1( 2098): ******Gralloc.cpp numBuffers:3******I/imx5x.gralloc1( 2098): ******Gralloc.cpp numBuffers:3******I/imx5x.gralloc1( 2098): ******Gralloc.cpp numBuffers:3******I/FslOverlay( 2098): hardware/mx5x/liboverlay/overlay.cpp: overlay_device_openI/FslOverlay( 2098): overlay_device_open control pid 2098,tid 2106I/FslOverlay( 2098): hardware/mx5x/liboverlay/overlay.cpp: overlay_init_fbdevI/FslOverlay( 209pmem: request for physical address of pmem region from process 2104.8): /dev/graphics/fb0 fb_var: bits_per_pixel 16,xres 800,yres 480,xres_virtual 800,yres_virtual 1536I/FslOverlay( 2098): hardware/mx5x/liboverlay/overlay.cpp: create_control_shared_dataI/FslOverlay( 2098): ***************create_control_shared_data mmap in*********************I/FslOverlay( 2098): ***************create_control_shared_data mmap out:0x2ea48000****************I/FslOverlay( 2098): hardware/mx5x/liboverlay/overlay_thread.h: onFirstRefI/FslOverlay( 2098): Overlay HAL control device Created successfullyI/libEGL  ( 2098): ******eglGetDisplay in egl : 1******I/SurfaceFlinger( 2098): ******DisplayHardware.cpp display:2******I/libEGL  ( 2098): ******egl.cpp eglInitialize******I/libEGL  ( 2098): ******egl.cpp IMX5X,dp->disp[0].dpy=0x3******I/libEGL  ( 2098): initialized 0 dpy=0x3, ver=1.4, cnx=0x6be08b54I/libEGL  ( 2098): ******egl.cpp IMX5X,dp->disp[1].dpy=0x0******
/*这里还有一些问题需要解决,主要是egl相关的一些东西,目前正在研究中!*/I/libagl  ( 2098): libagl egl.cpp:display is valid!!******W/libEGL  ( 2098): 1: eglInitialize(0x0) failed (EGL_BAD_DISPLAY)I/libEGL  ( 2098): ******egl egl.cpp eglCreateWindowSurface******E/imx5x.gralloc1( 2098): FBIOPAN_DISPLAY failedW/SurfaceFlinger( 2098): ro.sf.lcd_density not defined, using 160 dpi by default.E/imx5x.gralloc1( 2098): FBIOPAN_DISPLAY failedI/FslOverlay( 2098): Overlay thread running pid 2098 tid 2111I/SurfaceFlinger( 2098): EGL informations:I/SurfaceFlinger( 2098): # of configs : 27I/SurfaceFlinger( 2098): vendor    : Advanced Micro Devices, IncI/SurfaceFlinger( 2098): version   : 1.4 Internal version 1.4.1I/SurfaceFlinger( 2098): extensions: eglCreatePbufferFromClientBuffer EGL_KHR_image EGL_KHR_image_base EGL_KHR_image_pixmap EGL_ANDROID_image_native_buffer EGL_AMD_create_imageI/SurfaceFlinger( 2098): Client API: NULLI/SurfaceFlinger( 2098): EGLSurface: 5-6-5-0, config=0x6I/SurfaceFlinger( 2098): OpenGL informations:I/SurfaceFlinger( 2098): vendor    : Advanced Micro Devices, Inc.I/SurfaceFlinger( 2098): renderer  : AMD Z430I/SurfaceFlinger( 2098): version   : OpenGL ES-CM 1.1I/SurfaceFlinger( 2098): extensions: GL_AMD_compressed_3DC_texture GL_AMD_compressed_ATC_texture GL_AMD_performance_monitor GL_ATI_compressed_texture_atitc GL_ATI_texture_compression_atitc GL_OES_blend_equation_separate GL_OES_blend_func_separate GL_OES_blend_subtract GL_OES_compressed_ETC1_RGB8_texture GL_OES_compressed_paletted_texture GL_OES_draw_texture GL_OES_extended_matrix_palette GL_OES_EGL_image GL_OES_EGL_image_external GL_OES_framebuffer_object GL_OES_matrix_palette GL_OES_point_size_array GL_OES_point_sprite GL_OES_read_format GL_OES_stencil_wrap GL_OES_texture_cube_map GL_OES_texture_env_crossbar GL_OES_texture_mirrored_repeat I/SurfaceFlinger( 2098): GL_MAX_TEXTURE_SIZE = 2048I/SurfaceFlinger( 2098): GL_MAX_VIEWPORT_DIMS = 2048I/SurfaceFlinger( 2098): flags = 00000000

更多相关文章

  1. Android(安卓)CPU 架构详解
  2. Android(安卓)Studio 翻译插件Translation和strings.xml多语言文
  3. Android常用加密手段之MD5加密(字符串加密和文件加密)
  4. Android常用的数据加密方式代码详解
  5. Linux 下使用命令行开发 Android(安卓)应用程序~~玩玩还行
  6. Android中JNI的使用之一:Java原生JNI的使用、javah指令的使用以及
  7. 在Android中调用WebService .
  8. react-native-vector-icons使用
  9. Android(安卓)在一个APP内打开另一个APP

随机推荐

  1. 更改android锁屏方向
  2. Android(安卓)HTTP协议请求网络(一)之认
  3. Android中WebView页面交互
  4. Android:Intent Filter 和 action 简介
  5. No resource found that matches the giv
  6. Android设备管理器漏洞
  7. android studio 2.1 preview4 之 gradle
  8. Android中文 API (31) —— TimePicker
  9. android控件隐藏与显示
  10. Android(安卓)Touch事件分发机制