Chinaunix首页 | 论坛 | 博客
  • 博客访问: 239084
  • 博文数量: 32
  • 博客积分: 2033
  • 博客等级: 大尉
  • 技术积分: 354
  • 用 户 组: 普通用户
  • 注册时间: 2007-06-10 01:53
文章分类
文章存档

2011年(2)

2010年(16)

2009年(13)

2008年(1)

我的朋友

分类: LINUX

2010-07-31 19:23:05


Xorg 硬件加速 常用术语


firefox 4.0 pre来这里用cubog,现在没法输入焦点,只好先插入一个表格。

已经转型不做Xorg了,现在做android了,还是市场决定的吧。

不过xorg本身是一个很大的体系,所以本来自己有一些理解也不到位的地方,所以这里的答案并非最终答案
只供大家参谋,要是商业资讯要收咨询费的哦,1000美元一天啊。不过现在不做xorg可,应该可以写写了

1:什么是xorg的驱动
恩,这里简单来分吧,我说一下以前大体从事过的一些
1)输入设备的驱动,这个比较容易理解,之前的文章当中也有描述,比如鼠标,键盘,touchpad
touchscreen的驱动等等。xorg的inputinit(有点记不太清了)
2)图形驱动,这里实际上是输出设备的驱动,也就是xorg里面的outputinit(有点记不太清了)
图形驱动分的部分也比较多,但是大体上分为2D和3D两个部分。

xorg的大逻辑,开始的时候会进行各种初始化,输入部分,输出部分。事件队列,各种extention,等等


输入部分的逻辑相对来说比较简单,之前也有讲过这里的逻辑,所以不再赘述。
无非是从设备文件里面读消息,然后post消息到xorg的事件队列里面。不过实际要做好这里并不容易
xorg本身是bug很多的,另外就是之前也说到xorg本身的设计问题。还有就是会经常遇到一些
莫名其妙的bug,如果同时碰到图形驱动也出问题。有时候是kernel里面挂掉,有时候是xorg的逻辑
挂掉,有时候是其他驱动block住,总之多调试,就有经验了,希望国内的工程师多起来。

不过就xorg来说,没有商业的支持发展非常的缓慢,sun又死掉了,xorg就更不好过了。

android发展的不错,市场上要做的也多,所以需求大了,人都要转了。

下面主要描述一下图形部分的。

首先要说明的是xorg是pc用的,虽然n810?没记错的话,就是nokia的用maemo系统那个手机。
开始用的是kdrive。问题来了,

什么是kdrive?
之前已经有文章描述,这里再说一次,
kdrive是xserver的一种。看xorg的代码树下面就知道有多种xserver,他们的大体逻辑是一样的。
mi目录下面是最核心的抽象,抱歉这里都是凭脑袋写的,不能回去翻代码了。各种不同的xserver
设计的目的不一样,但是上面自然都是支持xlib,再往上就是支持gtk,qt这些widget了,
简单的说一些xserver
dmx分布式的x,大家可以man 一下就知道了,每个server目录下面都有说明的
xfree86就是我们通常说的xorg了。
kdrive就是kdrive了。也就是以前的tinyx,那个某某觉得xfree86的代码过于复杂,
(抱歉我实在是记不住名字了,对明星实在是不上心)
大家可以去翻翻以前的xserver的代码,极其混乱。后来做了很多工作,包括模块化,这个
工作对后来者来说是非常有作用的。kdrive的设计是非常简单有效的,大家可以去翻翻



好了,这里再说说kdrive的缺陷。自然就是很多扩展都不支持了。
最早的时候还支持kaa,之前有文章讲述什么是kaa了,之前也支持xvideo,
后来干脆都去掉了,好像就是去年还是前年的事情,所以现在kdrive是完全没有硬件加速框架了。
还有就是很多逻辑处理有问题,比如输入事件,输出事件,xorg现在更新完全有点伤筋动骨了。但是
kdrive维护的人就很少。所以nokia的maemo也该成了xorg了,后来nokia和intel把maemo改名
叫meego了。

