Android GUI FramebufferNativeWindow ANativeWindow

来源:互联网 发布:用eclipse写java 编辑:程序博客网 时间:2024/06/07 02:22

Android GUI FramebufferNativeWindow ANativeWindow

Android系统的GUI设计的两种本地窗口:
面向管理者(SurfaceFlinger)
SurfaceFlinger扮演了系统中所有UI界面的管理者,它需要直接或间接地持有“本地窗口”,这个窗口就是FramebufferNativeWindow
面向应用程序
—-这类窗口是SurfaceTextureClient
这里写图片描述
Window-1 是能直接显示在终端屏幕上, 它使用了帧缓冲区
Window-2 是从内存缓冲区分配的空间

OpenGL“本地窗口”(NativeWindow),Android系统通过ANativeWindow实现OpenGL ES的本地化, 而FramebufferNativeWindow是ANativeWindow子类,对应的是真实的物理屏幕。
OpenGL ES ->ANativeWindow->FramebufferNativeWindow

OpenGL ES 本质上是一个图形渲染管线的状态机
EGL
1、为 OpenGL ES 提供平台独立性而设计
2、是 OpenGL ES 和底层 Native 平台视窗系统之间的接口
3、用于监控图形渲染管线的状态以及维护 Frame buffer 和其他渲染 Surface 的外部层
—-OpenGL ES 图形管线的状态被存储于 EGL 管理的一个 Context 中。 Frame Buffers 和其他绘制 Surfaces 通过 EGL API 创建、管理和销毁。 EGL 同时也控制和提供了对设备显示和可能的设备渲染配置的访问
这里写图片描述

EGL 应用:

EGLDisplay mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); // 1、获取显示设备 //EGLDisplay eglGetDisplay (NativeDisplayType display); //display 参数是native系统的窗口显示ID值 eglInitialize(mEglDisplay, &major, &minor); // 2、初始化显示设备、获取EGL版本号EGLint config_attribs[] = {    EGL_BLUE_SIZE, 8,    EGL_GREEN_SIZE, 8,    EGL_RED_SIZE, 8,    EGL_RENDERABLE_TYPE, //指定渲染api类别, 这里或者是硬编码的4    EGL_OPENGL_ES2_BIT,  //或者是EGL14.EGL_OPENGL_ES2_BIT     EGL_SURFACE_TYPE,     EGL_WINDOW_BIT,    EGL_NONE};int num_configs = 0;EGLConfig   eglConfig;//3、获取满足attributes的所有config, EGLConfig---描述EGLSurface配置信息的数据类型(绘制目标framebuffer的配置属性)eglChooseConfig(mEglDisplay, config_attribs, &eglConfig, 1, &num_configs)) //通过ANativeWindow 创建本地surface---EGLSurface,它是系统窗口或frame buffer句柄,可以理解为一个后端的渲染目标窗口// 4、将Surface转换为本地窗口EGLSurface mEglSurface = eglCreateWindowSurface(mEglDisplay, eglConfig, mWin, NULL); eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &mSurfaceWidth); // 5、查询高宽eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &mSurfaceHeight);EGLint context_attrib[] = {    EGL_CONTEXT_CLIENT_VERSION, 2,    EGL_NONE};//创建EGL环境, EGLContext: OpenGL ES图形上下文,它代表了OpenGL状态机EGLContext mEglContext = eglCreateContext(mEglDisplay, eglConfig, EGL_NO_CONTEXT, context_attrib); // 6、根据EGLConfig、context_attrib创建EGLContext//7、将EGLDisplay、EGLSurface和EGLContext进行绑定(渲染上下文绑定到渲染面,指定当前的环境为绘制环境 EGLContext->context)//eglMakeCurrent后生成的surface就可以利用opengl画图了eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext); render: //双缓冲刷新 front buffer 和 back buffer //eglSwapBuffers会去触发queuebuffer,dequeuebuffer, //queuebuffer将画好的buffer(back->front)交给surfaceflinger处理, //dequeuebuffer新创建一个buffer用来画图 eglSwapBuffers(mEglDisplay, mEglSurface);//release流程: eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); //1、 eglDestroyContext(mEglDisplay, mEglContext); // 2、 eglDestroySurface(mEglDisplay, mEglSurface); // 3、 eglTerminate(mEglDisplay); // 4、mEglDisplay = EGL_NO_DISPLAY; // 5、 mEglContext = EGL_NO_CONTEXT; mEglSurface = EGL_NO_SURFACE;

