前文仅了解了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)
{
    // set up the thread-pool 建立线程池
    sp<ProcessState> proc(ProcessState::self());
    ProcessState::self()->startThreadPool();

// create a client to surfaceflinger 创建一个SurfaceFlinger client
    sp<SurfaceComposerClient> client = new SurfaceComposerClient();
   
    // create pushbuffer surface 创建一个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());
   
    // now request an overlay 创建一个overlay
    sp<OverlayRef> ref = isurface->createOverlay(320, 240, PIXEL_FORMAT_RGB_565);
    sp<Overlay> 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;
}

2Android系统创建中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<GraphicBuffer> 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<IMemoryHeap>(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<OverlayRef> 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<OverlayRef> LayerBuffer::SurfaceLayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t format)
|
sp<OverlayRef> LayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t f)
|
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();//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);
}

3Overlay HAL模块管理
Overlay.cpp (frameworks\base\libs\ui)负责管理overlay HAL,并对HAL的API进行封装

1)打开Overlay HAL模块
Overlay::Overlay(const sp<OverlayRef>& 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<IOverlay>& 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)

4、总结
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功能。

第三部分 overlay 学习的更多相关文章

  1. C#中的线程三 (结合ProgressBar学习Control.BeginInvoke)

    C#中的线程三(结合ProgressBar学习Control.BeginInvoke) 本篇继上篇转载的关于Control.BeginInvoke的论述之后,再结合一个实例来说明Cotrol.Begi ...

  2. 三、Android学习第三天——Activity的布局初步介绍(转)

    (转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 三.Android学习第三天——Activity的布局初步介绍 今天总结下 ...

  3. JavaWeb学习总结(三)——Tomcat服务器学习和使用(二) 包含https 非对称秘钥 NB

    JavaWeb学习总结(三)--Tomcat服务器学习和使用(二) 一.打包JavaWeb应用 在Java中,使用"jar"命令来对将JavaWeb应用打包成一个War包,jar命 ...

  4. 精通ASP.Net MVC 3 框架(第三版)学习笔记

    精通ASP.Net MVC 3 框架(第三版)学习笔记 代码才是王道. http://pan.baidu.com/s/1pJyL1cn

  5. JavaWeb学习总结(三)——Tomcat服务器学习和使用

    收藏 JavaWeb学习总结(三)——Tomcat服务器学习和使用 http://www.cnblogs.com/xdp-gacl/p/3744053.html

  6. JavaScript高级程序设计(第三版)学习,第一次总结

    Array类型 var arr = []; arr.length; //返回数组元素个数 改变length可以动态改变数组大小 检测数组 instanceof可以检测某个对象是否是数组,限制:只能是一 ...

  7. DirectX 9 UI三种设计学习笔记:文章4章Introducing DirectInput+文章5章Wrapping Direct3D

           本文从哈利_创.转载请注明出处.有问题欢迎联系本人!        邮箱:2024958085@qq.com 上一期的地址: DX 9 UI设计学习笔记之二 第4章 Introducin ...

  8. 第三周java学习总结

    学号 20175206 <Java程序设计>第三周学习总结 教材学习内容总结 本周为第四章的学习,分为以下几个方面: 1.包与代码组织 2.String类 3.对象创建 4.包装类 经过代 ...

  9. 2018年-2019年第二学期第三周C#学习个人总结

    在第三周,我们又开始了C#的进一步学习,学习的范围是从4.8static关键字到4.11对象初始化器.在4.8static关键字我学到了静态字段,静态属性,静态方法,静态类,静态构造方法单例模式,嵌套 ...

随机推荐

  1. [Database][SQL] 取得SQLServer中某一欄位名稱所在的資料表及欄位相關資訊

    取得SQLServer中某一欄位名稱所在的資料表及欄位相關資訊  

  2. 打破常规——大胆尝试在路由器上搭建SVN服务器

    注册博客园挺久了,一直比较懒,虽然有几次想写点文章,但是一直没有行动,今天给大家带来一篇比较有意思的文章,不涉及技术上的,希望大家轻拍.本文的文字和图片全部为原创,尊重作者转载请注明出处! 说起路由器 ...

  3. 记一个JAVA关于日期的坑

    JAVA解析日期格式代码,之前一直写成:“yyyy-MM-dd hh:mm”,比如"2016-01-18 11:00"."2016-01-18 15:00"都可 ...

  4. ISBN

    问题描述 每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括9位数字.1位识别码和3位分隔符,其规定格式如“x-xxx-xxxxx-x”,其中符号“-”是分隔符(键盘上的减号),最后一位 ...

  5. C语言-创建链表及排序

    #include <stdio.h> #define NEWNODE (Node *)malloc(sizeof(Node)) typedef struct mynode{ int num ...

  6. 【Passport】微软过时的技术

    虽然已过时,没来得及体验,摘录一段别人的文章,假装对passport的了解 微软在过去的身份验证服务上,一直采用的Passport验证,但已经是N年前推出来的一个软件架构,当然也被软件界很多地方采用到 ...

  7. OData 集成

    OData 集成 文档目录 本节内容: 简介 安装 安装Nuget包 设置模块依赖 配置你的实体 创建控制器 示例 获取实体列表 请求 响应 获取单个实体 请求 响应 获取单个实体及导航属性 请求 响 ...

  8. 微软Hololens学院教程-Hologram 230-空间场景建模(Spatial mapping )【微软教程已经更新,本文是老版本】

    这是老版本的教程,为了不耽误大家的时间,请直接看原文,本文仅供参考哦!原文链接:https://developer.microsoft.com/EN-US/WINDOWS/HOLOGRAPHIC/ho ...

  9. GWT RPC

    GWT RPC GWT RPCRemote Procedure Calls GWT: Google Web Toolkit的缩写,有了 GWT可以使用 Java 编程语言编写 AJAX 前端,然后 G ...

  10. NSFileHandle 和 NSFileManager的一些用法

    文件操作 NSFileManager 常见的NSFileManager文件的方法: -(BOOL)contentsAtPath:path 从文件中读取数据 -(BOOL)createFileAtPat ...