本文恐怕比较长,吃饭去回来再写。


插播一段邮件,会有问题吗?
-------------------------------------------------------------------------

上面5点这里解释一下
Xorg和opengl有关系,但是和opengles并没有任何直接的关系,目前只有eglx和egl/opengles有一点关系,但是这个东西并没有
标准化的,所以并不推荐使用。我们之前给别人做东西的时候倒是用过,但是那个是所有的3D应用都是用clutter来做的,后端
是eglx。驱动是基于glx/dri的。当然kernel里面也是有drm的,这个工作量来说太大了,而且当时是跟高通合作做的。需要各个
方面的专家来协同工作。

还有就是EGL在不同的平台上面差别是很大的,比如差不多两年前大家的EGL都是只支持fbdev的。后来的才慢慢出现支持xserver
的版本。这个区别主要是底下的nativewindow系统不同。比如android下面直接使用framebuffer,xorg下面使用的是xwindow

不知道你们具体的需求是什么,单纯的egl/opengles的应用是比较少的,没法支持多个window,单个应用占全屏幕的,这样来说
对系统限制很大,应用本身的限制也很大。gui的程序开发限制就多了。如果没有图形framework的话,开发应用也难度太高。

你说的3D的窗口管理器,窗口管理器是和图形系统紧密相关的,看你这里的意思是,你们已经定了xserver这个图形系统?


做2D的加速需要有2D芯片的资料,做3D,大多数情况下你们拿到的OPENGLES的,都是一个比较简单的版本,比如底下的图形系统
是专有的,而不是xwindow作为nativewindow的。目前支持比较多的两种nativewindow一个就是fbdev,另外一个就是xwindow的

这里有一个困难就是,这个东西都是和本地的图形系统相关的,比如你如果使用的是xwindow的话,首先你是要把buffer放到
显存里面的,xwindow要能够管理这个。但是现在你们的opengles和xorg是完全独立的两套系统,xwindow是要管理最后的输出的
但是你们的opengles会直接把swapbuffer输出到屏幕上面去。


也就是说实际上xwindow必须管理显卡的资源无论你通过什么接口,dri也好,或者私有的接口也好,实际dri的接口就是为了
2D和3D共享资源,3D画完了之后是需要输出到2D平面的。



> 6、我不太熟悉DRI,也不太熟悉EXA,如果不考虑太复杂的情况下,如何用 SDK 完成一个,带硬件加速功能的驱动,让我编译出来的 XORG
> 可以使用?最起码我可以先完成一个,支持 2D 加速的XSERVER,具体我应该怎么做呢?


不知道你们是否已经把xorg跑起来了,把xorg跑起来本身也需要做很多工作,你需要交叉编译这个系统,xorg本身依赖的库也是
很多的。如果没有的话你们可以先跑一个软的,也就是使用fbdev驱动的,不过这个需要系统能够提供framebuffer的设备。是纯软
的方案,

不知道你们是否有2D的芯片,还是说只有一个gpu,对方只提供了opengles/eg/openvg这样的东西给你们。
如果是只有后面的东西,2D加速时没有办法的,因为后面的3D加速的东西没法放到2D这边来。是两套完全不同的东西。
至于xgl,是用opengl来实现xrender方案的,但是一个问题是,它已经死掉了,现在应该是已经无法运行了。还有就是这个方案
本身是需要有opengl的驱动也就是opengl的应用能完全跑起来的,还有就是它依赖几个特殊的opengl的扩展,否则极慢,
不过opengles实际比opengl还是差很多的,opengles实际不需要glx的,除非你需要实现eglx

从现在已有的嵌入式的方案来说(开源的)一般他们会先实现xvideo的加速,因为多媒体这边对性能要求是最高的。实现也
相对简单一些。前提还是你们有2D的芯片,用opengles是不行的,除非能让opengles和xwindow的输出能够统一起来,也就是
把opengles的输出让xwindow来管理。xvideo主要是解决视频显示中颜色空间转换和视屏缩放的。


