关于Android下gralloc,hwcompoer以及surface模块的重新认识
引言
欠债还钱天经地义,知识的债也是如此!这不必须得将我前面欠下来的债给补上!对于任何复杂的知识点,我们都可以采用庖丁解牛的学习方式,一步步的分解。将知识由大到小吃透。虽说Android的graphics图形栈是一个非常负责的模块,但是完事开头难,我们先从基本面入手!
一. allocator service的实现
这里我只能无力的吐糟下Android为了所谓的system,vendor隔离,搞了一个HIDL,这可苦了我们这些搞Android的。这里我以最简单的alloctaor 2.0来作为参考,简单介绍其实现!
1.1 . allocator 2.0 service代码结构
这个比较简单,我们直接上代码!
//hardware/interfaces/graphics/allocator/2.0
├── Android.bp
├── default
│ ├── Android.bp
│ ├── android.hardware.graphics.allocator@2.0-service.rc
│ ├── OWNERS
│ ├── passthrough.cpp
│ └── service.cpp
├── IAllocator.hal
└── utils
├── gralloc1-adapter
│ ├── Android.bp
│ ├── gralloc1-adapter.cpp
│ ├── gralloc1-adapter.h
│ ├── Gralloc1On0Adapter.cpp
│ └── Gralloc1On0Adapter.h
├── hal
│ ├── Android.bp
│ └── include
│ └── allocator-hal
│ └── 2.0
│ ├── Allocator.h
│ └── AllocatorHal.h
├── OWNERS
└── passthrough
├── Android.bp
└── include
└── allocator-passthrough
└── 2.0
├── Gralloc0Hal.h
├── Gralloc1Hal.h
└── GrallocLoader.h
11 directories, 20 files
1.2 allocator 2.0 service passthrough方式的实现
这里我们不对细节,做过多的纠缠,我们只梳理其大体框架!
/**
* The id of this module
*/
#define GRALLOC_HARDWARE_MODULE_ID "gralloc"
/**
* Name of the graphics device to open
*/
#define GRALLOC_HARDWARE_GPU0 "gpu0"
//[passthrough.cpp]
HIDL_FETCH_IAllocator(...)
GrallocLoader::load() //GrallocLoader.h
loadModule()//核心是这个,加载HAL MODLE
hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module)
createHal(module)//这里无论是Gralloc1Hal还是Gralloc0Hal最终都会调用 gralloc_open(module, &mDevice)
gralloc_open(module, &mDevice)
module->methods->open(module,
GRALLOC_HARDWARE_GPU0, TO_HW_DEVICE_T_OPEN(device)) //注意这里传递的id为GRALLOC_HARDWARE_GPU0
createAllocator(std::move(hal))
这里我们重点需要关心的是,这里hw_get_modul传递的id是GRALLOC_HARDWARE_MODULE_ID!
1.3 allocator HAL的实现
通过前面分析可知,hw_get_module会加载HAL模块,这里我们以Android默认的gralloc实现来说明:
//[hardware/libhardware/modules/gralloc]
├── Android.mk
├── framebuffer.cpp
├── gralloc.cpp
├── gralloc_priv.h
├── gr.h
└── mapper.cpp
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,//注意这里的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,
};
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)) {
//allocator的gralloc加载会走次分支
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;
}
这里需要注意的是,此时allocator service调用open时候传递下来的id为GRALLOC_HARDWARE_GPU0,这个地方要和后面的composer的open对比来看
1.4 allocator HAL alloc的实现
上面的都是常规操作,下面我们接下来看下 allocator HAL alloc的实现!
//[gralloc.cpp]
static int gralloc_alloc(alloc_device_t* dev,
int width, int height, int format, int usage,
buffer_handle_t* pHandle, int* pStride)
{
...
if (usage & GRALLOC_USAGE_HW_FB) {
err = gralloc_alloc_framebuffer(dev, size, format, usage, pHandle);
} else {
err = gralloc_alloc_buffer(dev, size, usage, pHandle);
}
if (err < 0) {
return err;
}
*pStride = stride;
return 0;
}
此时的你是不是蒙圈了!尼玛gralloc_alloc里面又有两个分支:
-
gralloc_alloc_framebuffer
这个分支比较特殊,主要用于GPU合成时候FramebufferSurface使用!然后该buffer在后面就可以用于hwcompower合成使用了。
并且这里注意这里的FramebufferSurface是消费者,当消费者设置了GRALLOC_USAGE_HW_FB后,这个值在其对应的生产者申请buffer类型的时候,会获取到这个usage,然后这个usage就会随着生产者allocat()的调用逻辑,传递到gralloc来了!//[frameworks/native/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp] FramebufferSurface::FramebufferSurface(HWComposer& hwc, DisplayId displayId, const sp<IGraphicBufferConsumer>& consumer, uint32_t maxWidth, uint32_t maxHeight) : ConsumerBase(consumer