Android Overlay学习 一

fanleiym 2010-08-11

前文仅了解了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来创建overlay

LayerBuffer::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功能。

相关推荐