至于你说的把opengles整合到xorg里面,看你的意思是想用opengles/openvg来加速xorg。
arm曾经想让我们在他们的gpu(mali)这么干来,没答应他们。
如果你要给个确定的答复,我觉得是不可能了。
如果技术能力许可,可以实现的方案是这样的。
1)实现eglx的支持(主要是让opengles的输出能够被xwindow管理起来,就是clip等等的问题)
2)有了上面的之后就可以实现xorg+eglx+opengles的框架了,在这个框架之上可以使用一些eglx的框架,比如clutter。
这个时候只需要使用clutter来开发应用即可,不过这个东西主要是用来做比较酷炫的效果的,消费类产品比较适合.

这里可以不用考虑dri的问题,原因上面已经描述。私有的接口也可以,只要能实现就可以。
但是实际上你要实现的也是和dri类似的东西,就是窗口覆盖之后让egl只输出该输出的部分等等。


2D加速不知道你们有多大的需求,实际上比如android等等系统2D绘图的部分也是纯软件的,
还有就是2D加速(exa)部分也是要把东西放在显存里面才能加速的。这个部分并不是使用的egl/openges
这种框架的。

2D加速现在也有使用dri的了,没记错的话intel的驱动就是。
不过后来intel的驱动七改八改(kms,gallium)现在也不知道什么状态了。
回到正文。

kdrive的缺陷很多,这里说的很多扩展,比如xrandr,一般用来设置屏幕分辨率,旋转,多个屏幕的
输出选择等等,比如你要输出到DVI,或者HDMI。还有就是xinerama,多个屏幕组成一个屏幕。
还有一个根本的缺陷就是没有3D,因为没有glx dri等等支持而丧失了3D能力支持。
另外的根本缺陷就是驱动不能动态加载了。驱动支持的种类有限,对比xorg这边频繁的bug修改来说
kdrive本身已经缺乏更新,kdrive里面自带的驱动也是更缺乏更新了,大家还在不断的删除不被
维护的驱动,所以kdrive自身的能力就很有限了。还有不支持XKB(没记错的话),多国键盘的支持
也会有问题,这些很多限制在后期扩展的时候问题就很麻烦。
可能最大的限制还是大家移除了kdrive的硬件加速机制。


好,回来图形加速部分

我们已经不再讨论kdrive了,使用xorg取代kdrive,包括在嵌入式系统里面,前提是图形系统选型时选择了
xserver,那么xorg就是唯一之选了,

xorg的加速,我们这里讲到的加速暂时不提3D加速,实际上3D加速和xorg本身并没什么关系
3D只是给大家提供一种机制来创建3D的应用,比如游戏等等,所以3D部分是相对独立的。
3D之所以和xorg有关,是因为我们屏幕只有一个,所有的应用都要往屏幕上面输出,2D的部分要输出
3D的部分也要输出,所以需要有人来管理这个事情,比如说一个window盖住了3D游戏的一部分
那个3D游戏应当只输出没有被覆盖的那个部分。只有这个地方xorg和3D才有交集。glx就是用来干这个的
了。3D部分要使用glx来和xorg交流。


好下面,确定了加速目前只指2D加速,至于软3D和硬3D的区别后面会讲到
2D的加速,目前对于xorg来说exa是官方的方案,至于其他的衍生方案,比如intel的uxa什么的
暂时不提。

exa加速方案

exa的由来。

