android简易双屏支持【转】

本文转载自:http://blog.csdn.net/sfrysh/article/details/7463339

抱歉,之前说xorg的exa更新的时候恐怕一直不会更新了,
没有做xorg开发了。
转向android了。

最近断断续续做了一些杂七杂八的android事情,都是一些不太容易的事情。

简单的写了以下,android双屏的简易支持。
纲领性的一些东西吧。
简单双屏的支持。

和下面这种不一样哦
http://www.xici.net/main.asp?url=/u13971417/d101558450.htm
这种看起来完全是假的双屏,android完全运行在自己的屏幕上面,和主屏幕没有太直接的关系.
看起来更像双系统,而不是android的双屏。成本怕是很高的。

看,这个是两个独立的系统。
http://www.gadgetlite.com/2009/11/06/spring-design-dual-display-android/

国内国外好像还没有人做真双屏的工作(额,我好像总在做这样的事情呢)

简易的真双屏支持

有一说一,总体方案是同事定的,具体模块自己调查实现。
我对android的framework是很不熟悉,刚转过来,暂时看
surfaceflinger以及以下的一些东西。

目前只说display这边。如果要完整支持的话,需要做不少事情,比如事件处理Eventhub
,比如activity的管理。

按照计划是实现两个surfaceflinger的线程
每个surfaceflinger管理一个单独的硬件,也就是说,两个屏幕是单独运转的,互不干扰
surfaceflinger0管理原始的屏幕,surfaceflinger1管理第二个屏幕。
当然这个是因为google官方不支持,我们的一个偏门的支持办法。用display来区分不同的硬件。
也无法跨屏幕来显示东西。
两个屏幕之间可以通信,但是无法跨硬件显示。

上层应用调用的方法如下,比如animation的测试程序,以前是这样的。

BootAnimation::BootAnimation() : Thread(false)
{
    mSession = new SurfaceComposerClient();
}

如果我们要这个程序跑在第二个屏幕上面,程序需要做如下的修改。

BootAnimation::BootAnimation() : Thread(false)
{
    mSession = new SurfaceComposerClient(1);
}


上面是直接使用surfaceflinger的情况,如果需要应用自己做,则需要在上面的activemanager里面来做了,提供api给程序,设置当前程序的运行屏幕。

需要修改的模块如下
1:surfaceflinger
以前只添加一个服务surfaceflinger
现在需要再多添加一个服务surfaceflinger1
每个surfaceflinger知道自己所管理的硬件。


2:还有就是composer service也需要加入对应的逻辑。
3:framebuffer native window的逻辑

4:displayhardware的管理。
SurfaceFlinger初始化的时候会初始化硬件,id是surfaceflinger传递过来的。
两个surfaceflinger服务会初始化两个硬件,当然可以扩展到更多。

5:layer的处理
layer里面需要知道自己是属于哪个硬件的,是哪个设备里面的layer。

6:hardware模块的处理(gralloc模块)
主要是framebuffer open和gralloc。主要是设备的map,显存分配等等。
gralloc是一个单独的模块,和surfaceflinger,composerservice (libui,libsurfaceflinger等等和gralloc直接无法直接通信)等等无法直接通信。
Surfaceflinger到Displayhardware之后会dlopen这个模块。沟通的唯一的接口是gralloc这个hw_module_t里面的open函数,
只有这一个函数。几乎所有的地方都假定只有一个fb硬件,所以需要增加相关的逻辑。这里使用的还是全局变量。使用dlsym来获取的。

7:EGL的多display的支持。
目前如果不传递EGL_DEFAULT_DISPLAY的话,egl会直接返回错误。
其他还有不少逻辑也需要修改,主要是初始化部分的。真正运行起来之后,都是按照context的,可以理解为对象,都是自包含的,不怕display的问题。

8:模拟器支持多个硬件屏幕。
这个是在qemu里面改的,google这里改的还比较多,需要增加一个fb设备。


9:实现测试程序
直接改bootanimation就可以了。
验证的办法就是看fb1里面的东西是否被egl正常渲染进去了
当然,原来的程序都要是可以正常运行的,也就是说加了
一个屏幕,原始的屏幕要保持正常,新的屏幕也要可以正常
运行。

cat /dev/graphics/fb1 >/data/fb1
./adb pull /data/fb1 /tmp/fb1

ffmpeg -vcodec rawvideo -f rawvideo -pix_fmt rgb565 -s 800x600 -i fb1 -f image2 -vcodec png image%d.png

看看,应该能看到bootanimation的东西了。

双屏模拟器UI还没开发出来,目前只能这么验证。
这里fb1的virtual_size是fb1分辨率的两倍,所以取出来是两个的大小,这也是上面为什么用%d的原因,egl拿来一个作backbuffer
一个做frontbuffer的。我这个fb1是创建成了800x600





fb0的东西,也就是第一屏的东西
# cat /dev/graphics/fb0 >/data/fb0
ailantian@vax:~/soft/android/android-2.2/out/host/linux-x86/sdk/android-sdk_eng.ailantian_linux-x86/tools$ ./adb pull /data/fb0 /tmp/fb0
1308 KB/s (614400 bytes in 0.458s)
ailantian@vax:/tmp$ ffmpeg -vcodec rawvideo -f rawvideo -pix_fmt rgb565 -s 320x480 -i fb0 -f image2 -vcodec png image-fb0%d.png





