Android研究_Gralloc_2几种重要的数据结构

时间:2022-06-17 15:11:46

4.3 重要的数据结构

根据HAL层加载库的规定,加载的时候,从HAL_MODULE_INFO_SYM模块地址开始。

Galloc模块的HAL_MODULE_INFO_SYM定义如下:

// HAL module initialize

struct private_module_t HAL_MODULE_INFO_SYM = {

    base: {

        common: {

            tag: HARDWARE_MODULE_TAG,

            module_api_version: GRALLOC_MODULE_API_VERSION_0_2,

            hal_api_version: 0,

            id: GRALLOC_HARDWARE_MODULE_ID,

            name: "Graphics Memory Allocator Module",

            author: "The Android Open Source Project",

            methods: &gralloc_module_methods,

            dso: 0,

        },

        registerBuffer: gralloc_register_buffer,

        unregisterBuffer: gralloc_unregister_buffer,

        lock: gralloc_lock,

        unlock: gralloc_unlock,

        perform: gralloc_perform,

        lock_ycbcr: gralloc_lock_ycbcr,

    },

    framebuffer: 0,

    fbFormat: 0,

    flags: 0,

    numBuffers: 0,

    bufferMask: 0,

    lock: PTHREAD_MUTEX_INITIALIZER,

    currentBuffer: 0,

};

可是每一个HAL模块必须具备HAL_MODULE_INFO_SYM结构体,而这个结构体必须以hw_module_t作为开头,现在Gralloc是不是存在特殊之处?

4.3.1 结构体private_module_t

结构体private_module_t定义在文件hardware/hardware/qcom/display/msm8974/libgralloc/fb_priv.h中,它主要是用来描述Gralloc模块的属性,包括通过alloc device申请到的FrameBuffer,使用private_handle_t来描述,以及alloc device和fb0 device等。

struct private_module_t {

gralloc_module_t base;

 

// 成员变量framebuffer的类型为private_handle_t,它是一个指向系统帧缓冲区的句柄

struct private_handle_t* framebuffer;

 

uint32_t fbFormat;

 

// flags用来标志系统帧缓冲区是否支持双缓冲。如果支持的话,那么它的PAGE_FLIP位就等于1,否则的话,就等于0

uint32_t flags;

 

// numBuffers表示系统帧缓冲区包含有多少个图形缓冲区。一个帧缓冲区包含有多少个图形缓冲区是与它的可视分辨率以及虚拟分辨率的大小有关的。例如,如果一个帧缓冲区的可视分辨率为800 x 600,而虚拟分辨率为1600 x 600,那么这个帧缓冲区就可以包含有两个图形缓冲区。

uint32_t numBuffers;

 

// 成员变量bufferMask用来记录系统帧缓冲区中的图形缓冲区的使用情况。例如,假设系统帧缓冲区有两个图形缓冲区,这时候成员变量bufferMask就有四种取值,分别是二进制的00011011,其中,00分别表示两个图缓冲区都是空闲的,01表示第1个图形缓冲区已经分配出去,而第2个图形缓冲区是空闲的,10表示第1个图形缓冲区是空闲的,而第2个图形缓冲区已经分配出去,11表示两个图缓冲区都已经分配出去。

uint32_t bufferMask;

 

// lock是一个互斥锁,用来保护结构体private_module_t的并行访问。

pthread_mutex_t lock;

 

// currentBuffer的类型为buffer_handle_t,用来描述当前正在被渲染的图形缓冲区,

private_handle_t *currentBuffer;

 

// 成员变量infofinfo的类型分别为fb_var_screeninfofb_fix_screeninfo,它们用来保存设备显示屏的属性信息,其中,成员变量var_info保存的属性信息是可以动态设置的,而成员变量fx_info保存的属性信息是只读的。这两个成员变量的值可以通过IO控制命令FBIOGET_VSCREENINFOFBIOGET_FSCREENINFO来从帧缓冲区驱动模块中获得。

    struct fb_var_screeninfo info;

    struct mdp_display_commit commit;