最早的xfree86的加速方案目前可以查到的使用的是xaa的方案,
提供了众多的接口。后来有上面那个论文说了,我们只要加速少数的接口就可以了,
还有就是我们的显存管理要更加有效才可以。细节可参考上面的论文,(相关的论文众多,需要抱着
洋人们的论文多看看才行)
价值xfree86过于臃肿,后来直接就有了tinyx,后来变为kdrive,kdrive设计的加速框架
本称之为kaa。这里还是有必要提一下kaa的显存划分,这个之前的文章略掉了。
kaa的显存划分在上面的论文也有,时间长了有点记不住了,大体上是有对应屏幕的部分。
还有就是离屏的部分,也就是offscreen的部分,但是这些都是一个线性的空间。
以最常见的状况来说,比如我们在kernel里面fb0的分辨率是1024x768,这个一般我们指的是
第一个page,也就是屏幕可见的部分,这里熟悉framebuffer driver的朋友们知道
fbinfo里面还有一个virtual_size比如可能是1024x1536(没算错吧)这个代表fb0这个设备有两个
page,一个对应屏幕,一个对应offscreen。当你cat这个设备的时候,会输出两个屏幕分辨率那么
大的区域。当然一般都是两个page。不过也有4个的,就是看你对显存有多大的需求了。
这个地方如果有4个,也始终只有一个是对应屏幕的。剩下的三个page都是offscreen的。
我们为什么要这么多offscreen的空间呢?

答案是,我们的offscreen是用来加速用的。注意这里的4个page都是显存。所有的加速都是必须在
显存里面完成的。gpu只能在显存里面计算的,不过如果说嵌入式,因为都是内存,通过内核里面实现
一定的机制,gpu和cpu是都可以访问这个空间的。

那么比如我有一个surface,要加速怎么办,自然是先要倒到显存里面,然后绘图,然后再显示出去。
但是显存的大小始终是有限的,总有用完的时候,用完了怎么办,这个时候需要就要发生交换,
把显存里面踢出一些东西到系统内存,然后把要加速的东西放到这个被释放出来的空间。
一个简单的例子,比如xvideo,我们从mp4文件里面先要demux,分离出视频,音频,字幕等等数据,
对于视频,然后是解码,解码出来是一帧一帧的图片,对于pc来说,纯cpu解码的来说,这一切都是发生
在内存里面的,最后解码完的数据自然是一个buffer,也是在内存里面,可能是i420的格式,分辨率是
1280x720.然后我们要把这个数据倒到显存里面去,这个是xvideo自身提供的框架来自己做的。
然后剩下的就是大家做的xvideo加速来做的事情了,这个东西已经在显存里面,我们首先要转换成RGB
然后缩放成窗口大小,比如当前的window可能只有300x200.这个地方xvideo一般来说是直接显示
到屏幕上面去了。可以使用overlay的。但是overlay的缺点就是如果有窗口盖住了这个mediaplayer
但是mediaplay还是按照原始的大小输出的。也就是说这个window并没有被xwindow管理,xvideo
直接输出到了framebuffer了,注意这个framebuffer并不一定指fb0的第一个page。所以后来
大家用texture的video输出。也就是输出到一个buffer,然后由xwindow的窗口管理机制来剪切这个区域

当然芯片越多,这里就越复杂,比如一般都有dsp了,这个解码完的数据可能就不是在内存里面了
可能是一块特殊的区域,需要使用特殊的机制才能取出来。还有就是显示的时候可能是2D的芯片操作
也可能是3D的芯片去操作,也可能是cpu去操作,这个要看soc上面到底有多少加速芯片,和这个加速框架
具体是怎么实现的,整个加速的框架是必须放在整个系统里面来考虑的,这样才能发挥芯片本身应该有的性能,pc则又不同具体情况具体对待。


回到kaa的显存部分,2个page很多时候可能并不够用,一个简单的例子就是,比如我们的屏幕是720p
1280x720的。我当前本来有很多window,会占用一部分显存。然后我们还要解码视频。如果解码的输出
是直接放在显存里面,这本身就会占用显存,我们假定是720p的i420的数据,这会占用很多显存,然后
我们转换格式,缩放的时候还需要差不多同样的显存。

今天天气很好,适合看书,少更新点

我也是用拼音打字的,别字较多,希望不太影响阅读

上面说了kaa的显存管理机制了。
要加速的话,硬件是要能够访问这个offscreen的区域的,也就是说那个2D的芯片(用kdrive的一般
只能用2D加速了)要能够访问这个offscreen的区域和onlinescreen的区域。并在这个区域里面计算。