1、
ANativeWindow
EGL创建一个Window Surface函数原型列出如下:
EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
NativeWindowType window, const EGLint *attrib_list);

frameworks/base/opengl/include/egl/Eglplatform.h

#ifndef __eglplatform_h_#define __eglplatform_h_#include <KHR/khrplatform.h>#ifndef EGLAPI#define EGLAPI KHRONOS_APICALL#endif#ifndef EGLAPIENTRY#define EGLAPIENTRY  KHRONOS_APIENTRY#endif#define EGLAPIENTRYP EGLAPIENTRY*#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */#ifndef WIN32_LEAN_AND_MEAN#define WIN32_LEAN_AND_MEAN 1#endif#include <windows.h>typedef HDC     EGLNativeDisplayType;typedef HBITMAP EGLNativePixmapType;typedef HWND    EGLNativeWindowType;#elif defined(__WINSCW__) || defined(__SYMBIAN32__)  /* Symbian */typedef int   EGLNativeDisplayType;typedef void *EGLNativeWindowType;typedef void *EGLNativePixmapType;#elif defined(__ANDROID__) || defined(ANDROID) //针对android平台,关键定义项#include <android/native_window.h>struct egl_native_pixmap_t;typedef struct ANativeWindow*           EGLNativeWindowType;typedef struct egl_native_pixmap_t*     EGLNativePixmapType;typedef void*                           EGLNativeDisplayType;#elif defined(__unix__)/* X11 (tentative)  */#include <X11/Xlib.h>#include <X11/Xutil.h>typedef Display *EGLNativeDisplayType;typedef Pixmap   EGLNativePixmapType;typedef Window   EGLNativeWindowType;#else#error "Platform not recognized"#endif/* EGL 1.2 types, renamed for consistency in EGL 1.3 */typedef EGLNativeDisplayType NativeDisplayType;typedef EGLNativePixmapType  NativePixmapType;typedef EGLNativeWindowType  NativeWindowType;typedef khronos_int32_t EGLint;#endif /* __eglplatform_h */

ANativeWindow
system/core/include/system/Window.h