    struct fb_fix_screeninfo finfo;

 

//  成员变量xdpiydpi分别用来描述设备显示屏在宽度和高度上的密度,即每英寸有多少个像素点

    float xdpi;

    float ydpi;

 

// fps用来描述显示屏的刷新频率,它的单位的fps,即每秒帧数。

    float fps;

    uint32_t swapInterval;

    uint32_t currentOffset;

};

 

4.3.2 结构体gralloc_module_t

结构体gralloc_module_t定义在文件hardware/libhardware/include/hardware/gralloc.h中,继承了hw_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;

 

//  成员函数registerBufferunregisterBuffer分别用来注册和注销一个指定的图形缓冲区,这个指定的图形缓冲区使用一个buffer_handle_t句柄来描述。所谓注册图形缓冲区,实际上就是将一块图形缓冲区映射到一个进程的地址空间去,而注销图形缓冲区就是执行相反的操作。

    int (*registerBuffer)(struct gralloc_module_t const* module,

            buffer_handle_t handle);

    int (*unregisterBuffer)(struct gralloc_module_t const* module,

            buffer_handle_t handle);

      

// 成员函数lockunlock分别用来锁定和解锁一个指定的图形缓冲区,这个指定的图形缓冲区同样是使用一个buffer_handle_t句柄来描述。在访问一块图形缓冲区的时候,例如,向一块图形缓冲写入内容的时候,需要将该图形缓冲区锁定,用来避免访问冲突。在锁定一块图形缓冲区的时候,可以指定要锁定的图形绘冲区的位置以及大小,这是通过参数ltwh来指定的,其中,参数lt指定的是要访问的图形缓冲区的左上角位置,而参数wh指定的是要访问的图形缓冲区的宽度和长度。锁定之后,就可以获得由参数参数ltwh所圈定的一块缓冲区的起始地址,保存在输出参数vaddr中。另一方面,在访问完成一块图形缓冲区之后,需要解除这块图形缓冲区的锁定。

    int (*lock)(struct gralloc_module_t const* module,

            buffer_handle_t handle, int usage,

            int l, int t, int w, int h,

            void** vaddr);

    int (*unlock)(struct gralloc_module_t const* module,

            buffer_handle_t handle);

 

    int (*perform)(struct gralloc_module_t const* module,

            int operation, ... );

 

    int (*lock_ycbcr)(struct gralloc_module_t const* module,

            buffer_handle_t handle, int usage,

            int l, int t, int w, int h,

            struct android_ycbcr *ycbcr);

 

    int (*lockAsync)(struct gralloc_module_t const* module,

            buffer_handle_t handle, int usage,

            int l, int t, int w, int h,

            void** vaddr, int fenceFd);

    int (*unlockAsync)(struct gralloc_module_t const* module,

            buffer_handle_t handle, int* fenceFd);

 

    int (*lockAsync_ycbcr)(struct gralloc_module_t const* module,

            buffer_handle_t handle, int usage,

            int l, int t, int w, int h,

            struct android_ycbcr *ycbcr, int fenceFd);

 

    /* reserved for future use */

    void* reserved_proc[3];

} gralloc_module_t;

4.3.3 结构体hw_module_t

接下来来看下hw_module_t的结构体定义,这个其实是Android HAL层的标准定义,我们在HAL介绍的时候会重点关注:

/**

 * 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 hw_module_t {

    /** tag must be initialized to HARDWARE_MODULE_TAG */

    uint32_t tag;

    uint16_t module_api_version;

#define version_major module_api_version

    uint16_t hal_api_version;

#define version_minor hal_api_version

 

    const char *id;

 

    /** Name of this module */

    const char *name;

 

    /** Author/owner/implementor of the module */

    const char *author;

 

    /** Modules methods */

    struct hw_module_methods_t* methods;

 

    /** module's dso */

    void* dso;

 

#ifdef __LP64__

    uint64_t reserved[32-7];

#else

    /** padding to 128 bytes, reserved for future use */

    uint32_t reserved[32-7];

#endif

 

} hw_module_t;

 