exa,composite, composite manager, xgl

这几个东西本来没有太直接的关联,但是还是放在一起说了吧。

xgl之前有解释,上面也有解释,实际是用opengl来实现了xrender的接口,实际也是实现了exa
用opengl来实现的,具体的操作的时候使用的库叫做glitz,不过现在已经死了。
composite extension是xorg比较新的扩展,和damage extention一样,是算出来最晚的几个
extension之一了。不过也出来很久了。这里说说它的作用。
我们默认的情况下,创建window的时候都是可见的,也就是Xcreatewindow,这个是libx11,也就是xlib
的函数,就可以创建一个window,这里实际上是走socket到了xserver里面,然后window是在xserver
这边创建的。这个就是cs架构了,客户端是请求操作,xserver这边分配实际的资源。至于大家说用
gtk,qt,底下实际还是要走xlib的。当然,gtk和qt都有其他的后端,比如fbdev,但是用的最广泛
的还是x11的后端了。我们不讨论用的极少,又没有成熟的东西。以免大家混淆。
创建window都是可见的,我们要绘图的时候就直接显示到屏幕上面的,

但是后来大家有一个需求,就是说我们要做透明窗口的效果。那首先我们要把所有的window离屏画好,
然后再挨个做alpha blending到rootwindow,这样我们就可以看到一个窗口透过另外一个窗口的效果了
所以overlay是被拒绝的,overlay以后可能用的也会很少吧。实际窗口系统要的是规范性,性能是
可以放在其次的,比如我们应该看到该看到的区域,不该看到的区域不要被看到。这个是最基本的,但是
overlay就破坏了这种规范。

好,说多了,那么要怎么实现呢,这里就是composite extension了。具体用是在什么地方用呢?
以linux pc来说,是window manager来用的。一般都是实现在windowmanager里面的,实现一个
composite manager,具体的做法就是windowmanager去调用composite extension来实现的
composite manager,这里有点拗口,不过就是这样的。他会把window redirect到pixmap去。
函数是在libxcomposite里面提供的,请求时发送到xserver的。所有的实际处理都是xserver处理
外面只是简单调用一个api而已。这里所有window的操作都被“翻译”成了pixmap的请求。
createwindow实际上是变成了createpixmap。这里再xserver里面可以给每个screen注册createwindow
的回调,这个时候变成了pixmap。也就是上层的应用实际上没有任何改变,但是实际上底下的东西是变化的
这个东西画好了之后windowmanager要负责把每个该显示的部分显示到屏幕上面去。大家可以简单
看看metacity的里面XrenderComposite调用的地方,这个就是了。我们要把window composite到
rootwindow上面去。

那么这里和exa有什么关系呢?exa可以注册CreatePixmap的callback。简单描述一下调用如下
应用调用了Xcreatewindow,这个是libx11的函数,然后请求走socket到了xserver,xserver这边
由于metacity(window manager)做了composite的请求,这个请求变成了CreatePixmap,然后这个
请求被exa给注册了callback,也就是说调用到驱动的exa里面的CreatePixmap了。这样就从显存
里面分配了一个pixmap了。这样的好处是什么呢?

exa加速的时候首先要判断一下,这个被计算的src和dst是否在显存里面,如果本身就在显存里面
那么我们就开始计算了,否则我们要先拿到显存里面去,然后再计算。所以如果我们所有的东西如果
都是分配在显存里面的话,倒腾数据就少了。

不过这里要说一下,注册了这个回调之后,默认我们是从显存里面分配,对于pc来说显存稍稍大一些。
这个机制是可以的。但是对于嵌入式来说,默认从显存里面分配,很快就用光的。所以
默认从什么地方分配的是讲决策的,如果没有的话,默认是从内存里面分配,计算的时候放到显存。
也就是说看我们让大多数的buffer默认在什么地方,如果显存极小,我们默认就放在内存里面,保证
显存够计算我们足够大的window,缺点是我们每个buffer都是要倒到显存里面才能计算的。
如果显存够大,我们默认就放在显存里面,减少数据倒腾。但是如果估计失误,我们可能就很多时间在把
显存里面的东西往内存里面倒。

