Gralloc模块总结

Android系统在硬件抽象层提供了一个Grallo模块,封装了对帧缓冲区的所有操作。应用程序可以通过Gralloc模块申请图形缓冲区,像里写入要绘制的图画内容。

代码介绍

涉及文件
1,hardware\libhardware\include\hardware\gralloc.h
2,hardware\libhardware\include\hardware\fb.h
3,hardware\libhardware\modules\gralloc\gralloc_priv.h
4,hardware\libhardware\modules\gralloc\gralloc.cpp
5,hardware\libhardware\modules\gralloc\framebuffer.cpp

hardware\libhardware\include\hardware\gralloc.h
定义gralloc_module_talloc_device_t

//1.定义gralloc_module_t 
typedef struct gralloc_module_t {
    struct hw_module_t common;
    ....
}
//2.定义alloc_device_t
typedef struct alloc_device_t {
    struct hw_device_t common;

    int (*alloc)(struct alloc_device_t* dev,
            int w, int h, int format, int usage,
            buffer_handle_t* handle, int* stride);

    int (*free)(struct alloc_device_t* dev,
            buffer_handle_t handle);

    /* This hook is OPTIONAL.
     *
     * If non NULL it will be caused by SurfaceFlinger on dumpsys
     */
    void (*dump)(struct alloc_device_t *dev, char *buff, int buff_len);

    void* reserved_proc[7];
} alloc_device_t;

//3.定义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, TO_HW_DEVICE_T_OPEN(device));
}

static inline int gralloc_close(struct alloc_device_t* device) {
    return device->common.close(&device->common);
}

hardware\libhardware\include\hardware\fb.h
定义 framebuffer_device_t

//1.定义framebuffer_device_t 
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 */
    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);

    int (*setUpdateRect)(struct framebuffer_device_t* window,
            int left, int top, int width, int height);
            
    int (*post)(struct framebuffer_device_t* dev, buffer_handle_t buffer);

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

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

    void* reserved_proc[6];

} framebuffer_device_t;

//2.定义open和close函数
/** convenience API for opening and closing a supported device */
static inline int framebuffer_open(const struct hw_module_t* module,
        struct framebuffer_device_t** device) {
    return module->methods->open(module,
            GRALLOC_HARDWARE_FB0, TO_HW_DEVICE_T_OPEN(device));
}

static inline int framebuffer_close(struct framebuffer_device_t* device) {
    return device->common.close(&device->common);
}

hardware\libhardware\modules\gralloc\gralloc_priv.h

struct private_module_t {
    gralloc_module_t base;

    private_handle_t* framebuffer;
    uint32_t flags;
    uint32_t numBuffers;
    uint32_t bufferMask;
    pthread_mutex_t lock;
    buffer_handle_t currentBuffer;
    int pmem_master;
    void* pmem_master_base;

    struct fb_var_screeninfo info;
    struct fb_fix_screeninfo finfo;
    float xdpi;
    float ydpi;
    float fps;
};

/*****************************************************************************/

#ifdef __cplusplus
struct private_handle_t : public native_handle {
#else
struct private_handle_t {
    struct native_handle nativeHandle;
#endif

    enum {
        PRIV_FLAGS_FRAMEBUFFER = 0x00000001
    };

    // file-descriptors
    int     fd;
    // ints
    int     magic;
    int     flags;
    int     size;
    int     offset;

    // FIXME: the attributes below should be out-of-line
    uint64_t base __attribute__((aligned(8)));
    int     pid;

#ifdef __cplusplus
    static inline int sNumInts() {
        return (((sizeof(private_handle_t) - sizeof(native_handle_t))/sizeof(int)) - sNumFds);
    }
    static const int sNumFds = 1;
    static const int sMagic = 0x3141592;

    private_handle_t(int fd, int size, int flags) :
        fd(fd), magic(sMagic), flags(flags), size(size), offset(0),
        base(0), pid(getpid())
    {
        version = sizeof(native_handle);
        numInts = sNumInts();
        numFds = sNumFds;
    }
    ~private_handle_t() {
        magic = 0;
    }

    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)
        {
            ALOGE("invalid gralloc handle (at %p)", h);
            return -EINVAL;
        }
        return 0;
    }
#endif
};

我们看到Gralloc模块的private_module_t中包含gralloc_module_t,gralloc_module_t中又包含hw_module_t。这是各个HAL模块实现的模板,各HAL模式继承自hw_module_t并添加与自身模块相关的内容。

来看下Gralloc模块的实现代码
hardware\libhardware\modules\gralloc\gralloc.cpp

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_ID,
            .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,
};
//open设备
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;
}

重点来看下fb_device_open函数
hardware\libhardware\modules\gralloc\framebuffer.cpp中实现
注:dev->device是framebuffer_device_t
fb_device_open主要做了
1,framebuffer_device_t 的初始化,注册操作fb设备的函数
2,mapFrameBuffer,将fb映射到当前进程的地址空间

struct fb_context_t {
    framebuffer_device_t  device;
};
i
nt fb_device_open(hw_module_t const* module, const char* name,
        hw_device_t** device)
{
    int status = -EINVAL;
    if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {
        /* 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)
                         ? (m->info.red.offset ? HAL_PIXEL_FORMAT_BGRA_8888 : 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;
        } else {
            free(dev);
        }
    }
    return status;
}

mapFrameBuffer,该函数源码较长,我们截取关键内容显示

//1,打开设备
char const * const device_template[] = {
            "/dev/graphics/fb%u",
            "/dev/fb%u",
            0 };

int fd = -1;
int i=0;
char name[64];

while ((fd==-1) && device_template[i]) {
    snprintf(name, 64, device_template[i], 0);
    fd = open(name, O_RDWR, 0);
    i++;
}

//2,从设备中获取信息,并将获取到的信息设置给Gralloc模块变量private_module_t
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;

//3,将帧缓冲区映射到当前进程地址空间中
void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
module->framebuffer->base = intptr_t(vaddr);

至此,fb设备打开完成:打开fb设备,根据fb设备初始化相关的显示信息,并把fb设备显存映射到当前进程方便访问,同时还注册了几个操作fb设备的方法。

回到gralloc.cpp的gralloc_device_open函数中,fremebuffer_device_t的打开流程我们已经追踪过了,还有GRALLOC_HARDWARE_GPU0即alloc_device_t的打开。
alloc_device_t的打开相对来说简单一点,主要是对其进行初始化 ,同时注册了几个操作alloc_device_t设备的函数, gralloc_alloc和gralloc_free用于分配和释放图形缓冲区。

总结

上层应用使用帧缓冲区的流程如下:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值