Android Overlay学习 一
前文仅了解了overlay HAL的架构,下面继续看看系统层是如何调用Overlay模块。
1、 测试代码
frameworks/base/libs/surfaceflinger/tests/overlays/overlays.cpp提供了一个简单的overlay调用流程,可惜这个测试程序有错误,
在sp<Surface>surface=client->createSurface(getpid(),0,320,240,PIXEL_FORMAT_UNKNOWN,ISurfaceComposer::ePushBuffers);
这句话编译不过去,错误在Surface的申请,和overlay无关。我们来看看这段代码:
int main(int argc, char** argv)
{
//setupthethread-pool建立线程池
sp<ProcessState>proc(ProcessState::self());
ProcessState::self()->startThreadPool();// create a client to surfaceflinger 创建一个SurfaceFlinger client
sp<SurfaceComposerClient>client=newSurfaceComposerClient();
//createpushbuffersurface创建一个surface,最后那个参数是类型?
sp<Surface>surface=client->createSurface(getpid(),0,320,240,
PIXEL_FORMAT_UNKNOWN, ISurfaceComposer::ePushBuffers);// get to the isurface 取得isurface接口
sp<ISurface>isurface=Test::getISurface(surface);
printf("isurface=%p\n",isurface.get());
//nowrequestanoverlay创建一个overlay
sp<OverlayRef>ref=isurface->createOverlay(320,240,PIXEL_FORMAT_RGB_565);
sp<Overlay>overlay=newOverlay(ref);
/*
*herewecanusetheoverlayAPI创建好overlay后,即可使用overlay的API,这些都对应到overlayHAL的具体实现
*/
overlay_buffer_tbuffer;
overlay->dequeueBuffer(&buffer);
printf("buffer=%p\n",buffer);
void*address=overlay->getBufferAddress(buffer);
printf("address = %p\n", address);overlay->queueBuffer(buffer);//最重要的操作就是通过queueBuffer将buffer列队
return 0;}
2、Android系统创建中Overlay(调用createOverlay)
1)摄像头相关 CameraService.cpp (frameworks\base\camera\libcameraservice)
setPreviewDisplay()、startPreviewMode()
|
setOverlay()
|
creatOverlay()2)界面相关 ISurface.cpp (frameworks\base\libs\ui)
LayerBaseClient::Surface::onTransact()<--该函数位于LayerBase.cpp,好像是用于ibind进程通讯的函数
|
BnSurface::onTransact()//有5种方式,只有确定有overlay硬件支持时才会调用caseCREATE_OVERLAY
|
......
switch(code){
caseREQUEST_BUFFER:{
CHECK_INTERFACE(ISurface,data,reply);
intbufferIdx=data.readInt32();
intusage=data.readInt32();
sp<GraphicBuffer>buffer(requestBuffer(bufferIdx,usage));
returnGraphicBuffer::writeToParcel(reply,buffer.get());
}
caseREGISTER_BUFFERS:{
CHECK_INTERFACE(ISurface,data,reply);
BufferHeapbuffer;
buffer.w=data.readInt32();
buffer.h=data.readInt32();
buffer.hor_stride=data.readInt32();
buffer.ver_stride=data.readInt32();
buffer.format=data.readInt32();
buffer.transform=data.readInt32();
buffer.flags=data.readInt32();
buffer.heap=interface_cast<IMemoryHeap>(data.readStrongBinder());
status_terr=registerBuffers(buffer);
reply->writeInt32(err);
returnNO_ERROR;
}break;
caseUNREGISTER_BUFFERS:{
CHECK_INTERFACE(ISurface,data,reply);
unregisterBuffers();
returnNO_ERROR;
}break;
casePOST_BUFFER:{
CHECK_INTERFACE(ISurface,data,reply);
ssize_toffset=data.readInt32();
postBuffer(offset);
returnNO_ERROR;
}break;
caseCREATE_OVERLAY:{
CHECK_INTERFACE(ISurface,data,reply);
intw=data.readInt32();
inth=data.readInt32();
intf=data.readInt32();
sp<OverlayRef>o=createOverlay(w,h,f);
returnOverlayRef::writeToParcel(reply,o);
}break;
default:
returnBBinder::onTransact(code,data,reply,flags);
... ...3)LayerBuffer.cpp(frameworks\base\libs\surfaceflinger)这儿其实是createOverlay的实现
sp<OverlayRef>LayerBuffer::SurfaceLayerBuffer::createOverlay(uint32_tw,uint32_th,int32_tformat)
|
sp<OverlayRef>LayerBuffer::createOverlay(uint32_tw,uint32_th,int32_tf)
|
sp<OverlaySource> source = new OverlaySource(*this, &result, w, h, f); //通过OverlaySource来创建overlayLayerBuffer::OverlaySource::OverlaySource()//该函数调用了Overlay HAL的API createOverlay
{
overlay_control_device_t*overlay_dev=mLayer.mFlinger->getOverlayEngine();//getHAL
overlay_t* overlay = overlay_dev->createOverlay(overlay_dev, w, h, format);//HAL API// enable dithering...
overlay_dev->setParameter(overlay_dev,overlay,OVERLAY_DITHER,OVERLAY_ENABLE);
//设置参数,初始化OverlayRef类,OverlayRef的构造函数在Overlay.cpp中
mOverlay=overlay;
mWidth=overlay->w;
mHeight=overlay->h;
mFormat=overlay->format;
mWidthStride=overlay->w_stride;
mHeightStride=overlay->h_stride;
mInitialized=false;
......
*overlayRef=newOverlayRef(mOverlayHandle,channel,mWidth,mHeight,mFormat,mWidthStride,mHeightStride);
}3、Overlay HAL模块管理Overlay.cpp (frameworks\base\libs\ui)负责管理overlay HAL,并对HAL的API进行封装
1)打开Overlay HAL模块
Overlay::Overlay(constsp<OverlayRef>&overlayRef)
:mOverlayRef(overlayRef),mOverlayData(0),mStatus(NO_INIT)
{
mOverlayData=NULL;
hw_module_tconst*module;
if(overlayRef!=0){
if(hw_get_module(OVERLAY_HARDWARE_MODULE_ID,&module)==0){
if(overlay_data_open(module,&mOverlayData)==NO_ERROR){
mStatus=mOverlayData->initialize(mOverlayData,
overlayRef->mOverlayHandle);
}
}
}
}2)Overlay HAL的初始化参考上一段,overlayRef = new OverlayRef(mOverlayHandle, channel,mWidth, mHeight, mFormat, mWidthStride, mHeightStride);
构造函数位于Overlay.cpp
OverlayRef::OverlayRef(overlay_handle_thandle,constsp<IOverlay>&channel,
uint32_tw,uint32_th,int32_tf,uint32_tws,uint32_ths)
:mOverlayHandle(handle),mOverlayChannel(channel),
mWidth(w),mHeight(h),mFormat(f),mWidthStride(ws),mHeightStride(hs),
mOwnHandle(false)
{
}3)封装了很多的API,但是没有查到那儿有调用,看来还需要大改框架才能真正将overlay利用起来
比如TI自己写的opencore函数中到时有用到,主要负责视频输出。
Android_surface_output_omap34xx.cpp (hardware\ti\omap3\libopencorehw)4、总结
Overlay的输出对象有两种,一种是视频(主要是YUV格式,调用系统的V4L2),另外一个是ISurface的一些图像数据(RGB格式,直接写framebuffer)
从代码实现角度看,目前Android系统默认并没有使用Overlay功能,虽然提供了Skeleton的OverlayHAL,并对其进行封装,但是上层几乎没有调用到封装的API。
如果要用好OverlayHAL,需要大量修改上层框架,这对视屏播放可能比较重要,可参考TI的Android_surface_output_omap34xx.cpp。
此外Surface实现的Overlay功能和Copybit的功能有部分重复,从TI的代码看主要是实现V4L2的Overlay功能。