Android GDI显示缓冲管理

从最根源的硬件帧缓冲区开始。显示FrameBuffer在系统中就是一段内存,GDI 的工作就是把需要输出的内容放入到该段内存的某个位置。
1 基本知识
1.1 点的格式
对于不同的LCD 来讲,FrameBuffer的二进制格式不一样,并且可以分为两部分:
1)点的格式:通常将Depth,即多少位表示一个点。
1 位表示一个点
2 位表示一个点
16 位表示一个点
32 位表示一个点(Alpha 通道)
2)点内格式:RGB分量分布表示。

例如对于我们常见的16位表示一个点


1.2.格式之间的转换
所以屏幕输出实际上是一个值映射的关系。


源格式可能来自单色位图和彩色位图,对于具体的目标机来讲,我们的目标格式可能就是一种,例如16 位(5/6/5)格式。


在设计GDI 时,基本要求有一个可移植性好,所以我们还是必须考虑对于不同点格式LCD之间的转换操作。所以在GDI的驱动程序中涉及到如下几类主要操作:
区域操作(Blit):我们在显示缓冲区上做的最多的操作就是区块搬运。由此,很多的应用处理器使用了硬件图形加速器来完成区域搬运:blit.从我们的主要操作的对象来看,可以分为两个方向:
1)内存区域到屏幕区域
2)屏幕区域到屏幕区域
3)屏幕区域到内存区域
4)内存区域到内存区域
由于在Linux 不同进程之间的内存不能自由的访问,使得我们的每个Android应用对于内存区域和屏幕缓冲区的使用变得很复杂。在Android 的设计中,在屏幕缓冲区和内存缓冲区的管理分很多的层次,最上层的对象是可以在进程间自由传递,对于缓冲区内容则使用共享内存的机制。基于以上的基础知识,我们可以知道:
(1)代码中Config及其Format的意义。兼容性:采用同硬件相同的点的描述对象
(2)所有屏幕上图形的移动都是显示缓冲区搬运的结果。

1.2 图形加速器
应用处理器都可能带有图形加速器,对于不同的应用处理器对其图形加速器可能有不同的处理方式,对于2D加速来讲,都可归结为Blit。多为数据的搬运,放大缩小,旋转等。
2 Android的缓冲区抽象定义
不同的硬件有不同的硬件图形加速设备和缓冲内存实现方法。Android Gralloc动态库抽象的任务就是消除不同的设备之间的差别,在上层看来都是同样的方法和对象。在Module层隐藏缓冲区操作细节。Android使用了动态链接库gralloc.xxx.so,来完成底层细节的封装。
2.1 本地定义 @hardware\libhandware\modules\gralloc
每个动态链接库都用相同名称的调用接口:
1)硬件图形加速器的抽象:BlitEngine,CopyBit的加速操作。
2)硬件FrameBuffer内存管理
3)共享缓存管理
从数据关系上, 动态链接库的抽象行为: 在层次:
Hardware.c @hardware\libhardware 中对动态链接库中的内容作了全新的包装。
/system/lib/hw/gralloc.xxx.so 动态库文件。从文件Gralloc.h(handware\libhardware\include\hardware) 是抽象的结果: hw_get_module 从gralloc.xxx.so 提取了HAL_MODULE_INFO_SYM(SYM 变量)

从展露在外部的数据结构,我们在 @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,

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,

};
我们建立了什么对象来支撑缓冲区的操作?
buffer_handle_t:外部接口。
methods.open,registerBuffer,unregisterBuffer,lock,unlock
下面是外部接口和内部对象的结构关系,该类型的结构充分利用C Struct的数据排列特性:
基本结构体放置在最前面,本地私有放置在后面,满足了抽象的需要。
typedef const native_handle* buffer_handle_t;
private_module_t HAL_MODULE_INFO_SYM 向往暴露的动态链接库接口,通过该接口,我们直接可以使用该对象。

几个接口函数的解释:
(1)fb_post
对于帧缓冲区实际地址并不需要向上层报告,所有的操作都是通过fb_post完成。fp_post的任务就是将一个Buffer的内容传递到硬件缓冲区。其实现方式有两种:



(方式1)无需拷贝动作,是把Framebuffer的后buffer切为前buffer,然后通过IOCTRL 机
制告诉FB驱动切换DMA源地地址。这个实现方式的前提是Linux内核必须分配至少两个
缓冲区大小的物理内存和实现切换的ioctrol,这个实现快速切换。
(方式2)利用Copy 的方式。不修改内核,则在适配层利用从拷贝的方式进行,但是这个费时。
(2)gralloc的主要功能是要完成:
1)打开屏幕设备"/dev/fb0",,并映射硬件显示缓冲区。
2)提供分配共享显示缓存的接口
3)提供BiltEngine接口(完成硬件加速器的包装)
(3)gralloc_alloc 输出buffer_handle_t 句柄。
这个句柄是共享的基本依据,其基本原理在后面的章节有详细描述。
3 总结
总结一下,/system/lib/hw/gralloc.xxx.so 是跟硬件体系相关的一个动态链接库,也可以叫做Android的硬件抽象层。他实现了Android的硬件抽象接口标准,提供显示内存的分配机制和CopyBit等的加速实现。而如何具体实现这些功能,则跟硬件平台的配备有关系,所以我们看到了对于与不同的硬件架构,有不同的配置关系。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值