Chinaunix首页 | 论坛 | 博客
  • 博客访问: 277925
  • 博文数量: 95
  • 博客积分: 2047
  • 博客等级: 大尉
  • 技术积分: 1022
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-14 16:18
文章分类

全部博文(95)

文章存档

2013年(1)

2011年(94)

我的朋友

分类: 嵌入式

2011-08-28 20:44:26

前文仅了解了overlay HAL的架构,下面继续看看系统层是如何调用Overlay模块。

1、 frameworks/base/libs/surfaceflinger/tests/overlays/overlays.cpp提供了一个简单的overlay调用流程,可惜这个测试程序有错误,
    在sp surface = client->createSurface(getpid(), 0, 320, 240, PIXEL_FORMAT_UNKNOWN, ISurfaceComposer::ePushBuffers);
这句话编译不过去,错误在Surface的申请,和overlay无关。

我们来看看这段代码:

int main(int argc, char** argv)
{
    // set up the thread-pool 建立线程池
    sp proc(ProcessState::self());
    ProcessState::self()->startThreadPool();

    // create a client to surfaceflinger 创建一个SurfaceFlinger client
    sp client = new SurfaceComposerClient();
    
    // create pushbuffer surface 创建一个surface,最后那个参数是类型?
    sp surface = client->createSurface(getpid(), 0, 320, 240, 
            PIXEL_FORMAT_UNKNOWN, ISurfaceComposer::ePushBuffers);

    // get to the isurface 取得isurface接口
    sp isurface = Test::getISurface(surface);
    printf("isurface = %p\n", isurface.get());
    
    // now request an overlay 创建一个overlay
    sp ref = isurface->createOverlay(320, 240, PIXEL_FORMAT_RGB_565);
    sp overlay = new Overlay(ref);
    
    /*
     * here we can use the overlay API 创建好overlay后,即可使用overlay的API,这些都对应到overlay HAL的具体实现
     */
    
    overlay_buffer_t buffer; 
    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硬件支持时才会调用case CREATE_OVERLAY
|
... ...
switch(code) {
        case REQUEST_BUFFER: {
            CHECK_INTERFACE(ISurface, data, reply);
            int bufferIdx = data.readInt32();
            int usage = data.readInt32();
            sp buffer(requestBuffer(bufferIdx, usage));
            return GraphicBuffer::writeToParcel(reply, buffer.get());
        }
        case REGISTER_BUFFERS: {
            CHECK_INTERFACE(ISurface, data, reply);
            BufferHeap buffer;
            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(data.readStrongBinder());
            status_t err = registerBuffers(buffer);
            reply->writeInt32(err);
            return NO_ERROR;
        } break;
        case UNREGISTER_BUFFERS: {
            CHECK_INTERFACE(ISurface, data, reply);
            unregisterBuffers();
            return NO_ERROR;
        } break;
        case POST_BUFFER: {
            CHECK_INTERFACE(ISurface, data, reply);
            ssize_t offset = data.readInt32();
            postBuffer(offset);
            return NO_ERROR;
        } break;
        case CREATE_OVERLAY: {
            CHECK_INTERFACE(ISurface, data, reply);
            int w = data.readInt32();
            int h = data.readInt32();
            int f = data.readInt32();
            sp o = createOverlay(w, h, f);
            return OverlayRef::writeToParcel(reply, o);
        } break;
        default:
            return BBinder::onTransact(code, data, reply, flags);
... ...


3)LayerBuffer.cpp (frameworks\base\libs\surfaceflinger) 这儿其实是createOverlay的实现
sp LayerBuffer::SurfaceLayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t format)
|
sp LayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t f)
|
sp 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();//get HAL
    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 = new OverlayRef(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(const sp& overlayRef)
    : mOverlayRef(overlayRef), mOverlayData(0), mStatus(NO_INIT)
{
    mOverlayData = NULL;
    hw_module_t const* 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_t handle, const sp& channel,
         uint32_t w, uint32_t h, int32_t f, uint32_t ws, uint32_t hs)
    : 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)



总结:
Overlay的输出对象有两种,一种是视频(主要是YUV格式,调用系统的V4L2),另外一个事ISurface的一些图像数据(RGB格式,直接写framebuffer)
从代码实现角度看,目前Android系统默认并没有使用Overlay功能,虽然提供了Skeleton的Overlay HAL,并对其进行封装,但是上层几乎没有调用到封装的API。
如果要用好Overlay HAL,需要大量修改上层框架,可参考TI的Android_surface_output_omap34xx.cpp。
此外Surface实现的Overlay功能和Copybit的功能有部分重复,从TI的代码看主要是实现V4L2的Overlay功能。

阅读(653) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~