如前所述,Gralloc模块主要由 gralloc_module_t 模块,alloc_device_t 设备和 framebuffer_device_t 设备3个结构体来描述。
1. Gralloc模块的主要调用者是ui库中的以下文件:
frameworks/base/libs/ui/FramebufferNativeWindow.cpp
FramebufferNativeWindow的构造函数如下:
/*
* This implements the (main) framebuffer management. This class is used
* mostly by SurfaceFlinger, but also by command line GL application.
*
* In fact this is an implementation of ANativeWindow on top of
* the framebuffer.
*
* This implementation is able to manage any number of buffers,
* defined by NUM_FRAME_BUFFERS (currently set to 2: front
* and back buffer)
*
*/
FramebufferNativeWindow::FramebufferNativeWindow()
: BASE(), fbDev(0), grDev(0), mUpdateOnDemand(false)
{
hw_module_t const* module;
if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
int stride;
int err;
#ifdef OMAP_ENHANCEMENT
int i;
#endif
err = framebuffer_open(module, &fbDev); //打开framebuffer设备
LOGE_IF(err, "couldn't open framebuffer HAL (%s)", strerror(-err));
err = gralloc_open(module, &grDev); //打开gralloc设备
LOGE_IF(err, "couldn't open gralloc HAL (%s)", strerror(-err));
// bail out if we can't initialize the modules
if (!fbDev || !grDev) //只有framebuffer和gralloc都存在,才能继续运行
return;
mUpdateOnDemand = (fbDev->setUpdateRect != 0); //可选的setUpdateRect
// initialize the buffer FIFO
#ifdef OMAP_ENHANCEMENT
mNumBuffers = NUM_FRAME_BUFFERS;
mNumFreeBuffers = NUM_FRAME_BUFFERS;
#else
mNumBuffers = 2; //初始化 buffer FIFO,双缓冲,有2块内存。
mNumFreeBuffers = 2;
#endif
mBufferHead = mNumBuffers-1;
#ifdef OMAP_ENHANCEMENT
for(i = 0; i < NUM_FRAME_BUFFERS; i++){
buffers[i] = new NativeBuffer(
fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB);
}
for(i = 0; i < NUM_FRAME_BUFFERS; i++){
err = grDev->alloc(grDev,
fbDev->width, fbDev->height, fbDev->format,
GRALLOC_USAGE_HW_FB, &buffers[i]->handle, &buffers[i]->stride);
LOGE_IF(err, "fb buffer %d allocation failed w=%d, h=%d, err=%s",
i, fbDev->width, fbDev->height, strerror(-err));
if(err){
mNumBuffers = i;
mNumFreeBuffers = i;
mBufferHead = mNumBuffers-1;
break;
}
}
#else
buffers[0] = new NativeBuffer( //初始化2个缓冲区
fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB);
buffers[1] = new NativeBuffer(
fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB);
err = grDev->alloc(grDev, //从gralloc设备中分配内存
fbDev->width, fbDev->height, fbDev->format,
GRALLOC_USAGE_HW_FB, &buffers[0]->handle, &buffers[0]->stride);
LOGE_IF(err, "fb buffer 0 allocation failed w=%d, h=%d, err=%s",
fbDev->width, fbDev->height, strerror(-err));
err = grDev->alloc(grDev,
fbDev->width, fbDev->height, fbDev->format,
GRALLOC_USAGE_HW_FB, &buffers[1]->handle, &buffers[1]->stride);
LOGE_IF(err, "fb buffer 1 allocation failed w=%d, h=%d, err=%s",
fbDev->width, fbDev->height, strerror(-err));
#endif
const_cast<uint32_t&>(ANativeWindow::flags) = fbDev->flags; //从framebuffer设备中获得常量
const_cast<float&>(ANativeWindow::xdpi) = fbDev->xdpi;
const_cast<float&>(ANativeWindow::ydpi) = fbDev->ydpi;
const_cast<int&>(ANativeWindow::minSwapInterval) =
fbDev->minSwapInterval;
const_cast<int&>(ANativeWindow::maxSwapInterval) =
fbDev->maxSwapInterval;
} else {
LOGE("Couldn't get gralloc module");
}
ANativeWindow::setSwapInterval = setSwapInterval; //处理函数指针
ANativeWindow::dequeueBuffer = dequeueBuffer;
ANativeWindow::lockBuffer = lockBuffer;
ANativeWindow::queueBuffer = queueBuffer;
ANativeWindow::query = query;
ANativeWindow::perform = perform;
ANativeWindow::cancelBuffer = 0;
#ifdef OMAP_ENHANCEMENT
LOGE("%d buffers flip-chain implementation enabled\n", mNumBuffers);
#endif
}
status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format,
int usage, buffer_handle_t* handle, int32_t* stride)
{
// make sure to not allocate a N x 0 or 0 x N buffer, since this is
// allowed from an API stand-point allocate a 1x1 buffer instead.
if (!w || !h)
w = h = 1;
// we have a h/w allocator and h/w buffer is requested
status_t err;
//mAllocDev 类型为 alloc_device_t,当调用的参数有GRALLOC_USAGE_HW_MASK标志时,有alloc_device_t调用分配一个内存,否则从软件分配一个内存。
if (usage & GRALLOC_USAGE_HW_MASK) {
err = mAllocDev->alloc(mAllocDev, w, h, format, usage, handle, stride);
} else {
err = sw_gralloc_handle_t::alloc(w, h, format, usage, handle, stride);
}
LOGW_IF(err, "alloc(%u, %u, %d, %08x, ...) failed %d (%s)",
w, h, format, usage, err, strerror(-err));
if (err == NO_ERROR) {
Mutex::Autolock _l(sLock);
KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
alloc_rec_t rec;
rec.w = w;
rec.h = h;
rec.s = *stride;
rec.format = format;
rec.usage = usage;
rec.size = h * stride[0] * bytesPerPixel(format);
list.add(*handle, rec);
}
return err;
}
status_t sw_gralloc_handle_t::alloc(uint32_t w, uint32_t h,int format,
int usage, buffer_handle_t* pHandle, int32_t* pStride)
{
int align = 4;
int bpp = 0;
switch (format){
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
bpp = 4;
break;
case HAL_PIXEL_FORMAT_RGB_888:
bpp = 3;
break;
case HAL_PIXEL_FORMAT_RGB_565:
case HAL_PIXEL_FORMAT_RGBA_5551:
case HAL_PIXEL_FORMAT_RGBA_4444:
bpp = 2;
break;
default:
return -EINVAL;
}
size_t bpr = (w*bpp +(align-1))& ~(align-1);
size_t size = bpr * h;
size_t stride = bpr / bpp;
size =(size + (PAGE_SIZE-1))& ~(PAGE_SIZE-1);
int fd = ashmem_create_region("sw-gralloc-buffer",size);
if (fd< 0) {
LOGE("ashmem_create_region(size=%d) failed (%s)",
size, strerror(-errno));
return -errno;
}
int prot = PROT_READ;
if (usage& GRALLOC_USAGE_SW_WRITE_MASK)
prot |= PROT_WRITE;
if (ashmem_set_prot_region(fd, prot)< 0) {
LOGE("ashmem_set_prot_region(fd=%d, prot=%x) failed (%s)",
fd, prot, strerror(-errno));
close(fd);
return -errno;
}
void*base = mmap(0,size, prot, MAP_SHARED, fd, 0);
if (base== MAP_FAILED){
LOGE("alloc mmap(fd=%d, size=%d, prot=%x) failed (%s)",
fd, size, prot, strerror(-errno));
close(fd);
return -errno;
}
sw_gralloc_handle_t* hnd = new sw_gralloc_handle_t();
hnd->fd= fd;
hnd->size= size;
hnd->base= intptr_t(base);
hnd->prot= prot;
*pStride = stride;
*pHandle = hnd;
return NO_ERROR;
}
status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle)
{
status_t err;
//mAllocMod的类型为 gralloc_module_t,可以从Gralloc模块中注册Buffer,也可以从软件注册Buffer
if (sw_gralloc_handle_t::validate(handle)< 0) {
err = mAllocMod->registerBuffer(mAllocMod, handle);
} else{
err = sw_gralloc_handle_t::registerBuffer((sw_gralloc_handle_t*)handle);
}
LOGW_IF(err,"registerBuffer(%p) failed %d (%s)",
handle, err, strerror(-err));
return err;
}
GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
PixelFormat reqFormat, uint32_t reqUsage)
: BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), //调用GraphicBufferMapper
mInitCheck(NO_ERROR), mIndex(-1)
{
width =
height =
stride =
format =
usage =
transform = 0;
handle = NULL;
mInitCheck = initSize(w, h, reqFormat, reqUsage);
}
status_t GraphicBuffer::initSize(uint32_t w, uint32_t h,PixelFormat format,
uint32_t reqUsage)
{
GraphicBufferAllocator& allocator = GraphicBufferAllocator::get(); //调用GraphicBufferAllocator
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;
}
// ============================================================================
// LayerBuffer::Buffer
// ============================================================================
LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers,
ssize_t offset, size_t bufferSize)
: mBufferHeap(buffers), mSupportsCopybit(false)
{
NativeBuffer& src(mNativeBuffer);
src.crop.l= 0; //剪切区域
src.crop.t= 0;
src.crop.r= buffers.w;
src.crop.b= buffers.h;
src.img.w= buffers.hor_stride?: buffers.w; //区域大小和颜色
src.img.h= buffers.ver_stride?: buffers.h;
src.img.format= buffers.format;
src.img.base= (void*)(intptr_t(buffers.heap->base())+ offset);
src.img.handle= 0;
gralloc_module_t const * module = LayerBuffer::getGrallocModule();
if (module&& module->perform){ //根据情况调用perform
int err = module->perform(module,
GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER,
buffers.heap->heapID(), bufferSize,
offset, buffers.heap->base(),
&src.img.handle);
// we can fail here is the passed buffer is purely software
mSupportsCopybit = (err == NO_ERROR);
}
}