...typedef const native_handle_t* buffer_handle_t;typedef struct android_native_base_t{    /* a magic value defined by the actual EGL native type */    int magic;    /* the sizeof() of the actual EGL native type */    int version;    void* reserved[4];    /* reference-counting interface */    void (*incRef)(struct android_native_base_t* base);    void (*decRef)(struct android_native_base_t* base);} android_native_base_t;typedef struct ANativeWindowBuffer{#ifdef __cplusplus    ANativeWindowBuffer() {        common.magic = ANDROID_NATIVE_BUFFER_MAGIC;        common.version = sizeof(ANativeWindowBuffer);        memset(common.reserved, 0, sizeof(common.reserved));    }    // Implement the methods that sp<ANativeWindowBuffer> expects so that it    // can be used to automatically refcount ANativeWindowBuffer's.    void incStrong(const void* id) const {        common.incRef(const_cast<android_native_base_t*>(&common));    }    void decStrong(const void* id) const {        common.decRef(const_cast<android_native_base_t*>(&common));    }#endif    struct android_native_base_t common;    int width;    int height;    int stride;    int format;    int usage;    void* reserved[2];    buffer_handle_t handle;    void* reserved_proc[8];} ANativeWindowBuffer_t;// Old typedef for backwards compatibility.typedef ANativeWindowBuffer_t android_native_buffer_t;...struct ANativeWindow{#ifdef __cplusplus    ANativeWindow()        : flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0)    {        common.magic = ANDROID_NATIVE_WINDOW_MAGIC;        common.version = sizeof(ANativeWindow);        memset(common.reserved, 0, sizeof(common.reserved));    }    /* Implement the methods that sp<ANativeWindow> expects so that it       can be used to automatically refcount ANativeWindow's. */    void incStrong(const void* id) const {        common.incRef(const_cast<android_native_base_t*>(&common));    }    void decStrong(const void* id) const {        common.decRef(const_cast<android_native_base_t*>(&common));    }#endif    struct android_native_base_t common;    /* flags describing some attributes of this surface or its updater */    const uint32_t flags;    /* min swap interval supported by this updated */    const int   minSwapInterval;    /* max swap interval supported by this updated */    const int   maxSwapInterval;    /* horizontal and vertical resolution in DPI */    const float xdpi;    const float ydpi;    /* Some storage reserved for the OEM's driver. */    intptr_t    oem[4];    //设置交换间隔时间    int     (*setSwapInterval)(struct ANativeWindow* window,                int interval);    //EGL通过这个dequeueBuffer来申请一个buffer。本地窗口所提供的buffer分别来自于帧缓冲区和内存空间。    int     (*dequeueBuffer)(struct ANativeWindow* window,                struct ANativeWindowBuffer** buffer);    int     (*lockBuffer)(struct ANativeWindow* window,                struct ANativeWindowBuffer* buffer);    //当EGL对一块buffer渲染完成后,调用queueBuffer来unlock和post buffer    int     (*queueBuffer)(struct ANativeWindow* window,                struct ANativeWindowBuffer* buffer);    int     (*query)(const struct ANativeWindow* window,                int what, int* value);    /*     * hook used to perform various operations on the surface.     * (*perform)() is a generic mechanism to add functionality to     * ANativeWindow while keeping backward binary compatibility.     *     * DO NOT CALL THIS HOOK DIRECTLY.  Instead, use the helper functions     * defined below.     *     *  (*perform)() returns -ENOENT if the 'what' parameter is not supported     *  by the surface's implementation.     *     * The valid operations are:     *     NATIVE_WINDOW_SET_USAGE     *     NATIVE_WINDOW_CONNECT               (deprecated)     *     NATIVE_WINDOW_DISCONNECT            (deprecated)     *     NATIVE_WINDOW_SET_CROP     *     NATIVE_WINDOW_SET_BUFFER_COUNT     *     NATIVE_WINDOW_SET_BUFFERS_GEOMETRY  (deprecated)     *     NATIVE_WINDOW_SET_BUFFERS_TRANSFORM     *     NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP     *     NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS     *     NATIVE_WINDOW_SET_BUFFERS_FORMAT     *     NATIVE_WINDOW_SET_SCALING_MODE     *     NATIVE_WINDOW_LOCK                   (private)     *     NATIVE_WINDOW_UNLOCK_AND_POST        (private)     *     NATIVE_WINDOW_API_CONNECT            (private)     *     NATIVE_WINDOW_API_DISCONNECT         (private)     *     */    int     (*perform)(struct ANativeWindow* window,                int operation, ... );    int     (*cancelBuffer)(struct ANativeWindow* window,                struct ANativeWindowBuffer* buffer);    void* reserved_proc[2];};

native_handle_t代表一块内存块
system/core/include/cutils/native_handle.h

typedef struct native_handle{    int version;        /* sizeof(native_handle_t) */    int numFds;         /* number of file-descriptors at &data[0] */    int numInts;        /* number of ints at &data[numFds] */    int data[0];        /* numFds + numInts ints */} native_handle_t;

2、
FramebufferNativeWindow对应的是真实的物理屏幕
frameworks/base/include/ui/FramebufferNativeWindow.h

...#define NUM_FRAME_BUFFERS  2class FramebufferNativeWindow     : public EGLNativeBase<        ANativeWindow,         FramebufferNativeWindow,         LightRefBase<FramebufferNativeWindow> >{public:    FramebufferNativeWindow();     framebuffer_device_t const * getDevice() const { return fbDev; }     bool isUpdateOnDemand() const { return mUpdateOnDemand; }    status_t setUpdateRectangle(const Rect& updateRect);    status_t compositionComplete();    void dump(String8& result);    // for debugging only    int getCurrentBufferIndex() const;private:    friend class LightRefBase<FramebufferNativeWindow>;        ~FramebufferNativeWindow(); // this class cannot be overloaded    static int setSwapInterval(ANativeWindow* window, int interval);    static int dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer);    static int lockBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);    static int queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);    static int query(const ANativeWindow* window, int what, int* value);    static int perform(ANativeWindow* window, int operation, ...);    framebuffer_device_t* fbDev;    alloc_device_t* grDev;    sp<NativeBuffer> buffers[NUM_FRAME_BUFFERS];    sp<NativeBuffer> front;    mutable Mutex mutex;    Condition mCondition;    int32_t mNumBuffers; //FramebufferNativeWindow管理的buffer总数    int32_t mNumFreeBuffers; // 空闲的buffer数    int32_t mBufferHead;    int32_t mCurrentBufferIndex;    bool mUpdateOnDemand;#if defined(BOARD_USES_HDMI)    SecHdmiClient *mHdmiClient;#endif};

frameworks/base/libs/ui/FramebufferNativeWindow.cpp

...class NativeBuffer     : public EGLNativeBase<        ANativeWindowBuffer,         NativeBuffer,         LightRefBase<NativeBuffer> >{public:    NativeBuffer(int w, int h, int f, int u) : BASE() {        ANativeWindowBuffer::width  = w;        ANativeWindowBuffer::height = h;        ANativeWindowBuffer::format = f;        ANativeWindowBuffer::usage  = u;    }private:    friend class LightRefBase<NativeBuffer>;        ~NativeBuffer() { }; // this class cannot be overloaded};FramebufferNativeWindow::FramebufferNativeWindow()     : BASE(), fbDev(0), grDev(0), mUpdateOnDemand(false){    hw_module_t const* module;#if defined(BOARD_USES_HDMI)    mHdmiClient = android::SecHdmiClient::getInstance();#endif    //1\将指定的模块加载到内存来    if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {        int stride;        int err;        int i;        //2\打开Gralloc模块中的gralloc设备和fb设备        //Gralloc模块负责注册图形缓冲区,gralloc设备负责分配图形缓冲区,fb设备负责渲染图形缓冲区        //framebuffer_open()\gralloc_open()实际都调用gralloc.cpp中的gralloc_device_open()打开实际的设备        err = framebuffer_open(module, &fbDev); //打开framebuffer设备        LOGE_IF(err, "couldn't open framebuffer HAL (%s)", strerror(-err));        err = gralloc_open(module, &grDev); //grallo设备        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 = NUM_FRAME_BUFFERS;        mNumFreeBuffers = NUM_FRAME_BUFFERS;        mBufferHead = mNumBuffers-1;        for (i = 0; i < mNumBuffers; i++)        {        //向HAL层的Gralloc申请缓冲空间                buffers[i] = new NativeBuffer(                        fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB);        }        for (i = 0; i < mNumBuffers; i++)        {        //hardware/libhardware/include/hardware/Gralloc.h 函数原型:        // int (*alloc)(struct alloc_device_t* dev,        //    int w, int h, int format, int usage,        //    buffer_handle_t* handle, int* stride);        //通过 gralloc_device_open()函数的 dev->device.alloc   = gralloc_alloc;进行一步步函数调用实现分配图形缓冲区                   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));                if (err)                {                        mNumBuffers = i;                        mNumFreeBuffers = i;                        mBufferHead = mNumBuffers-1;                        break;                }        }        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");    }    //FramebufferNativeWindow将其setSwapInterval/dequeueBuffer等成员函数填充   到ANativeWindow中的函数指针中,OpenGL ES才能通过一个ANativeWindow来正确地与本地窗口建立真正的连接    ANativeWindow::setSwapInterval = setSwapInterval;    ANativeWindow::dequeueBuffer = dequeueBuffer;    ANativeWindow::lockBuffer = lockBuffer;    ANativeWindow::queueBuffer = queueBuffer;    ANativeWindow::query = query;    ANativeWindow::perform = perform;}

hardware/libhardware/include/hardware/FB.h

...static inline int framebuffer_open(const struct hw_module_t* module,        struct framebuffer_device_t** device) {    return module->methods->open(module,            GRALLOC_HARDWARE_FB0, (struct hw_device_t**)device);}

hardware/libhardware/include/hardware/Gralloc.h

...static inline int gralloc_open(const struct hw_module_t* module,         struct alloc_device_t** device) {    return module->methods->open(module,             GRALLOC_HARDWARE_GPU0, (struct hw_device_t**)device);}

3、

用户空间的应用程序在使用帧缓冲区之前,首先要加载Gralloc模块,并且获得一个gralloc设备和一个fb设备。
有了gralloc设备之后,用户空间中的应用程序就可以申请分配一块图形缓冲区,并且将这块图形缓冲区映射到应用程序的地址空间来,以便可以向里面写入要绘制的画面的内容。最后,用户空间中的应用程序就通过fb设备来将前面已经准备好了的图形缓冲区渲染到帧缓冲区中去,即将图形缓冲区的内容绘制到显示屏中去。
当用户空间中的应用程序不再需要使用一块图形缓冲区的时候,就可以通过gralloc设备来释放它,并且将它从地址空间中解除映射。

分配图形缓冲区: grDev->alloc()
gralloc_device_open() =>gralloc_alloc()
=>gralloc_alloc_framebuffer()=>gralloc_alloc_framebuffer_locked()
=>mapFrameBufferLocked()=>mapFrameBuffer()//帧缓冲区分配

gralloc_device_open() =>gralloc_alloc()=>gralloc_alloc_buffer()
=>ashmem_create_region()
//创建一块匿名共享内存,接着再在这块匿名共享内存上分配一个图形缓冲区
=>mapBuffer()
//把从匿名共享内存中分配的图形缓冲区映射到进程的地址空间,然后才可以使用,通过调用函数mapBuffer实现映射
=>gralloc_map(module, hnd, &vaddr);
//将参数hnd所描述的一个图形缓冲区映射到当前进程的地址空间

framebuffer设备渲染:fb_post()
framebuffer_open() => gralloc_device_open() => fb_device_open() => fb_post() 将图形缓冲区渲染到系统帧缓冲区中去,把画面绘制到设备显示屏中

hardware/libhardware/module/gralloc/gralloc.cpp

int gralloc_device_open(const hw_module_t* module, const char* name,        hw_device_t** device){    int status = -EINVAL;    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);    }    return status;}分配图形缓冲区//用户空间的应用程序用到的图形缓冲区是由Gralloc模块中的函数gralloc_alloc来分配static int gralloc_alloc(alloc_device_t* dev,        int w, int h, int format, int usage,        buffer_handle_t* pHandle, int* pStride){    if (!pHandle || !pStride)        return -EINVAL;    size_t size, stride;    int align = 4;    int bpp = 0;    switch (format) {        case HAL_PIXEL_FORMAT_RGBA_8888:        case HAL_PIXEL_FORMAT_RGBX_8888:        case HAL_PIXEL_FORMAT_BGRA_8888:            bpp = 4;            break;        case HAL_PIXEL_FORMAT_RGB_888:            bpp = 3;            break;        case HAL_PIXEL_FORMAT_RGB_565:        case HAL_PIXEL_FORMAT_RGBA_5551:        case HAL_PIXEL_FORMAT_RGBA_4444:            bpp = 2;            break;        default:            return -EINVAL;    }    size_t bpr = (w*bpp + (align-1)) & ~(align-1);    size = bpr * h;    stride = bpr / bpp;    int err;    //系统帧缓冲区中分配还是在内存中分配缓冲,内存中分配的图形缓冲区,最终是需要拷贝到系统帧缓冲区去的    if (usage & GRALLOC_USAGE_HW_FB) {        err = gralloc_alloc_framebuffer(dev, size, usage, pHandle);    } else {        err = gralloc_alloc_buffer(dev, size, usage, pHandle);    }    if (err < 0) {        return err;    }    *pStride = stride;    return 0;}//函数gralloc_alloc_framebuffer用来在系统帧缓冲区中分配图形缓冲区static int gralloc_alloc_framebuffer(alloc_device_t* dev,          size_t size, int usage, buffer_handle_t* pHandle)  {      private_module_t* m = reinterpret_cast<private_module_t*>(              dev->common.module);      pthread_mutex_lock(&m->lock);      //函数gralloc_alloc_framebuffer_locked才是真正用来分配图形缓冲区    int err = gralloc_alloc_framebuffer_locked(dev, size, usage, pHandle);      pthread_mutex_unlock(&m->lock);      return err;  } static int gralloc_alloc_framebuffer_locked(alloc_device_t* dev,          size_t size, int usage, buffer_handle_t* pHandle)  {      private_module_t* m = reinterpret_cast<private_module_t*>(              dev->common.module);      // allocate the framebuffer      if (m->framebuffer == NULL) {          // initialize the framebuffer, the framebuffer is mapped once          // and forever.          int err = mapFrameBufferLocked(m);          if (err < 0) {              return err;          }      }      const uint32_t bufferMask = m->bufferMask;      const uint32_t numBuffers = m->numBuffers;      const size_t bufferSize = m->finfo.line_length * m->info.yres;      if (numBuffers == 1) {          // If we have only one buffer, we never use page-flipping. Instead,          // we return a regular buffer which will be memcpy'ed to the main          // screen when post is called.          int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;          return gralloc_alloc_buffer(dev, bufferSize, newUsage, pHandle);      }      if (bufferMask >= ((1LU<<numBuffers)-1)) {          // We ran out of buffers.          return -ENOMEM;      }      // create a "fake" handles for it      intptr_t vaddr = intptr_t(m->framebuffer->base);      private_handle_t* hnd = new private_handle_t(dup(m->framebuffer->fd), size,              private_handle_t::PRIV_FLAGS_FRAMEBUFFER);      // find a free slot      for (uint32_t i=0 ; i<numBuffers ; i++) {          if ((bufferMask & (1LU<<i)) == 0) {              m->bufferMask |= (1LU<<i);              break;          }          vaddr += bufferSize;      }      hnd->base = vaddr;      hnd->offset = vaddr - intptr_t(m->framebuffer->base);      *pHandle = hnd;      return 0;  }//函数gralloc_alloc_buffer用来在内存在分配图形缓冲区static int gralloc_alloc_buffer(alloc_device_t* dev,        size_t size, int usage, buffer_handle_t* pHandle){    int err = 0;    int fd = -1;    size = roundUpToPageSize(size);    //创建一块匿名共享内存,接着再在这块匿名共享内存上分配一个图形缓冲区    fd = ashmem_create_region("gralloc-buffer", size);    if (fd < 0) {        LOGE("couldn't create ashmem (%s)", strerror(-errno));        err = -errno;    }    if (err == 0) {        private_handle_t* hnd = new private_handle_t(fd, size, 0);        gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>(                dev->common.module);        //把从匿名共享内存中分配的图形缓冲区映射到进程的地址空间,然后才可以使用,通过调用函数mapBuffer实现映射        err = mapBuffer(module, hnd);        if (err == 0) {            *pHandle = hnd;        }    }    LOGE_IF(err, "gralloc failed err=%s", strerror(-err));    return err;}