上面不知道说明白没有。
然后就是xgl,这里会什么要提是因为这个技术本身来说还可以吧,但是novel/suse不够google那么
有钱来支持这个项目。
简单说一下吧
xgl这个实际用的是render to texture (不过有可能我也理解错误的)
另外大家并不太看好用opengl来加速2D的操作,一个是本身这个不合适。另外一个就是gpu有很多计算
没法完成。不够cpu灵活,还有就是显存本来就小,跑游戏还不一定够呢,还要把2D的东西放到texture里面
底下都是用glitz来做绘图的,再底下就是opengl了,这个xgl并不是构建在opengl之上的,
因为opengl本身是依赖xserver/glx的,所以两个本身是杂合在一起的。
关于依赖的扩展,有一个比较重要的就是opengl需要提供texture_from_pixmap,如果没记错的话。
因为之前我们分配buffer是pixmap的,这个东西如果直接分配在显存里面,然后texture_from_pixmap
的时候就简单了,和EGL_KHR的扩展差不多,这个地方极其有用,我们不用再texture2D了。
本质在于数据传输量太大,纹理太多。反复倒腾的时间已经抵消了gpu的计算性能提高了。

关于dri的解释。

dri这个是开源社区设计的一个框架了,做3D加速用的框架,但是实际上,私有的驱动,pc的比如
nvidia,嵌入式的私有的驱动就更多了,基本都不遵循dri的框架。目前看到只有高通的是dri的。
这里简单说一下dri和dri2的区别。
从应用来说的话,最大的区别应该说是dri2可以render to pixmap。
这个的好处主要就是composite manager打开的时候我们也能正常的看到opengl的程序的输出,


关于EGL
是一个工业标注,之前的文章有简单提到。这个会提供一个标准的接口给上面的应用。
可以理解为是一个中间层。简单的流程如下
eglcreateContext
eglcreateWindowSurface
eglmakecurrent
然后我们就可以用opengles的api往这个surface绘图了,
eglswapbuffers
输出我们所绘图的图像。

EGL下面要显示出来肯定是要和本地的图形系统相关的。最简单的就是fbdev的情况。直接全屏输出到
framebuffer上面了。android就是这样的。本地的图形系统是会影响到EGL的实现的,EGL的实现
必须知道底下的windowing system,native window。android的比较简单一点,只支持565.
所以egl也只需要支持565就可以了。另外android的EGL要求支持swaprect,也就是指刷新一小块
不要全屏幕刷新

如果下面是xserver的话,因为xserver是支持多window的,所以就复杂一些,egl是必须知道window
的状态的。比如只渲染到某个window区域的某个剪切域。还有就是xserver本身基本支持所有的
pixelformat,所以egl这边也要支持了,否则createwindow的时候就会出问题了,createpixmapsurface也一样
所以以xwindow为native的EGL会比以framebuffer的要复杂的多了。

必须为不同的window系统开发不同的EGL版本,不过一般来说,大家会开发一个LIBEGL.SO
然后下面动态的去装载其他的so,比如egl_subfb.so,egl_subx11.so大概名字是类似这样了,
有点记不住了。


关于软3D和硬3D
最常见的软3D就是mesa了。mesa已经迁移到了gallium了。
mesa是opengl的软实现,好久没看了,可能支持openvg和gles也说不定
android自带的有一个软3D的opengles 1.x的版本。

所谓软3D,就是用cpu去算的
所有opengl的算法都用cpu来计算的。这个极慢。

硬3D就是厂家提供的,对应特定的gpu的了,
比如opengles的一般会提供
libegl13.so,opengles20.so,opengles11.so openvg11.so ,xxx_dri.so
名字凭记忆写的,大概就是这些了。

opengl的比如nvidia的,
libglx.so, libGL.so,等等。