hw_module_t结构体有一个重要的成员变量methods,它的类型为hw_module_methods_t,它用来描述一个HAL模块的操作方法列表。结构体hw_module_methods_t只定义有一个操作方法open,用来打开一个指定的设备。

typedef struct hw_module_methods_t {

    /** Open a specific device */

    int (*open)(const struct hw_module_t* module, const char* id,

            struct hw_device_t** device);

 

} hw_module_methods_t;

4.3.4结构体private_handle_t

我们还要看看一个重要的数据结构:private_handle_t,定义在hardware/hardware/qcom/display/msm8974/libgralloc/gralloc_priv.h中,用来描述一块图形缓冲区,这块图形缓冲区可能是在帧缓冲区中分配的,也可能是在内存中分配的,视具体情况而定。

#ifdef __cplusplus

struct private_handle_t : public native_handle {

#else

    struct private_handle_t {

        native_handle_t nativeHandle;

#endif

        enum {

            PRIV_FLAGS_FRAMEBUFFER        = 0x00000001,

            PRIV_FLAGS_USES_PMEM          = 0x00000002,

            PRIV_FLAGS_USES_PMEM_ADSP     = 0x00000004,

            PRIV_FLAGS_USES_ION           = 0x00000008,

            PRIV_FLAGS_USES_ASHMEM        = 0x00000010,

            PRIV_FLAGS_NEEDS_FLUSH        = 0x00000020,

            PRIV_FLAGS_DO_NOT_FLUSH       = 0x00000040,

            PRIV_FLAGS_SW_LOCK            = 0x00000080,

            PRIV_FLAGS_NONCONTIGUOUS_MEM  = 0x00000100,

            // Set by HWC when storing the handle

            PRIV_FLAGS_HWC_LOCK           = 0x00000200,

            PRIV_FLAGS_SECURE_BUFFER      = 0x00000400,

            // For explicit synchronization

            PRIV_FLAGS_UNSYNCHRONIZED     = 0x00000800,

            // Not mapped in userspace

            PRIV_FLAGS_NOT_MAPPED         = 0x00001000,

            // Display on external only

            PRIV_FLAGS_EXTERNAL_ONLY      = 0x00002000,

            // Display only this buffer on external

            PRIV_FLAGS_EXTERNAL_BLOCK     = 0x00004000,

            // Display this buffer on external as close caption

            PRIV_FLAGS_EXTERNAL_CC        = 0x00008000,

            PRIV_FLAGS_VIDEO_ENCODER      = 0x00010000,

            PRIV_FLAGS_CAMERA_WRITE       = 0x00020000,

            PRIV_FLAGS_CAMERA_READ        = 0x00040000,

            PRIV_FLAGS_HW_COMPOSER        = 0x00080000,

            PRIV_FLAGS_HW_TEXTURE         = 0x00100000,

            PRIV_FLAGS_ITU_R_601          = 0x00200000,

            PRIV_FLAGS_ITU_R_601_FR       = 0x00400000,

            PRIV_FLAGS_ITU_R_709          = 0x00800000,

            PRIV_FLAGS_L3_SECURE_BUFFER   = 0x01000000,

        };

// 成员变量fd指向一个文件描述符,这个文件描述符要么指向帧缓冲区设备,要么指向一块匿名共享内存,取决于它的宿主结构体private_handle_t描述的一个图形缓冲区是在帧缓冲区分配的,还是在内存中分配的。

        // file-descriptors

        int     fd;

        int     fd_metadata;          // fd for the meta-data

        // ints

 

//成员变量magic指向一个魔数,它的值由静态成员变量sMagic来指定,用来标识一个private_handle_t结构体。

        int     magic;

 

// 成员变量flags用来描述一个图形缓冲区的标志,它的值要么等于0,要么等于PRIV_FLAGS_FRAMEBUFFER。当一个图形缓冲区的标志值等于PRIV_FLAGS_FRAMEBUFFER的时候,就表示它是在帧缓冲区中分配的。

        int     flags;

 

//成员变量size用来描述一个图形缓冲区的大小。

        int     size;

 

//成员变量offset用来描述一个图形缓冲区的偏移地址。例如,当一个图形缓冲区是在一块内存中分块的时候,假设这块内存的地址为start,那么这个图形缓冲区的起始地址就为start + offset

