Gralloc 模块

1. 在Android Eclair 及其之后的版本中,显示系统增加了一个名为Gralloc的硬件模块。
Gralloc的含义为, Graphics Alloc(图形分配),这个模块位于libui和显示设备的驱动程序之间。
Gralloc模块被放在/system/lib/hw/下,下面是omap3的一个gralloc:

    $ ls system/lib/hw -l
    总用量 144
    -rwxrwxr-x 1 xxha xxha 18204 2012-03-14 15:57 alsa.adlink.so
    -rwxrwxr-x 1 xxha xxha 9840 2012-03-13 15:56 gps.goldfish.so
    -rwxrwxr-x 1 xxha xxha 5596 2012-03-13 15:56 gps.omap4.so
    -rwxrwxr-x 1 xxha xxha 10112 2012-03-13 15:56 gralloc.default.so
    lrwxrwxrwx 1 xxha xxha 28 2012-03-19 11:11 gralloc.omap3.so -> gralloc.omap3.so.1.1.17.4403
    -rw-rw-r-- 1 xxha xxha 14380 2012-03-19 11:11 gralloc.omap3.so.1.1.17.4403
    -rwxrwxr-x 1 xxha xxha 9756 2012-03-13 15:56 lights.omap3.so
    -rwxrwxr-x 1 xxha xxha 34860 2012-03-13 15:56 overlay.omap3.so
    -rwxrwxr-x 1 xxha xxha 14416 2012-03-13 15:56 sensors.adlink.so
    -rwxrwxr-x 1 xxha xxha 10044 2012-03-13 15:56 sensors.goldfish.so

2. gralloc相当与显示系统的硬件抽象层,以硬件模块的形式存在,这时一个Android标准的硬件模块。
其头文件位于:hardware/libhardware/include/hardware/gralloc.h

a. Gralloc.h 首先定义模块和自设备的名称:
    /**
     * The id of this module
     */
    #define GRALLOC_HARDWARE_MODULE_ID "gralloc"    //这个硬件模块的名称
    /**
     * Name of the graphics device to open
     */
    #define GRALLOC_HARDWARE_FB0 "fb0"
    #ifdef OMAP_ENHANCEMENT
    #define GRALLOC_HARDWARE_FB1 "fb1"
    #endif
    #define GRALLOC_HARDWARE_GPU0 "gpu0"

b. gralloc_module_t 是模块的核心:
    /**
     * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM
     * and the fields of this data structure must begin with hw_module_t
     * followed by module specific information.
     */
    typedef struct gralloc_module_t {
        struct hw_module_t common;
        /*
         * (*registerBuffer)() must be called before a buffer_handle_t that has not
         * been created with (*alloc_device_t::alloc)() can be used.
         *
         * This is intended to be used with buffer_handle_t's that have been
         * received in this process through IPC.
         *
         * This function checks that the handle is indeed a valid one and prepares
         * it for use with (*lock)() and (*unlock)().
         *
         * It is not necessary to call (*registerBuffer)() on a handle created
         * with (*alloc_device_t::alloc)().
         *
         * returns an error if this buffer_handle_t is not valid.
         */
        int (*registerBuffer)(struct gralloc_module_t const* module,
                buffer_handle_t handle);
        /*
         * (*unregisterBuffer)() is called once this handle is no longer needed in
         * this process. After this call, it is an error to call (*lock)(),
         * (*unlock)(), or (*registerBuffer)().
         *
         * This function doesn't close or free the handle itself; this is done
         * by other means, usually through libcutils's native_handle_close() and
         * native_handle_free().
         *
         * It is an error to call (*unregisterBuffer)() on a buffer that wasn't
         * explicitly registered first.
        */
        int (*unregisterBuffer)(struct gralloc_module_t const* module,
                buffer_handle_t handle);
        /*
         * The (*lock)() method is called before a buffer is accessed for the
         * specified usage. This call may block, for instance if the h/w needs
         * to finish rendering or if CPU caches need to be synchronized.
         *
         * The caller promises to modify only pixels in the area specified
         * by (l,t,w,h).
         *
         * The content of the buffer outside of the specified area is NOT modified
         * by this call.
         *
         * If usage specifies GRALLOC_USAGE_SW_*, vaddr is filled with the address
         * of the buffer in virtual memory.
         *
         * THREADING CONSIDERATIONS:
         *
         * It is legal for several different threads to lock a buffer from
         * read access, none of the threads are blocked.
         *
         * However, locking a buffer simultaneously for write or read/write is
         * undefined, but:
         * - shall not result in termination of the process
         * - shall not block the caller
         * It is acceptable to return an error or to leave the buffer's content
         * into an indeterminate state.
         *
         * If the buffer was created with a usage mask incompatible with the
         * requested usage flags here, -EINVAL is returned.
         *
         */
        int (*lock)(struct gralloc_module_t const* module,
                buffer_handle_t handle, int usage,
                int l, int t, int w, int h,
                void** vaddr);
        /*
         * The (*unlock)() method must be called after all changes to the buffer
         * are completed.
         */
        int (*unlock)(struct gralloc_module_t const* module,
                buffer_handle_t handle);
        /* reserved for future use */
        int (*perform)(struct gralloc_module_t const* module,
                int operation, ... );
        /* reserved for future use */
        void* reserved_proc[7];
    } gralloc_module_t;