以opengles为例来说明。
这里不带xorg的,他们直接会打开设备文件,比如/dev/hw3d等等,
用户空间直接往里面写东西了。opengles的实现里面会去和硬件打交道。

关于3D的xorg的框架,记得有4篇比较好的文章,都是洋人的文章了,他们的确是走在我们前面很多

算了,还是找个中文的给大家吧

这个也可以了。

http://dri.freedesktop.org/wiki/Documentation

抱歉,老文章实在不太好找了。先就这样吧。

如果大家想要实现私有的gl,不使用dri的话,dri也是非常值得参考的。


exa加速的操作主要有,composite,copy, solid, uploadtoscreen,downloadfromscreen
这些接口大家都可以在exa.h(没记错的话),我现在翻不了代码。

composite就是两个buffer的composite运算,至于什么是composite。wikipedia上面有解释
copy,就是copy操作了,这个时候是有运算的。mask等等
solid是填充,同上,也是有运算的,不是单纯的填充。
其他就是数据传输了,exa后来增加了一些接口。


关于XFT
下面用了fontconfig和freetype,所以只要用了xft的库的,都是支持这些的。pango也是其中之一
pango有很多后端xft是其中一个。

关于CTL
qt和gtk用的是最广泛的toolkit了。
CTL部分的代码都是来自于最早的freetype,后来各自发展,后来两大社区又谋划再回到一起
这个就是halfbuzz,不知道我写错没有,这个是国际化必须的,比如我们要横排,竖排,
还有就是一些很特殊的字符的现实,几个字符在一起的时候会要求按照规则组合成另外一个字符
这个是语法规则,这些东西有些在ttf里面是要规定的,比如GSUB,GPOS等等信息。

感觉应该说的比较清楚了吧


好,关于留言的回复
1:为什么要offscreen
这个比较容易理解,好比问,为什么opengl要支持doublebuffer一样。我们要先离屏画好了之后
然后搬运到屏幕上面,这样我们就不会看到绘图的过程,否则系统慢的时候我们会看到这个绘图的过程
比如一个绘图过程很复杂,我们又没有double buffer的话我们就会看到这个图形是怎么绘制出来的,
pipe line的过程我们都要看到了。

2:为什么我们不直接画到屏幕上面去
这个可以参考为什么不用overlay。是一样的问题,我们必须只显示我们该看到的区域。
overlay的机制是这样的,我们使用overlay的输出的时候硬件会直接输出到屏幕上面指定的区域
而不管这个地方有没有东西,一个简单的例子,比如我们使用overlay来播放视频的时候,这个时候
系统弹出一个警告框,需要在最前面显示,但是overlay的画面并不知道下面有什么,这个时候overlay
会盖住它。

android是如何使用这两个buffer的,这里简单描述一下应该就比较清楚了。
android要求framebuffer支持flip也就是至少提供两个page,这里一个page作为了frontbuffer
一个page作为了backbuffer。当egl绘图的时候都是在backbuffer里面绘制的,等绘制完了之后
告诉hardware模块说,请切换一下buffer,也就是fb_post,这里默认情况下只要调用一个ioctl
就可以了,然后kernel里面的驱动会把这个backbuffer给作为输出屏幕,从这里搬运数据到lcd上面
注意这里并没有发生数据搬运,可以理解为只是lcdc取数据的地址变了,当然不同的硬件是处理不一样的。

这里大家可能会问到Vsync的问题
这个文章可以解释大家的疑问,还有为什么需要tripple buffer