        int     offset;

        int     bufferType;

 

//成员变量base用来描述一个图形缓冲区的实际地址,它是通过成员变量offset来计算得到的。例如,上面计算得到的start + offset的值就保存在成员变量base中。

        int     base;

        int     offset_metadata;

        // The gpu address mapped into the mmu.

        int     gpuaddr;

        int     format;

        int     width;

        int     height;

        int     base_metadata;

 

#ifdef __cplusplus

        static const int sNumInts = 12;

        static const int sNumFds = 2;

        static const int sMagic = 'gmsm';

 

        private_handle_t(int fd, int size, int flags, int bufferType,

                         int format,int width, int height, int eFd = -1,

                         int eOffset = 0, int eBase = 0) :

            fd(fd), fd_metadata(eFd), magic(sMagic),

            flags(flags), size(size), offset(0), bufferType(bufferType),

            base(0), offset_metadata(eOffset), gpuaddr(0),

            format(format), width(width), height(height),

            base_metadata(eBase)

        {

            version = sizeof(native_handle);

            numInts = sNumInts;

            numFds = sNumFds;

        }

        ~private_handle_t() {

            magic = 0;

        }

 

        bool usesPhysicallyContiguousMemory() {

            return (flags & PRIV_FLAGS_USES_PMEM) != 0;

        }

 

// 静态成员函数validate,用来验证一个native_handle_t指针是否指向了一个private_handle_t结构体

        static int validate(const native_handle* h) {

            const private_handle_t* hnd = (const private_handle_t*)h;

            if (!h || h->version != sizeof(native_handle) ||

                h->numInts != sNumInts || h->numFds != sNumFds ||

                hnd->magic != sMagic)

            {

                ALOGD("Invalid gralloc handle (at %p): "

                      "ver(%d/%d) ints(%d/%d) fds(%d/%d) magic(%c%c%c%c/%c%c%c%c)",

                      h,

                      h ? h->version : -1, sizeof(native_handle),

                      h ? h->numInts : -1, sNumInts,

                      h ? h->numFds : -1, sNumFds,

                      hnd ? (((hnd->magic >> 24) & 0xFF)?

                             ((hnd->magic >> 24) & 0xFF) : '-') : '?',

                      hnd ? (((hnd->magic >> 16) & 0xFF)?

                             ((hnd->magic >> 16) & 0xFF) : '-') : '?',

                      hnd ? (((hnd->magic >> 8) & 0xFF)?

                             ((hnd->magic >> 8) & 0xFF) : '-') : '?',

                      hnd ? (((hnd->magic >> 0) & 0xFF)?

                             ((hnd->magic >> 0) & 0xFF) : '-') : '?',

                      (sMagic >> 24) & 0xFF,

                      (sMagic >> 16) & 0xFF,

                      (sMagic >> 8) & 0xFF,

                      (sMagic >> 0) & 0xFF);

                return -EINVAL;

            }

            return 0;

        }

 

        static private_handle_t* dynamicCast(const native_handle* in) {

            if (validate(in) == 0) {

                return (private_handle_t*) in;

            }

            return NULL;

        }

#endif

    };

结构体native_handle_t用来描述一个本地句柄值,它定义在系统运行时层的文件system/core/include/cutils/native_handle.h文件中。

typedef struct native_handle

{

// version的大小被设置为结构体native_handle_t的大小,用来标识结构体native_handle_t的版本。

int version;        /* sizeof(native_handle_t) */

 

// 成员变量numFdsnumInts表示结构体native_handle_t所包含的文件描述符以及整数值的个数,这些文件描述符和整数保存在成员变量data所指向的一块缓冲区中

    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;

4.3.5 结构体alloc_device_t

Gralloc设备通过alloc_device_t结构体来描述,定义在文件hardware/libhardware/include/hardware/gralloc.h中,alloc设备是提供对于F0设备的操作接口。

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 8 pixels).

     * The CALLER TAKES OWNERSHIP of the buffer_handle_t.

     *