c. gralloc 和 framebuffer 两种设备的打开和关闭接口如下:open/close
    /** convenience API for opening and closing a supported device */
    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);
    }
    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,
            struct framebuffer_device_t** device) {
        return module->methods->open(module,
                GRALLOC_HARDWARE_FB0, (struct hw_device_t**)device);
    }
    #ifdef OMAP_ENHANCEMENT
    static inline int framebuffer_open_by_name(const struct hw_module_t* module,
            struct framebuffer_device_t** device, const char *fb_name) {
        return module->methods->open(module,
                fb_name, (struct hw_device_t**)device);
    }
    #endif
    static inline int framebuffer_close(struct framebuffer_device_t* device) {
        return device->common.close(&device->common);
    }
这4个函数是Gralloc模块特定的API。

d. GRALLOC_HARDWARE_GPU0对应的设备为alloc_device_t:
    /**
     * Every device data structure must begin with hw_device_t
     * followed by module specific public methods and attributes.
     */
    typedef struct alloc_device_t {
        struct hw_device_t common;
        /*
         * (*alloc)() Allocates a buffer in graphic memory with the requested
         * parameters and returns a buffer_handle_t and the stride in pixels to
         * allow the implementation to satisfy hardware constraints on the width
         * of a pixmap (eg: it may have to be multiple of 9 pixels).
         * The CALLER TAKES OWNERSHIP of the buffer_handle_t.
         *
         * Returns 0 on success or -errno on error.
         */
        int (*alloc)(struct alloc_device_t* dev,        //用于分配一个显示内存。
                int w, int h, int format, int usage,
                buffer_handle_t* handle, int* stride);
        /*
         * (*free)() Frees a previously allocated buffer.
         * Behavior is undefined if the buffer is still mapped in any process,
         * but shall not result in termination of the program or security breaches
         * (allowing a process to get access to another process' buffers).
         * THIS FUNCTION TAKES OWNERSHIP of the buffer_handle_t which becomes
         * invalid after the call.
         *
         * Returns 0 on success or -errno on error.
         */
        int (*free)(struct alloc_device_t* dev,
                buffer_handle_t handle);
    } alloc_device_t;

e. GRALLOC_HARDWARE_FB0对应的设备为framebuffer_device_t:
    typedef struct framebuffer_device_t {
        struct hw_device_t common;
        /* flags describing some attributes of the framebuffer */
        const uint32_t flags;
        /* dimensions of the framebuffer in pixels */
        const uint32_t width;
        const uint32_t height;
        /* frambuffer stride in pixels */
        const int stride;
        /* framebuffer pixel format */
        const int format;
        /* resolution of the framebuffer's display panel in pixel per inch*/
        const float xdpi;
        const float ydpi;
        /* framebuffer's display panel refresh rate in frames per second */
        const float fps;
        /* min swap interval supported by this framebuffer */
        const int minSwapInterval;
        /* max swap interval supported by this framebuffer */
        const int maxSwapInterval;
        int reserved[8];
        /*
        * requests a specific swap-interval (same definition than EGL)
         *
         * Returns 0 on success or -errno on error.
         */
        int (*setSwapInterval)(struct framebuffer_device_t* window,     //用于交换显示区域
                int interval);
        /*
         * This hook is OPTIONAL.
         *
         * It is non NULL If the framebuffer driver supports "update-on-demand"
         * and the given rectangle is the area of the screen that gets
         * updated during (*post)().
         *
         * This is useful on devices that are able to DMA only a portion of
         * the screen to the display panel, upon demand -- as opposed to
         * constantly refreshing the panel 60 times per second, for instance.
         *
         * Only the area defined by this rectangle is guaranteed to be valid, that
         * is, the driver is not allowed to post anything outside of this
         * rectangle.
         *
         * The rectangle evaluated during (*post)() and specifies which area
         * of the buffer passed in (*post)() shall to be posted.
         *
         * return -EINVAL if width or height <=0, or if left or top < 0
         */
        int (*setUpdateRect)(struct framebuffer_device_t* window,     //用于更新指定区域
                int left, int top, int width, int height);
        /*
         * Post <buffer> to the display (display it on the screen)
         * The buffer must have been allocated with the
         * GRALLOC_USAGE_HW_FB usage flag.
         * buffer must be the same width and height as the display and must NOT
         * be locked.
         *
         * The buffer is shown during the next VSYNC.
         *
         * If the same buffer is posted again (possibly after some other buffer),
         * post() will block until the the first post is completed.
         *
         * Internally, post() is expected to lock the buffer so that a
         * subsequent call to gralloc_module_t::(*lock)() with USAGE_RENDER or
         * USAGE_*_WRITE will block until it is safe; that is typically once this
         * buffer is shown and another buffer has been posted.
         *
         * Returns 0 on success or -errno on error.
         */
        int (*post)(struct framebuffer_device_t* dev, buffer_handle_t buffer);   //用于发送某个Buffer到屏幕上
        /*
         * The (*compositionComplete)() method must be called after the
         * compositor has finished issuing GL commands for client buffers.
         */
        int (*compositionComplete)(struct framebuffer_device_t* dev);
        void* reserved_proc[8];
    } framebuffer_device_t;

3. 在上层,libui库中的FramebufferNativeWindow.cpp 是Gralloc的主要调用者。
Gralloc 与上层的关系,见下篇。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值