3:有硬件加速的2D的模块,要如何开发xorg的驱动。
个人看法,需要做如下的一些操作
a)如果要规范的话,需要做一个exa的驱动,可以参考其他嵌入式的exa的驱动。一般写的比较简单。
不要看pc显卡的exa的驱动。推荐omap的 ,高通的,还有另外一家是哪家忘记了。都是开源的
b)最主要的问题是显存管理的问题(因为你们xorg已经可以启动)
当exa判断pixmap或者window不在显存里面时候需要倒腾到显存里面,这个时候需要先用平台相关的
接口申请一下显存,放到里面,然后计算,如果有必要计算完了之后再倒出来(说的是显存很小的情况)
倒到dst的buffer里面,如果能够所有的buffer都分配在显存里面自然好。
还要做显存的swap的操作,显存不够的时候把存在显存里面的数据倒出来放到内存里面,
这个地方有一个问题是exa目前是通过偏移地址来判断是否在显存里面的,但是像你们的状况肯定是不行
所以要实现exapixmapisoffscreen?我记得好像是有这个函数。可参考intel的驱动实现。
屏幕如果小的话,实际感觉没什么用。还有就是本身有些2D芯片很弱,能够想象到的,说是支持2D
加速,但是支持的限制很大,比如copy,但是实际上xorg的copy过程中是每个像素都有运算的,可能是
mask,可能是or运算,等等。并非单纯的copy操作,所以需要判断满足硬件配置的时候才可以使用硬件
加速,但是这个判断本身是需要时间的,被hit的概率太小的话,实际上比不做硬件加速还要慢。
因为如果不支持,会返回fallback用软件的实现。




本文完毕



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

chinaunix网友2010-12-14 12:05:38

看到了什么是高手, 牛!

ailantian2010-08-04 19:28:43

Qualcomm xorg driver https://www.codeaurora.org/gitweb/quic/xwin/ others(在我之前的文章已经提到) 下面是老地址,新版本改动可能比较多,请大家自己找一下 http://repository.maemo.org/pool/maemo5.0alpha/free/x/xserver-xorg-video-fbdev/ git://git.openmoko.org/git/xf86-video-glamo http://cgit.pingu.fi/xf86-video-omapfb/tree/?h=master

瑜静俭2010-08-01 01:00:59

很牢骚的说句,鄙视intel,不是技术上鄙视,大企业的通病在它身上也有,给人希望的同时,回头等待的只有一头凉水,meego,2年以后吧(directfb还没做好的intel!) 关于我的问题,我觉得有必要再解释一下,我的意思是,fb0这个设备文件其实只用有1屏就好啦,对于图形的操作,做出要求,对于解码的结果,都必须放到显存里,不就可以了?这样为什么不行呢?否则的话从设计上来说,多少个offscreen都有可能是不够用的(如果像我们那样做,全部应用数据都搞预加载,并且生存周期为整个板载的加电过程)。如果考虑到交换(于kernel管理的内存进行数据交换),是不可避免的,这个offscreen的设计在我看来也是多余的呀,为什么还会出现这种设计?

瑜静俭2010-08-01 00:43:59

拼音打字,上面的错别字有些,汗! 另上面写的内存管理,不是C99,应该是C库GLIBC或者是UCLIBC,脑袋有点短路只想说明这些操作是非标的,这里不能编辑留言。 另,这有一份个人觉得非常好的 x 的架构图,写在楼主的BLOG 上吧 http://stashbox.org/122385/xorg%20architecture2.pdf 希望能跟博主一样,分享自己的研究结果。

瑜静俭2010-08-01 00:30:11

另外就是,在学些framebuffer的过程中,发现了fb0这个设备确实有2倍的分辨率和颜色模式下来的大小,看了您的解释才指导这叫 offscreen 的设计。 按照您的理解 为什么要出现这个 offscreen 的设计呢?为什么选择 整个屏幕的2倍大小作为设计的原则呢?之前我们对 linux 设计还不熟悉的时候,我们也自己做了很多设计,我们将应用的数据,通过一种方式,我们称之为预加载(实际就是将解码后的数据放到显存中),来解决这种问题,这样同样是在显存中,数据的搬运和操作就可以很搞笑,但对应的问题是,应用复杂的情况下,所需要进行预加载的显存则需要非常多(最高的时候我们用到,单个显示应用需要80M显存,甚至更多),那么对于 frame buffer 的设计来说,offscreen 的设计只有1个屏幕这么大,这是什么设计原则?