     * If format is HAL_PIXEL_FORMAT_YCbCr_420_888, the returned stride must be

     * 0, since the actual strides are available from the android_ycbcr

     * structure.

     *

     * 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);

 

    /* This hook is OPTIONAL.

     *

     * If non NULL it will be caused by SurfaceFlingeron dumpsys

     */

    void (*dump)(struct alloc_device_t *dev, char *buff, int buff_len);

 

    void* reserved_proc[7];

} alloc_device_t;

4.3.7 结构体fb_var_screeninfo

struct fb_var_screeninfo {
__u32 xres; /* visible resolution横像素 */
__u32 yres;   //竖像素

 

// 虚拟分辨率的像素,如果将虚拟分辨率的高度值设置成可视分辨率的NUM_BUFFER倍,比如说2倍的,就硬件就可以实现双buffer,即双缓冲技术。也可以用来实现画面平滑滑动的效果。
__u32 xres_virtual; /* virtual resolution */
__u32 yres_virtual;

 

// 表示可视区域左上角对应虚拟内存的xy
__u32 xoffset; /* offset from virtual to visible */
__u32 yoffset; /* resolution */

 

__u32 bits_per_pixel; /* guess what代表颜色深度 */

__u32 grayscale; /* != 0 Graylevels instead of colors  */

 

// fb_bitfield结构体描述每一像素显示缓冲区的组织方式,包含位域长度和MSB指示。

struct fb_bitfield red; /* bitfield in fb mem if true color, */
struct fb_bitfield green; /*else only length is significant */
struct fb_bitfield blue;
struct fb_bitfield transp; /*transparency */

 

__u32 nonstd; /* != 0 Non standard pixel format */

__u32 activate; /* see FB_ACTIVATE_* */

 

__u32 height; /* height of picture in mm???*/
__u32 width; /* width of picture in mm????*/

__u32 accel_flags; /* acceleration flags (hints) */

 

/* Timing: All values in pixclocks, except pixclock (of course) */

__u32 pixclock; /* pixel clock in ps (pico seconds) */

__u32 left_margin; /* time from sync to picture */
__u32 right_margin; /* time from picture to sync */
__u32 upper_margin; /* time from sync to picture */
__u32 lower_margin;


__u32 hsync_len; /* length of horizontal sync */
__u32 vsync_len; /* length of vertical sync */

__u32 sync; /* see FB_SYNC_* */

__u32 vmode; /* see FB_VMODE_* */

__u32 reserved[6]; /* Reserved for future compatibility
*/

};

 

Android研究_Gralloc_2几种重要的数据结构

中间由xres和yres组成的区域即为显示屏的图形绘制区,在绘制区的上、下、左和右分别有四个边距upper_margin、lower_margin、left_margin和right_margin。此外,在显示屏的最右边以及最下边还有一个水平同步区域hsync_len和一个垂直同步区域vsync_len。电子枪按照从左到右、从上到下的顺序来显示屏中打点,从而可以将要渲染的图形显示在屏幕中。前面所提到的区域信息分别保存在fb_var_screnninfo结构体info的成员变量xres、yres、upper_margin、lower_margin、left_margin、right_margin、hsync_len和vsync_len。

电子枪每在xres和yres所组成的区域中打一个点所花费的时间记录在fb_var_screnninfo结构体info的成员变量pixclock,单位为pico seconds,即10E-12秒。

电子枪从左到右扫描完成一行之后,都会处理关闭状态,并且会重新折回到左边去。由于电子枪在从右到左折回的过程中不需要打点,因此,这个过程会比从左到右扫描屏幕的过程要快,这个折回的时间大概就等于在xres和yres所组成的区域扫描(left_margin+right_margin)个点的时间。这样,我们就可以认为每渲染一行需要的时间为(xres +left_margin + right_margin)* pixclock。