函数mapBuffer实现在文件hardware/libhardware/modules/gralloc/mapper.cpp

int mapBuffer(gralloc_module_t const* module,          private_handle_t* hnd)  {      void* vaddr;      return gralloc_map(module, hnd, &vaddr); //将参数hnd所描述的一个图形缓冲区映射到当前进程的地址空间  } 

hardware/libhardware/modules/gralloc/framebuffer.cpp

int fb_device_open(hw_module_t const* module, const char* name,        hw_device_t** device){    int status = -EINVAL;    if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {        alloc_device_t* gralloc_device;        status = gralloc_open(module, &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;        dev->device.setUpdateRect = 0;        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);            int format = (m->info.bits_per_pixel == 32)                         ? HAL_PIXEL_FORMAT_RGBX_8888                         : HAL_PIXEL_FORMAT_RGB_565;            const_cast<uint32_t&>(dev->device.flags) = 0;            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;            const_cast<int&>(dev->device.format) = format;            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;        }    }    return status;}//将图形缓冲区渲染到系统帧缓冲区中去,把画面绘制到设备显示屏中static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer){    if (private_handle_t::validate(buffer) < 0)        return -EINVAL;    fb_context_t* ctx = (fb_context_t*)dev;    private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(buffer);    private_module_t* m = reinterpret_cast<private_module_t*>(            dev->common.module);    if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {        const size_t offset = hnd->base - m->framebuffer->base;        m->info.activate = FB_ACTIVATE_VBL;        m->info.yoffset = offset / m->finfo.line_length;        if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1) {            LOGE("FBIOPUT_VSCREENINFO failed");            m->base.unlock(&m->base, buffer);             return -errno;        }        m->currentBuffer = buffer;    } else {        // If we can't do the page_flip, just copy the buffer to the front         // FIXME: use copybit HAL instead of memcpy        void* fb_vaddr;        void* buffer_vaddr;        m->base.lock(&m->base, m->framebuffer,                 GRALLOC_USAGE_SW_WRITE_RARELY,                 0, 0, m->info.xres, m->info.yres,                &fb_vaddr);        m->base.lock(&m->base, buffer,                 GRALLOC_USAGE_SW_READ_RARELY,                 0, 0, m->info.xres, m->info.yres,                &buffer_vaddr);        memcpy(fb_vaddr, buffer_vaddr, m->finfo.line_length * m->info.yres);        m->base.unlock(&m->base, buffer);         m->base.unlock(&m->base, m->framebuffer);     }    return 0;}