概述
Gralloc硬件抽象层:申请释放渲染图像缓冲,驱动屏幕的显示
- open函数,打开设备,通过name区分了不同的设备
int gralloc_device_open(const hw_module_t* module, const char* name,
hw_device_t** device){
if(name=="gpu0"){
device=new alloc_device_t();
}else if(name=="fb0"){
device=new framebuffer_device_t();
}
}
- 支持2中类型的设备
(1.) alloc_device_t 申请释放图像缓冲,保存了一堆函数指针,主要是
申请内存
alloc
释放内存
free
注意:
alloc指向gralloc_alloc函数 ,支持在fb和共享内存中申请graphicbuffer
if (usage & GRALLOC_USAGE_HW_FB) {
//用fb中映射的显存
err = gralloc_alloc_framebuffer(dev, size, usage, pHandle);
} else {
//创建共享内存
err = gralloc_alloc_buffer(dev, size, usage, pHandle);
}
(2.)framebuffer_device_t 渲染图像缓存,通过(/dev/fbx 驱动)显示到屏幕上 ,保存了一堆函数指针,主要是
丢一个buffer,等vsync信号来了再渲染出来,这很重要的函数,调用post把输入buffer刷新到屏幕上(调用了fb驱动),屏幕的显示都是直接或间接调用了post
post
设置刷新间隔
setswapinterval
加载fb成功后,通过mmap把fb映射到进程的地址空间中,首地址保存到framebuffer->base中, framebuffer->base就是显存了,
会根据屏幕大小分成几段, 加载fb驱动后就会把显存整个映射到进程的内存中。
- GraphicBuffer包装了底层的buffer
graphicbuffer的初始化依赖
GraphicBufferAllocator
//调用initsize后这个buffer就有效了
status_t
GraphicBuffer
::
initSize
(
uint32_t
w
,
uint32_t
h
,
PixelFormat
format
,
uint32_t
reqUsage
)
{
GraphicBufferAllocator
&
allocator
=
GraphicBufferAllocator
::
get
();
//
handle 保存的底层的句柄
status_t
err
=
allocator
.
alloc
(
w
,
h
,
format
,
reqUsage
, &
handle
, &
stride
);
if
(
err
==
NO_ERROR
) {
this
->
width
=
w
;
this
->
height
=
h
;
this
->
format
=
format
;
this
->
usage
=
reqUsage
;
}
return
err
;
}
继承关系
GraphicBuffer
:
public
ANativeObjectBase
<
ANativeWindowBuffer
,
GraphicBuffer
,
RefBase
>,
public
Flattenable
<
GraphicBuffer
>
Flattenable:序列化的接口,为了跨进程传递这个GraphicBuffer,这个不分析,就是吧一堆变量,句柄按格式从内存中读写
ANativeObjectBase
<
ANativeWindowBuffer
,
GraphicBuffer
,
RefBase
>:就是一个
ANativeWindowBuffer ,主要的就是保存了硬件抽象层中生成的句柄,handle是主要的东西
//获取buffer的一堆属性
uint32_t
getWidth
()
const
{
return
width
; }
uint32_t
getHeight
()
const
{
return
height
; }
uint32_t
getStride
()
const
{
return
stride
; }
uint32_t
getUsage
()
const
{
return
usage
; }
PixelFormat
getPixelFormat
()
const
{
return
format
; }
Rect
getBounds
()
const
{
return
Rect
(
width
,
height
); }
//lockbuffer返回可操作的内存地址,这就调用
GraphicBufferMapper的代码了
status_t
lock
(
uint32_t
usage
,
void
**
vaddr
);
status_t
unlock
();
- GraphicBufferAllocator: 单例 (通过硬件抽象层进行图像缓存的申请,释放)
GraphicBufferAllocator类初始化的时候加载硬件驱动层打开allocdev,以后就是通过allocdev进行图像缓存的申请释放
allocdev 通过
HAL_MODULE_INFO_SYM的common.open打开的
输入需要的buffer 宽度,高度,格式,用来干嘛(是否从fb中分配
),返回的
buffer_handle_t就是硬件驱动层生成的图像缓存句柄
status_t
alloc
(
uint32_t
w
,
uint32_t
h
,
PixelFormat
format
,
int
usage
,
buffer_handle_t
*
handle
,
int32_t
*
stride
);
1. a
lloc
(
uint32_t
w
,
uint32_t
h
,
PixelFormat
format
,
int
usage
,
buffer_handle_t
*
handle
,
int32_t
*
stride
);
2.mAllocDev
->
alloc
(
mAllocDev
,
w
,
h
,
format
,
usage
,
handle
,
stride
);
(alloc指向
gralloc_alloc 函数指针
)
gralloc_alloc
(
alloc_device_t
*
dev
,
int
w
,
int
h
,
int
format
,
int
usage
,
buffer_handle_t
*
pHandle
,
int
*
pStride
) //硬件抽象层的
3.
gralloc_alloc_framebuffer/
gralloc_alloc_buffer
//根据使用情况打开不同的buffer
gralloc_alloc(){
if
(
usage
&
GRALLOC_USAGE_HW_FB
) {
err
=
gralloc_alloc_framebuffer
(
dev
,
size
,
usage
,
pHandle
);
}
else
{
err
=
gralloc_alloc_buffer
(
dev
,
size
,
usage
,
pHandle
);
}
}
分配显存
gralloc_alloc_framebuffer
gralloc_alloc_framebuffer_locked
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
);
if
(
m
->
framebuffer
==
NULL
) {
// 第一次就进行fb的映射,以后就用这个了
mapFrameBufferLocked
(
m
);
}
if
(
numBuffers
== 1) {
// 如果显存只有1屏的大小则用共享内存吧
int
newUsage
= (
usage
& ~
GRALLOC_USAGE_HW_FB
) |
GRALLOC_USAGE_HW_2D
;
return
gralloc_alloc_buffer
(
dev
,
bufferSize
,
newUsage
,
pHandle
);
}
private_handle_t
*
hnd
=
new
private_handle_t
// 看一下显存的有没有空闲的后台缓存
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;
}
//打开fb驱动获取到显存的n多属性,初始化一下
int
mapFrameBufferLocked
(
struct
private_module_t
*
module
)
{
if
(
module
->
framebuffer
) {
return
0;
}
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); //这个怎么写死的0呢,其他屏幕怎么处理啊,还没明白,明白后再说了
fd
=
open
(
name
,
O_RDWR
, 0);
i
++;
}
....获取属性,初始化,然后映射到内存中
}
共享内存分配
static
int
gralloc_alloc_buffer
(
alloc_device_t
*
dev
,
size_t
size
,
int
usage
,
buffer_handle_t
*
pHandle
)
{
//对齐到页大小
size
=
roundUpToPageSize
(
size
);
//创建共享内存
fd
=
ashmem_create_region
(
"gralloc-buffer"
,
size
);
//映射内存,内部会mmap()
mapBuffer
(
module
,
hnd
);
}
释放图像缓存句柄
status_t
free
(
buffer_handle_t
handle
);
- GraphicBufferMapper: 单例 (申请完图像缓冲后,Mapper进行图像缓存的映射(map映射到不同的进程内存中),lock)
GraphicBufferMapper
类初始化的时候加载硬件驱动层打开
mAllocMod,这个是
gralloc_module_t,而GraphicBufferAllocator是通过allocMod打开了allocDev
//
buffer_handle_t是GraphicBuffer中的,GraphicBufferAllocator申请的,registerbuffer以后映射内存保存到hanle中
status_t
GraphicBufferMapper
::
registerBuffer
(
buffer_handle_t
handle
)
{
err
=
mAllocMod
->
registerBuffer
(
mAllocMod
,
handle
);
}
看一下调用流程:
硬件抽象层导出的标准接口定义
HAL_MODULE_INFO_SYM
= {
base
: {
common
: {
tag
:
HARDWARE_MODULE_TAG
,
....
},
registerBuffer
:
gralloc_register_buffer
,
unregisterBuffer
:
gralloc_unregister_buffer
,
lock
:
gralloc_lock
,
unlock
:
gralloc_unlock
,
}
1.mAllocMod
->
registerBuffer(
gralloc_module_t,
buffer_handle_t
)
2.
gralloc_register_buffer(
gralloc_module_t
const
*
module
,
buffer_handle_t
handle)//验证一下有效性,然后map
3.
gralloc_map
(
gralloc_module_t
const
*
module
,
buffer_handle_t
handle
,
void
**
vaddr
)
4.mmap()
gralloc_map(){
private_handle_t
*
hnd
= (
private_handle_t
*)
handle
;
if
(!(
hnd
->
flags
&
private_handle_t
::
PRIV_FLAGS_FRAMEBUFFER
)) {//如果不是famebuffer的则mmap,因为共享framebuffer开始打开的时候就已经映射过了
size_t
size
=
hnd
->
size
;
void
*
mappedAddress
=
mmap
(0,
size
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
hnd
->
fd
, 0);
hnd
->
base
=
intptr_t
(
mappedAddress
) +
hnd
->
offset
;
}
*
vaddr
= (
void
*)
hnd
->
base
;
}
//下面几个都差不多,都是调用硬件抽象层的函数
status_t
GraphicBufferMapper
::
unregisterBuffer
(
buffer_handle_t
handle
)
{
err
=
mAllocMod
->
unregisterBuffer
(
mAllocMod
,
handle
);
}
status_t
GraphicBufferMapper
::
lock
(
buffer_handle_t
handle
,
int
usage
,
const
Rect
&
bounds
,
void
**
vaddr
)
{
mAllocMod
->
lock
}
status_t
GraphicBufferMapper
::
unlock
(
buffer_handle_t
handle
)
{
mAllocMod
->un
lock
}
最后
以上就是自觉小伙为你收集整理的GraphicBuffer和Gralloc模块的全部内容,希望文章能够帮你解决GraphicBuffer和Gralloc模块所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复