前文仅了解了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;
}
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<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);
}
3、Overlay 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功能。
分享到:
相关推荐
在百度地图Android SDK中,Overlay Item通常表示地图上的一个特定标记或图标,例如用户的位置、兴趣点等。拖拽功能允许用户通过手指操作移动这些标记,这在需要动态调整位置或进行交互式操作的场景下非常有用。 ...
在Android开发中,"Overlay Menu"通常指的是一个悬浮在应用主界面之上的菜单,它可以提供额外的功能选项,而不会遮挡或干扰用户对主要界面的交互。这种设计模式在许多现代应用中非常常见,比如社交媒体应用或者游戏...
开发者可能通过这个项目来学习和实践高德地图API的使用,以及Android平台上照相功能的集成。 总结来说,这个项目涵盖了以下几个关键知识点: 1. 高德地图API的Overlay使用,包括自定义绘制和点击事件处理。 2. ...
在Android开发中,创建引人注目的用户界面是至关重要的,而`OverlayCardViewPager`就是一个实现独特视觉效果的工具,它能为应用带来层叠卡片的动态展示效果。`CardView`是Android支持库中的一个组件,常用于构建具有...
"Android学习笔记 - 地图(1)"可能涵盖了创建地图的基本步骤,如添加地图Fragment,设置地图类型(卫星、普通、地形等),以及如何调整缩放级别和滚动地图。文档还可能讨论了权限管理,例如在AndroidManifest.xml中...
此资料包含 Android学习笔记 - 地图.doc 通过地名获得经纬度并标识在地图上.doc 点中overlay弹出带尾巴的气泡的实现.doc 传递坐标到Google地图.doc android map.doc Android地图和定位学习总结 .doc 希望对大家有...
在Android开发中,WebView是一个非常重要的组件,它允许我们在应用程序中内嵌网页内容,实现与网页的交互。本文将深入探讨WebView的相关知识点,包括它的基本使用、设置、以及与JavaScript的交互。 首先,使用...
嵌入式Linux系统学习者:将Android作为一个集Linux核心和应用层程序于一体的系统进行学习,并可以利用Android的仿真环境运行和调试程序。 读者在学习本书的过程中,应尽量对照本书的框图和手头的Android源代码,...
1. **集成百度地图SDK**:首先,你需要下载百度地图Android SDK,并将其库文件(通常为.aar格式)导入到Delphi的项目中。这可以通过在项目的Library Path中添加路径或直接将aar文件解压并引用其包含的.jar和.so文件...
在Android系统中,overlay是一种允许自定义系统UI和应用行为的方式,通过将用户提供的资源覆盖到系统默认资源上。 文件列表中的"xhochy-overlay-源码.zip"可能包含以下部分: 1. **代码结构**:通常,源码会按照...
通过本文的学习,我们可以了解到Android UI设计的核心概念及其基本组成部分。了解不同类型的ViewGroup及其应用场景有助于开发者更好地设计出美观、实用的应用界面。无论是静态定义还是动态构建,合理的UI设计都能够...
1. **地图初始化**:在Activity或Fragment中,我们需要创建一个MapView对象,并设置其布局参数。然后通过调用百度地图API的onCreate、onResume、onPause和onDestroy方法来管理地图的生命周期。 2. **显示地图**:...
在Android应用开发中,Google Maps API是一个至关重要的组件,它允许开发者在应用程序中集成谷歌地图的功能,提供丰富的地理位置服务。本文档将深入探讨Android Map API v1,这一版本虽然已被更新的v2替代,但对于...
在Android系统中,桌面悬浮窗是一种非常实用的功能,它可以在用户使用其他应用程序的同时显示重要的信息或者提供便捷的操作入口。本文将深入探讨如何实现一个具备自由拖动和智能隐藏功能的Android桌面悬浮窗。 首先...
在Android开发中,集成地图功能是一项常见的需求,而百度地图API为开发者提供了丰富的地图操作接口。本篇将详细讲解如何在Android应用中调用百度地图并实现自定义覆盖层,以便将数据可视化地展示在地图上。 首先,...
[Android.UI基础教程].Jason.Ostrander.扫描版,关于android的UI设计方面的知识,学习过程的经典书
嵌入式Linux系统学习者:将Android作为一个集Linux核心和应用层程序于一体的系统进行学习,并可以利用Android的仿真环境运行和调试程序。 读者在学习本书的过程中,应尽量对照本书的框图和手头的Android源代码,...
【标题】"安卓Android源码——android 悬浮窗.rar" 涉及到的是Android系统中的悬浮窗功能实现,这是Android应用开发中一个相对高级且实用的技术。悬浮窗通常被用于实现类似通知、快捷操作或者辅助工具的功能,可以在...
嵌入式编程是将操作系统和应用程序集成到硬件设备中的技术,Android系统因其开源性和灵活性,已经成为...深入学习这一主题,不仅可以提升对Android系统底层运作的理解,还能为开发高效、可靠的嵌入式设备奠定坚实基础。