同样,电子枪从上到下扫描完成显示屏之后,需要从右下角折回到左上角去,折回的时间大概等于在xres和yres所组成的区域中扫描(upper_margin +lower_margin)行所需要的时间。这样,我们就可以认为每渲染一屏图形所需要的时间等于在xres和yres所组成的区域中扫描(yres + upper_margin +lower_margin)行所需要的时间。由于在xres和yres所组成的区域中扫描一行所需要的时间为(xres + left_margin + right_margin)* pixclock,因此,每渲染一屏图形所需要的总时间就等于(yres + upper_margin + lower_margin)* (xres +left_margin + right_margin)* pixclock。

每渲染一屏图形需要的总时间经过计算之后,就保存在变量refreshQuotient中。注意,变量refreshQuotient所描述的时间的单位为1E-12秒。这样,将变量refreshQuotient的值倒过来,就可以得到设备显示屏的刷新频率。将这个频率值乘以10E15次方之后,就得到一个单位为10E-3 HZ的刷新频率,保存在变量refreshRate中。

当Android系统在模拟器运行的时候,保存在fb_var_screnninfo结构体info的成员变量pixclock中的值可能等于0。在这种情况下,前面计算得到的变量refreshRate的值就会等于0。在这种情况下,接下来的代码会将变量refreshRate的值设置为60 * 1000 * 10E-3 HZ,即将显示屏的刷新频率设置为60HZ。

4.3.6结构体fb_context_t

Fb0设备通过fb_context_t结构体来描述,定义在文件hardware/libhardware/qcom/display/msm8974/libgralloc/framebuffer.cpp中。但是fb_context_t本质上就是对应framebuffer_device_t结构体的再次封装。Framebuffer_device_t定义在hardware/libhardware/include/hardware/fb.h

typedef struct framebuffer_device_t {

    /**

     * Common methods of the framebuffer device.  This *must* be the first member of

     * framebuffer_device_t as users of this structure will cast a hw_device_t to

     * framebuffer_device_t pointer in contexts where it's known the hw_device_t references a

     * 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 */

// 一行占据的点数,与宽度的差别就在于前者对齐到4字节边界,后者是调用者传进来的,不一定是对齐到4字节边界的。

    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;

 

    /* Number of framebuffers supported*/

    const int       numFramebuffers;

 

    int reserved[7];

 

    /*

     * 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);

 

 

    /*

     * The (*compositionComplete)() method must be called after the

     * compositor has finished issuing GL commands for client buffers.

     */

 

    int (*compositionComplete)(struct framebuffer_device_t* dev);

 

    /*

     * This hook is OPTIONAL.

     *

     * If non NULL it will be caused by SurfaceFlingeron dumpsys

     */

    void (*dump)(struct framebuffer_device_t* dev, char *buff, int buff_len);

 

    /*

     * (*enableScreen)() is used to either blank (enable=0) or

     * unblank (enable=1) the screen this framebuffer is attached to.

     *

     * Returns 0 on success or -errno on error.

     */

    int (*enableScreen)(struct framebuffer_device_t* dev, int enable);

 

    void* reserved_proc[6];

 

} framebuffer_device_t;

4.3.7 几个结构体之间的关系

我们用一个图来清楚描述下这些结构体的关系:

Android研究_Gralloc_2几种重要的数据结构

结构体private_module_t的第一个成员变量base指向一个gralloc_module_t结构体,而gralloc_module_t结构体的第一个成员变量common又指向了一个hw_module_t结构体,这意味着,指向一个private_module_t结构体的指针同时可以用作一个gralloc_module_t或者hw_module_t结构体提针来使用。事实上,这是使用C语言来实现的一种继承关系,等价于结构体private_module_t继承结构体gralloc_module_t,而结构体gralloc_module_t继承hw_module_t结构体。

这样,我们就可以把在Gralloc模块中定义的符号HAL_MODULE_INFO_SYM看作是一个hw_module_t结构体。从而解答了本节开头中提到的疑问。

几个重要概念及其数据结构之间的对应关系。

l  Fb_device: fb_context_t & framebuffer_device_t

l  Alloce_device: alloc_device_t

l  Gralloc_module: private_module_t & gralloc_module_t

l  Framebuffer: private_handle_t

Android研究_Gralloc_2几种重要的数据结构

版权所有,转载请注明出处:http://www.junsion.icoc.bz/ by 小丑