注意,有时候fb设备里面的内容并不能忠实反应屏幕上面的东西
尤其是有硬件加速的时候,硬件锁住的时候是一个奇怪的东西。

至于主要的文件修改列表如下

android/skin/file.c
android/skin/file.h
cmds/bootanimation/BootAnimation.cpp
framebuffer.c
hardware.c
hw/android_arm.c
hw/goldfish_fb.c
include/hardware/gralloc.h
include/hardware/hardware.h
include/ui/FramebufferNativeWindow.h
include/ui/SurfaceComposerClient.h
liblog/logprint.c
libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
libs/surfaceflinger/LayerBase.cpp
libs/surfaceflinger/LayerBase.h
libs/surfaceflinger/LayerBlur.cpp
libs/surfaceflinger/LayerBuffer.cpp
libs/surfaceflinger/Layer.cpp
libs/surfaceflinger/LayerDim.cpp
libs/surfaceflinger/LayerDim.cpp
libs/surfaceflinger/Layer.h
libs/surfaceflinger/SurfaceFlinger.cpp
libs/surfaceflinger/SurfaceFlinger.h
libs/ui/FramebufferNativeWindow.cpp
libs/ui/GraphicBuffer.cpp
libs/ui/SurfaceComposerClient.cpp
libs/ui/Surface.cpp
modules/gralloc/framebuffer.cpp
modules/gralloc/gralloc.cpp
modules/gralloc/gralloc_priv.h
opengl/libagl/egl.cpp
opengl/libs/EGL/egl.cpp
opengl/libs/hooks.h

恩,也是刚转型做android,只能RTFS(read the fucking source)
android的代码还是很大的(2.5G),对这个框架也不了解,
另外就是c++也好多年不做了,实际上以前从来没做过实际项目,也遇到一些基本语法问题。
不过搜索引擎还是很不错的。
不喜欢c++的风格,一个函数实现多种功能,看代码的时候结构不清楚。

为什么不用一个surfaceflinger来管理所有硬件?额,因为现在不了解android的framework。
要一下子做的很好怕是有困难。只能一步一步来了
如果google自己做的话,应该是一个surfaceflinger的来管理所有的硬件。而且这样结构也更
清楚,也是努力的方向。,两个surfaceflinger的缺点和优点也还是比较明显,两个是独立的线程
互相不影响,一个挂掉或者阻塞或者delay,另外一个也没事,context就需要两个了,另外就是多个gpu的话,这样会容易扩展一些。

因为gpu只有一个,egl只需要操作一个gpu就可以了,至于copyblit,以msm的芯片来说
可以在不同的fb里面随便搬运,egl也可以直接访问这些区域。所以一个surfaceflinger理论上
也是可行的,而且结构更好。

像android这样严重依赖多线程的设计,就最好不要使用静态全局变量,或者系统的全局变量。
不然扩展的时候很不方便。不过android目前的逻辑就是这样,所以扩展不方便




额,顺便说说其他的系统
1:moblin
最早是intel的kernel加上maemo的系统,最早intel没有自己的系统,
做了几个版本之后有了自己的系统,以前主打mid
应用慢慢迁移到clutter了

2:maemo
是nokia的开源的移动系统,做的不错。
最早的框架是基于gtk的,后来nokia收购了qt,慢慢打算迁移到qt base
主打大屏幕手机和mid
图形系统最早是kdrive,后来迁移到xorg

3:meego
是moblin和maemo的结合体。

3:iphone os
苹果的系统,据说和pc是一样的,感觉不能一样,mac os应该要定制过才能。

4:android
google的手机系统,手机上主要还是高通的芯片,可能有山寨的也说不定,其他做arm芯片厂家比较多
也有的能自己出android的bsp,有的则希望外包做bsp卖自己的芯片。
智能电视上也开始用了,大家比较看好nvidia的芯片
这里显示芯片有很大重要性,大多amd的也就是ati的,多家封装的是这个gpu核心
还有就是pvr的,主要是ti系列。还有就是arm自己也出gpu,也就是mali系列。
图形系统是新开发的,不是很完善

5:chrome os
怎么说呢,就是linux系统,图形系统是xserver,应用上完全精简了。
浏览器是核心应用,基本上没有人选择这个系统,除了demo之外,也就是大家展会上经常看到的


6:恩,暂时想不起来其他还有什么系统了

总有人拿android和iphone比较。
个人观点。
android是年轻人,iphone是中年人。
android的变化是很剧烈的,保留着很多开发者的痕迹,还谈不上美观。
很多东西还没有定下来。就个人爱好来说,喜欢开放型的系统。可以随意使用的系统,使用起来方便的系统。
不喜欢itunes。iphone也喜欢,但是喜欢的不是功能,而是那种感觉,就是这个系统用起来的时候
你就感觉他为人性化操作作了很多工作,虽然你有时候说不出来哪里好,但是的确就是用起来舒服。
就是你总会在某一天发现一个新的功能,觉得,恩,这个功能真不错。但是说明书上没有说到它
除了itunes带来的不便之外,不能随意copy东西,不能随意安装软件等等限制。

android的进步看得见,变化很大,但是成熟度不够,
iphone 4.0呢?没见过,可能会很好吧,但是对苹果的东西不要抱太大期望,某一点让你特别喜欢就好了

大家都想赚钱,有竞争是好事,不然苹果怕是多少年懒得改进

posted @ 2017-11-16 14:07  请给我倒杯茶  阅读(739)  评论(0编辑  收藏  举报