很多文章说Gralloc模块是由FramebufferNativewindow在构造函数中加载的,但是在android7.0的代码中没有找到FrameBufferNativewindow类。
通过查看代码,7.0版本,应该是HWComposer模块的构造函数中加载了Gralloc库:
// Load and prepare the FB HAL, which uses the gralloc module. Sets mFbDev.
int HWComposer::loadFbHalModule()
{
hw_module_t const* module;
int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
if (err != 0) {
ALOGE("%s module not found", GRALLOC_HARDWARE_MODULE_ID);
return err;
}
return framebuffer_open(module, &mFbDev);
}
然后通过open方法打开了Gralloc中的两个设备即fb0和gralloc:
static struct hw_module_methods_t gralloc_module_methods = {
.open = gralloc_device_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;
}
有一个问题,因为没有找到FrameBufferNativewindow,面向SurfaceFlinger的本地窗口是谁呢?是FramebufferSurface?即:android\frameworks\native\services\surfaceflinger\DisplayHardware\FramebufferSurface.cpp。
还在分析中...,那位朋友知道给指点下!
-----------------------
续:
面向SurfaceFligner的本地窗口也是Surface,跟面向应用程序的Surface是同一类型,只是其中缓冲区的来源不同,面向SurfaceFlinger的Surface对应的缓冲区是从帧缓冲区分配;面向应用程序的Surface对应的缓冲区是从匿名共享内存分配,这也符合应用程序和SurfaceFlinger共享这块缓冲区的特点。
先看面向SurfaceFligner的Surface:
SurfaceFlinger.cpp
void SurfaceFlinger::createDefaultDisplayDevice() {
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, type, consumer);
sp<DisplayDevice> hw = new DisplayDevice(this, DisplayDevice::DISPLAY_PRIMARY, type, isSecure,
token, fbs, producer, mRenderEngine->getEGLConfig(),useWideColorMode);
}
其中FramebufferSurface.cpp的构造函数中,通过BufferQueueConsumer设置了Surface要申请的缓冲区的用途。
FramebufferSurface.cpp
FramebufferSurface::FramebufferSurface(HWComposer& hwc, int disp,
const sp<IGraphicBufferConsumer>& consumer) :ConsumerBase(consumer),...{
mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
GRALLOC_USAGE_HW_RENDER |GRALLOC_USAGE_HW_COMPOSER);
}
通过BufferQueueConsumer的函数setConsumerUsageBits来设置USAGE的类型,会保存到BufferQueueCore中的mConsumerUsageBits变量中。
在看DisplayDevice的构造函数:
DisplayDevice.cpp
sp<ANativeWindow> mNativeWindow;
DisplayDevice::DisplayDevice( const sp<SurfaceFlinger>& flinger,...){
Surface* surface;
mNativeWindow = surface = new Surface(producer, false);
ANativeWindow* const window = mNativeWindow.get();
EGLSurface eglSurface;
eglSurface = eglCreateWindowSurface(display, config, window, NULL);
}
先是创建了Surface对象赋值给ANativeWindow类型的指针变量mNativeWindow,然后用其构造一个EglSurface,配置opengl es环境。
在看面向应用程序的Surface:
应用程序端的Surface实际对应了一个layer,
Layer.cpp
void Layer::onFirstRef() {
mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
}
uint32_t Layer::getEffectiveUsage(uint32_t usage) const
{
// TODO: should we do something special if mSecure is set?
if (mProtectedByApp) {
// need a hardware-protected path to external video sink
usage |= GraphicBuffer::USAGE_PROTECTED;
}
if (mPotentialCursor) {
usage |= GraphicBuffer::USAGE_CURSOR;
}
usage |= GraphicBuffer::USAGE_HW_COMPOSER;
return usage;
}
通过SurfaceFlingerConsumer间接调用了BufferQueueConsumer的setConsumerUsageBits函数,来设置缓冲区用途。
最后看缓冲区的分配:
BufferQueueProducer.cpp
void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height,
PixelFormat format, uint64_t usage) {
uint64_t allocUsage = 0;
allocUsage = usage | mCore->mConsumerUsageBits;
sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(
allocWidth, allocHeight, allocFormat, BQ_LAYER_COUNT,
allocUsage, {mConsumerName.string(), mConsumerName.size()});
}
先获取前面设置的usage,作为GraphicBuffer的参数。
GraphicBuffer.cpp
GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
PixelFormat inFormat, uint32_t inLayerCount, uint64_t usage, std::string requestorName)
: GraphicBuffer()
{
mInitCheck = initWithSize(inWidth, inHeight, inFormat, inLayerCount,
usage, std::move(requestorName));
}
status_t GraphicBuffer::initWithSize(uint32_t inWidth, uint32_t inHeight,
PixelFormat inFormat, uint32_t inLayerCount, uint64_t inUsage,
std::string requestorName)
{
GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
uint32_t outStride = 0;
status_t err = allocator.allocate(inWidth, inHeight, inFormat, inLayerCount,
inUsage, &handle, &outStride, mId,
std::move(requestorName));
return err;
}
GraphicBufferAllocator返回的是Gralloc中的Allocator,所以最终完成缓冲区分配的是Gralloc。
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, usage, pHandle);
} else {
err = gralloc_alloc_buffer(dev, size, usage, pHandle);
}
}
根据不同的用途,从不同的区域分配内存。
static int gralloc_alloc_framebuffer(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);
pthread_mutex_lock(&m->lock);
//从帧缓冲区
int err = gralloc_alloc_framebuffer_locked(dev, size, usage, pHandle);
pthread_mutex_unlock(&m->lock);
return err;
}
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);
if (fd < 0) {
ALOGE("couldn't create ashmem (%s)", strerror(-errno));
err = -errno;
}
return err;
}
帧缓冲区FrameBuffer可以看成是显示设备的抽象,所以往这块缓冲区post数据,就相当于送到了显示设备。
被显示的线段、字符、图形、背景色都会按像素一一存储在Framebuffer中,它是屏幕所显示画面的一个直接映像,也成为光栅,FrameBuffer中的每一个存储单元对应屏幕上的一个像素,整个帧缓存就对应了一帧图像。