主要描述了一下xorg的一些令我比较头痛的问题和一些感想。
1:单进程的设计
类似于以前的游戏,就是一个大循环while(1)
然后再进行处理。这里面每个操作都不能阻塞否则就会导致xorg挂起没有反应。
缺陷主要表现在,每个模块都必须是完全可靠的,所有的驱动,从kernel到上层输入输出,否则xorg整体就挂掉了
a)input处理
这里的问题从下往上来看,最下面是kernel的driver,也就是ldd,并不是每个人都能写好ldd,很多ldd写的有问题。
简单的例子,就是evdev的driver处理不符合规范,会导致上面的xserver无法处理,sigio处理不好就导致xorg进入无限循环
还有就是xserver自己的处理都是靠sigio来实现的,当底下设备比如鼠标有数据可以读的时候就会发sigio上来中断xserver
xserver是在信号处理程序里面来做所有的input操作的,也就是说实际上xserver的input的驱动都是在信号处理程序里面,
但是很多人不熟悉信号处理里面是有很多事情不能做的,内存管理等等,abort消息就会到来,xserver挂掉了。
也就是说从kernel里面到xserver里面任何一个地方都不能出问题,但是实际上,有些驱动有问题,可能在任何模块,比如dma模块,
出了问题之后上面的总线就会出问题,然后usb设备驱动就不正常,鼠标键盘,touchpad,touchscreen就出问题,xorg 挂起。
还有就是kernel的驱动开发不符合规范,比如Synaptics的驱动,有些做bsp的人员对上面的xserver并不太了解,做驱动的时候有些
想当然的按照低端的嵌入式来做的,自己定一套规范,这样上面是无法使用的。
b)graphic驱动。
凡是和硬件相关的都不太好处理,因为底下的驱动有问题的话,上面是很难发现错误的,比如一个ioctl就block到内核里面了,
简单的比如硬件解码或者一个hardware的blend,就导致硬件挂起。屏幕蓝屏或者屏幕不刷新了。我们没有办法可以交互。
还有就是有些设备并没有串口或者网络可以调试,嵌入式的驱动都是要自己写的了。不像pc这么成熟。
c)很老的设计
目前还有很多十几年前的代码,简单点说比如freetype相关的东西也都是7年前的了,现在没有人用,也没有人删除。
问题列表
1:为什么xorg不使用多线程来处理。
多线程的程序调试太麻烦了,而且目前的input框架,是靠sigio来驱动的,信号驱动的时候,就驱动来说,比如xf86-input-synaptics,里面绝大多数的代码
都是在信号处理程序里面执行的,所以请尽快处理,请不要分配内存,请不要block,请尽快返回。这样来说驱动是不能做的很复杂的。
2:为什么input不能单独拿出一个进程来处理
个人觉得input部分是可以拿出来作为一个进程来处理的。input部分是一个相对独立的系统,和其他部分的关联很小,目前看唯一关联的就是grab,
因为从xserver的设计来说grab的时候是和window关联的,但是window这个设计整个就不是现代化的。设备的grab感觉需要重新设计一下,目前grab比较乱。但是
input自己的处理是相对独立的,还有就是input的设计是一个全局的变量,xorg会要求必须有一个键盘一个鼠标处理的逻辑这个就是所谓的VCP/VCK
这个东西想抠出来比较麻烦。无处不在的使用这个全局变量input.info.xx
还有就是热插拔的处理,这个子模块也是使用全局变量来处理的,如果单独拿出来的话,input daemon里面要做处理,xserver里面也要做处理。
如果grab能够处理好的话,input daemon还是能够复用很多xserver的代码的。在input daemon和xserver之间可以使用一个虚拟的驱动,
比如vinput.so,编写的框架继承现有的input框架,然后从socket来获取input daemon的事件。这样需要新的x协议XinputDaeon event.使用evdev不太好。
3:Output部分是否可以单独拿出一个进程来处理。
这个有点麻烦,因为所有的drawable的申请可能还是需要在xserver里面处理的,因为兼容性的需要,为什么要兼容xserver,因为目前应用软件,
很多应用软件想要移植到别的图形系统工作量太大了,而且时间太长,简单点,比如说firefox如果想要移植到minigui并不太容易,首先想要看懂gecko的代码就不是
一件容易的事情。为什么不用gtk-directfb,同理,还是应用软件的问题,必须能够做到应用软件拿来就可以用,或者做简单的debug就可以使用。thunderbird要移植也
很不容易,我以前也不用thunderbird,但是后来有人发邮件总是说,请看红色的部分,但是sylpheed等等软件无法回复html邮件,
简单的要想composite html,目前没有gecko之外的选择,浏览器还可以选用webkit,但是webkit的gtk后端并不太稳定,简单的浏览国内的一些网站
就可以发现,好些网站都无法正常浏览,要么直接显示html代码,要么就是崩溃退出,而同样的页面用firefox或者gecko的其他浏览器就能够显示,
一句话,webkit的容错性不行,导致稳定性不行,而gecko太慢。
话说回来,如果output是一个单独的进程的问题,首先就是线路流程太长,以一个简单的调用来说,上层想用gtk来显示一张图片,这个过程我们看看
首先gdk模块把文件装载到内存,这个是从硬盘读取到应用程序的进程空间,在该应用程序的内存里面,然后显示的时候gtk会调用函数把这个图片
显示到图形系统上面,到xlib这一层的函数的时候一般都是调用xputimage,或者变种,比如Xshmputimage,Xvputimage,XvShmPutimage,类似
这样的函数。这样的函数的处理流程如下,xlib会把这个图片通过socket发送到xserver这边,如果是shm的则不用,但是普通情况下
都是走socket,本地的socket或者是tcp的远程socket。xlib把这个图片发送到xserver端的时候,xserver端再显示出去,如果没有硬件加速,就是直接搬运到framebuffer了
如果有硬件加速,就是要先搬到显存,然后再走驱动的加速显示出去。因为Putimage的时候是需要进行一些运算的,比如image可能是有背景的,或者说是有alpha值的
如果不是over操作的话,就需要计算了,这个时候最好是有gpu的加速,不然cpu是很慢的,所以说output如果作为一个单独的daemon来跑的话,
这样在xserver和output daemon之前是有很大量的数据操作的,那么说可以直接在xserver里面把请求转到output daemon,所有的drawble的分配
都在output daemon里面来做,这个也没错,但是xserver里面还要处理事件的,比如要计算鼠标到了哪个window之上,这个需要和output daemon通信。
实际上通信会非常多,当然不知道这里是否可以更好的协调这些之前的关系,就是xapp,xserver,outputdaemon。inputdaemon
4:xserver加速框架的问题
Xaa是老的加速框架,现在已经基本不用了,
KAA是kdrive的加速框架,kdrive之前本来是一个试验性的xserver也就是说是xserver的一种,xserver有多种,xorg,kdrive,xdmx,等等
EXA是xorg的KAA类比实现,
这些加速框都是分两边的,一个是xserver这边的框架实现(xorg/hw/xfree86/exa xorg/exa,一个是驱动这边的回调函数的实现(xf86-video-intel)。
至于xvideo或者xvmc等等,也一般就直接实现在这个graphic 驱动里面了,这个是2d的
上面说的都是2d的加速
xaa,kaa,exa都是2d的加速,包含一些最基本的加速,比如填充,填充又分多种了,但是就算是现代的gpu也不完全支持这些图形操作,还有就是
对不同的操作模式gpu的速度也有很大差别。比如composite操作,比如copy的操作。
对于每种操作,源和目的的格式可能不一样,比如RGB565,RGB888,这样也是xserver能支持各种不同pict的原因。
还有就是mask的处理。关于pixel的mask,这个目前看好像opengl里面没有对应的实现。只能mask掉某个通道,但是不能mask掉特定的某几个bit。
还有就是另外的一种opengl的mask,mask平面,和目前kaa加速机制上用不上,xserver最早的设计,图形操作是什么都做,但是gpu并不是什么运算
都能支持,简单点说gpu的特长是blend。像素运算。就目前的图形系统来说,虽然3d出来已经很多年,但是目前的图形系统实际上还是一个2D的系统
Xserver本身只设计成处理pixel的,像素操作的,比如简单的,不能处理矢量数据,没有任何浮点支持。image也都是像素的,虽然xvimage是可以缩放和旋转的,
但是这个本质上还是像素的处理。cairo是矢量的,cairo和xserver没有太直接的关系,cairo可以创建xlib的后端,surface创建xlibsurface就可以画到xwindow里面
了。但是也只是以xserver作为输出,现在字体基本上输出都是矢量的了,但是xserver是不支持矢量的,glyph的渲染目前有接口,但是实际上都没有加速的实现,
大家越来越倾向于所有的事情都在客户端做,比如图形渲染,效果直接在应用程序里面做好,xserver这边只管输出,或者只管clip。这样xserver的框架也就简单了。
还有自己的渲染,也都移动到客户端来实现了。目前基本都使用的是freetype,字体图形是在客户端这边生成完之后,到xserver那边显示的,但是这样也害死和有问题
就是cache的问题,如果所有的事情都在xserver这边做,xserver可以cache所有的客户端需求的字体,如果都在客户端做,每个客户端都需要cache自己的字体,而如果
这个程序是使用opengl的texture来渲染的,就会占用很多texuture,显存很快就不够用了。显存和内存之间倒腾数据是很废时间的。libxft也是在客户端生成字体,然后xserver
端显示的。
为什么我们不把所有的东西都用3D来做呢?或者说xgl,xegl为什么失败了。
这个之前也说过了,xegl失败应该说是一个必然,就不再说了,xegl是否适合于嵌入式,就像gallium3d一样,从嵌入式,然后再porting到desktop。
实际上我们一直有一个问题是回避不了的,就是2d和3D共存的问题,因为本质上我们的图形系统是一个2d的系统。但是我们又要支持3D.比如iphone也要支持游戏的。
如果人人都想直接输出到屏幕又不管别人,那样会是什么样子,屏幕就乱掉了,并且狂闪,每个人都在往同一个区域画自己的东西。 X on EGL.
实际上,所有的2d应用,都在一个3D应用里面,也就是说,只有3d的应用,所有的普通的xlib的应用,都发请求到xserver,而xserver自己是一个简单的EGl应用,
负责在3D的context里面来处理这些2D的绘图请求,关于clip,还是要靠glx。EGl库里面需要告诉opengl clip掉哪些区域,可惜的是,大家说,我们可以开放EGl的代码
但是opengl这部分不行,那还不如什么都他们实现。
为什么不能在gtk里面直接使用opengl来渲染,或者说使用opengl来加速gtk等等,
这个当然是可以的,只是大家讨论的结果是,opengl并不适合做gtk里面的各种加速的操作,opengl比较适合做3D?反正是后来没做。
字体渲染是很慢的,而且内存管理上问题很多。点阵字体基本只用户屏幕显示了,打印上还是矢量字体,而且目前基本都是freetype做的。
为什么我们不能做一个3D的widget?
目前是有的,就是clutter了,但是没法把所有的应用软件都porting到clutter上面。目前绝大多数的应用,可以说99.99999%都是其他的widget,
比如gtk,qt,wxwidget等等,要把这些都加速,还是只能在xserver里面做。我们应该是无法在xlib里面做的。xlib是在应用程序的空间,可以发请求到xserver
现在越来越多的程序依赖cairo了,任何能看到的高品质的输出现在基本上都依赖cairo了,但是cairo目前用的最多的还是xlib的surface,使用exa加速
如果没有exa的驱动,就加速不了,嵌入式上面要自己做还是很麻烦的事情。如果能够加速的操作太少,这些判断能否加速的操作所耗费的"时间比"就会上升,
这样会比不加速还慢。
使用opengl来直接做加速的各种显示很多。
1:首先一条就是texture大小的显示,我们使用render to texture的时候,texture不能太小,
比如firefox打开一个页面,里面有很多图片,这很常见,我们假定每个图片大小500kb,不算大,但是jpeg的放到内存里面之后可能会有10M大小,
当然图片可能更大,还有就是比如,我们使用20张图片,就是200M显存,这样嵌入式上面根本就是用不了了,就算pc,最近的pc有200M的也还不算
是太老的显卡。我们首先要把20张图片放到显存里面,还有就是这个surface也是要在texture上面的,也就是说我们把这20张图片渲染到一个texture上面去
因为我们要滚动啊,整个window或者说drawable或者pixmap都是在显存里面的,我们的显存根本放不下,嵌入式的显存32M差不多很大了。就涉及到texture拆分的
问题,这样复杂度就上来了。
2:context的限制,嵌入式能够支持的context太少,可能3个左右,或者更少,有些可以支持7到8个,不知道iphone是不是就是因为context太少才不支持多任务
实际上来说iphone的系统本来是多任务的,但是UI的application就不行了。当前只能跑一个,而且iphone的游戏都是全屏的,EGL on FB就是这样了。
不能创建window,只能是全屏的window,如果是EGL on X就可以是小的window了,clutter就有eglx的后端。而我们讨论的X ON EGL,是X ON EGL FB
而不是X on EGL on X
EGL是对上的一个接口,下面是有一个native的输出系统的,可以是framebuffer,这个是最基本的,一般提供的都是egl on framebuffer的。
下面也可以是xserver,也就是opengl render到x的一个window里面去。
context支持的越多,显存占用也越多,context切换也更慢。context越少,xegl的需求就越强烈。因为我们要用有限的context加速到所有的应用。
只有在xserver端使用一个context来加速众多xclient的应用了,所有的绘图请求发送到xserver这边,而xserver是一个3D的应用程序,就可以使用opengl的函数来加速
这些操作了。
所以如果在嵌入式上面,大多数应用使用gtk,而gtk下面现在是cairo,gtk的engine现在也换成了cairo,如果使用cairo-xlib,没有加速,慢,假矢量实现更慢
如果使用cairo-vg,因为每个用用至少要占用一个context,context又不够了,我们至少要跑个7,8个程序吧。cairo-gl,是依赖glx的,一般嵌入式无法使用opengl,
所以这个没法使用,cairo-glitz, glitz已经随着xgl死掉而死掉了。计算没有死掉,glitz也同样,context会不够用。目前使用cairo-glitz的也很少,cairo-gl的基本没有。
基本都是cairo-xlib,底下使用exa加速的,而没有exa,这些都白说。
glitz类比pixman,就是pixman的opengl实现,xorg把pixel的操作慢慢都拿到pixman里面做,所以xorg现在离不开pixman了,所以之前xgl也需要一个gtliz,
也就是pixman的替代品。
plugin framework.目前的插件实现基本都是so的形式,但是so形式的插件有一个重大缺陷就是,任何一个不好的so就会导致整个framework挂掉。
还有就是线程的支持,不同的so可能有些做了线程安全的处理,而有些没有,还有就是so出问题难于调试。用so的好处是,一个进程空间,资源共享容易,
通信容易,效率更高,window管理更为方便,不过是子窗口和父窗口的问题,layout也容易管理。还有一点就是xevent的处理很容易,因为就是一个本地应用。
但是如果做成多进程的插件,用一个单独的进程来画另外一个程序的window,这样实现是比较困难的,首先就是window mapping的问题,还有就是输入事件的获取
还有就是当主进程窗口被覆盖和最小化处理等等,总之交互的处理很不方便。说这个主要是flash.
flash真的这么烂吗?是的,flash问题很多。
1:cpu占用高,以adobe的arm的flash10实现来说,cpu占用很高,而国内的网站,比如sina,sohu等等,flash广告极多,多这还不要紧,多开几个tab页的时候
浏览器就反应不过来了。只靠cpu指令的优化性能提高有限,
2:国际化支持差,字体显示技术不行。
3:crashy,这个问题在pc上也很常见,经常导致浏览器挂起,(遇到的少的朋友是很少从开发者的角度去看这个问题)
4:内存占用高。
5: clip反应慢,残留。
还有其他一些问题。
x on egl fb的限制,最基本的显示还是opengl自己的限制。opengl并不是万能的,3D是他的强项,但是2D处理上面尤其是目前的2D设计
比如目前的2D的api,也就是上层Xlib提供的2D的API,并不是opengl能够完全做的了的。那么shader?但是shader做逻辑处理好像也不行。
还有就是扩展性的问题,x on egl只适合小系统,而框架并不适合xserver原始的设计,扩展性, flexible,比如opengl的实现,管理一个显卡,
一个输出设备,显存管理也依赖opengl,opengl的压力会很大。而且有些东西是实现不了的,比如多屏支持,多头支持,分布式渲染的支持,
分布式opengl的支持,就不行了。还有就是分辨率调整,外置接头的输出(HDMI等等),一句话,opengl如果做最底层的话带来了众多限制,
但是对于大多数人来说,也就是本机可以使用,所以x on egl fb可能还是有用的。
还有就是我们的显卡其实不够强大到所有的操作都交给它实现,偶尔我们运行一下3D游戏,这个显卡还够用,但是大量的GUI都靠它的时候,它就不行了。
xgl当时不行还有一个原因就是,很多人的显卡都是intel的集成的显卡,但是intel的opengl性能就是垃圾, intel显卡的出货量占到30%左右
虽然我们平常说的都是nvidia和ati/amd但是intel在显卡这里还是有很大份额的,以前好像一直是最大来。
显示的计算最早是在内存里面,现在也还是需要在内存里面,因为显存始终是比内存小很多,现在内存可以4G了,但是显存也就500M上下
内存是线性的,pixman可以很容易的计算,但是没有加速,opengl里面的显存我们是无法直接用cpu计算的,gpu不支持的计算我们就需要使用
cpu来计算,cpu是万能的,虽然很慢,耗电量很大,我们就要使用texture到显存了,这样性能影响很大,因为要flush整个pipeline。然后才读出来。
算完之后,在将来的某个时候他还要再回到显存里面去。执行gpu所支持的运算。内存可以扩展到无限大,但是显存就不行。我们需要不断的在显存和内存之间传递
数据。500M的显存并不那么大。那么说为什么不使用集成显卡,又回来了,intel的显卡性能差一个主要原因就是集成显卡,使用用内存做显存
因为内存带宽是一定的,我们平时访问数据也要使用内存带宽,显卡使用显存也要使用内存带宽,只能有一个人用,需要等待。而且还有就是集成显卡
内存也不是动态增长的,也就是说在bios里面就划定了某块区域是显卡使用的,系统启动之后看不到这个内存了。什么时候能够显卡cpu共用内存
而且带宽足够大,不用反复搬运,性能就会好很多了。
framebuffer抽象出一个线性的区域来说,对于计算会好很多。但是目前opengl这个东西分配来的内存是按照opengl开发者的策略从显存中挖了一块显存出来
我们是无法计算其地址的,也就是说我们实际上无法使用exa和fb的计算机制,kaa,exa的显存管理模型就是利用offscreen来加速的,
系统中的某块地址是online screen,某块地址是offscreen,使用offscreen的地址画这个东西,当然这里所说的onlinescreen和offscreen都是显存里面,
计算都是在offscreen里面算好的,然后显示到onlinescreen的。如果资料在内存,也就是我们说的主存,那么就需要先搬运到offscreen去计算。
当offscreen显存不够的时候就踢出一部分到内存里面去。
但是opengl是不进行这个管理的,只有用户知道这个东西什么时候改,比如创建texture失败的时候就知道该置换一部分显存出来了,但是显存总是太小,
我们总是在倒腾数据。
clutter是会自己拆分texture的。
egl on nvidia还是别指望了,pc上面肯定没戏。没人用。驱动这个东西如果没有项目驱动,光靠开源的热情是没用的,商家看到的是钱,如果
项目不能带来利益(包括声望)的话,是没动力的,还有很重要一点就是,专利保护越来越厉害,能不开源的东西最好不要开源,否则被别人专利打击
了就不好了。这也是为什么egl可以比较容易沟通,但是opengl就不行。drm可以公开,但是opengl还是不行。
硬件的限制太多,而cpu+主存+swap基本能力上说是无限的。
比如简单的硬件缩放,有些2D芯片只能缩放多少倍,有些是无级缩放,但是性能不行,cpu最通用,逻辑限制也最少,当然如果不考虑加速等等的话。
关于openvg。
openvg是比较接近2D的要求的,所以为什么不用EGL+openvg?
again,还是一样的限制,openvg的接口比opengles的接口要简单一些,
关于openvg的实现,有一些厂家是用opengles1.1来实现的,也就是说用固定流水线的opengl来实现的openvg。
也就是说使用的是3D的芯片,而3D的嵌入式芯片性能本来就很弱。
有些厂家的openvg的实现是单独的2D芯片,比如arm公司自己出的mali gpu,但是这样还是有一个问题就是
我们这里有了多个存储部件了,
1:openvg,2D的显存(hardware的2D芯片,不是3D芯片gles实现的openvg)
2:opengles 3D的显存
3:内存,也就是我们的主存了
4:硬盘(swap)
5:online ,offscreen部分的处理。
我们需要在上述几个部分反复的倒腾数据,芯片越多越复杂。
如果是openvg用opengles来实现的。
1:3D显存,我们走EGL的api可以在opengvg和opengles之间倒腾数据,希望它不会太慢
2:内存
3:硬盘(swap)
4:online,offscreen逻辑的处理。
嵌入式上面要极力避免使用swap,在pc上面硬盘虽然慢,但是硬盘的速度也还是有600M/S左右,
但是在嵌入式呢?如果是flash,很慢,如果是sd卡,更慢,如果是usb disk,看接口了,也不太快。
你很快就会发现,kswapd 的cpu跑到100%了,还有就是你的swap设备很快就坏掉了。
xserver的grab机制。
也有一些问题,就是有时候grab会造成屏幕锁住,比如鼠标可以移动,但是点击不了了。xserver的window管理都是靠window manager来实现的,
所以在输入password的时候可能会弹出其他的对话框,密码就会被别人看到了。
xserver的事件监听机制,某些快捷键被别人grab走了之后就无法监听到。
所以最好xserver还是input分开。
kms
之前的文章说过了,图形最好是在开机的时候就初始化好,这样xorg启动的时候不用再初始化一次。屏幕就不会闪了。
还有就是,屏幕相关的设置都拿到kernel里面去,这样xorg就不再需要root权限了,而xorg这个大家伙目前是需要root用户的。
xorg的目前是作为一个简单的应用程序来运行,或者是一个简单的opengl的应用程序。反正xorg里面的东西要尽量简单,
目前这些所有的重要的功能都在xorg里面实现,导致他太重要,一点错误也不能出,其中某一个功能出了问题都是致命性的,要么是crash,要么是hang。
一旦hang住,我们就没法交互了。网络?但是有些设备上面没有网络,或者网络很不稳定,比如3G,wifi也有时候不太稳定,usb dongle,驱动稳定性更差
Xorg目前引入了太多linux专有的东西,当然linux用的人多,开发的人也多,但是xorg这个大家伙,要删除几十年前的代码并不是一件容易的事情,而且
老的设计现在处处都制纣,想拿掉不容易,想加也不容易,加的话,各个模块都要加,否则一个单独的功能,比如单独的xorg的patch如果导致别的模块无法使用的话
是不会被接受的。比如hal,比如kms,比如udev,
纯软件的限制最少,所有的东西都在内存里面的计算模型最方便。cpu的计算最通用。
但是我们要的就是加速。
egl+opengl虽然opengl是最通用的加速方式,但是驱动和芯片开发商一般都要考虑directx的实现,虽然他们实现opengl的时候尽量少的和window sys相关。
但是想让他们开发egl+opengl就难了。一来用的人少。二来不能给厂商带来利益,这样开源的人开发的少,商业的开发的也少,开源社区想给nvidia这样的社区施加
压力是基本不可能的。他们只会按部就班的走,就像开源社区的人喜欢开发自己喜欢的东西,而不是大家所需要的东西一样。
没有商业公司的需求和支持,linux也无法走到今天。
开源的dri的框架为什么难于被支持,还是老话,越专有,越不容易被打击,反汇编有罪。而且工作量极大,特别是硬件相关的,而且是寄存器太多的
情况下。另外就是dri并不比私有的框架优秀多少,除非这个框架特别优秀。
Xorg现在是尾大不掉,linux应用也是,离不开这些widget,但是widget从最早的设计就严重一来window系统。
必须考虑fallback的情况。显卡不支持的东西太多了。看opengl像无所不能似的,实际上图形学比这个要广泛的多了。
Xorg是纯2D的像素处理的设计。
字体处理是图形系统很重要一块,性能也是,性能主要就是各种图形运算了,数据传输等等。
还有很重要一点就是交互了,GUI就是为交互而设计的,输出系统只是其中一部分,输入系统也是很重要一部分。
虽然这么多年过去,最重要的输入设备还是mouse, keyboard,touchpad,touchscreen,画板等等,但是比如多点触摸,鼠标手势,重力感应,图像识别(指纹等等)gps,camera等等,
慢慢也都进入寻常家庭了。
国际化,现在没有一个数字消费产品不支持国际化吧,这个包括字体显示(render,raster),排版(layout),缩放(scale),还有就是输入法了
笔画输入,手写输入,键盘基本输入,
dri还是非dri。
dri的性能会好,非dri的管理性更好,如果大家都是offscreen render的话,只需要一个display manager就行了。
为什么clutter不支持offscreen的stage。要显示出来还是要读出来,如果是render to texture,还是需要把这个texture搬运到屏幕上面。
需要一次额外的搬运,如果是dri,opengl知道自己什么时候该刷新屏幕,什么时候pipeline完毕了。直接blend到framebuffer上面。
我们只有一个framebuffer,所以才需要有人来管理这个事情,如果只有一个人往这里写,自然就没有问题了。其他的人都render to texture,或者render to pixmap
但是这样我们的理论还是2D的设计,最后blend到2D的framebuffer上面去。当然我们的硬件的确就是一块2D的屏幕。
关于硬件解码。
从硬盘上的文件,读取到内存里面,这个时候我们传递给硬件解码器,硬件解码器解码出来是frame,简单理解就是一个图片吧,这个图片我们直接在显存里面。
然后从显存搬运到framebuffer去,这样的搬运是比较少的。
另外一种,
从硬盘上的文件,读取到内存,写入到硬件解码器,解码到特定的存储空间,然后从特定的存储空间取出这个frame,到了内存,也就是解码完之后的frame,现在在内存里面
然后如果没有xv,我们就创建一个ximage,然后走socket,xputimage,传递到xserver的空间(还是在内存,不过在xserver的进程空间),然后xserver把这个搬运到offscreen的显存
然后从这里搬运到onlinescreen,
如果有xv,我们就创建一个xvimage,然后走socket,传递xserver的空间(还是在内存,不过在xserver的进程空间),然后xserver把这个搬运到offscreen的显存,然后走硬件加速
blend到onlinescreen的特定区域,blend的过程中可以缩放,可以旋转等等。
当然也可以支持shm。image的传输可以省掉,但是数据搬运还是存在。
所以最好硬件解码器解码完毕之后是在显存里面的。不用搬回到内存,然后再回到显存。当然解码器解码到显存,这块显存是预留的,需要使用专门的接口来获取这个地址,
显卡也能够通过这个地址来搬运到屏幕上面。
但是一般的arm+dsp的就不行了,dsp解码完之后都是片上内存,还要读出来。
mplayer还可以走opengl的输出,使用opengl的输出,可以使用gpu做缩放和filter,和其他的变换。1080p每一帧
1920×1080x16/8=3.955078125M(yuv422格式),还有就是解码前,解码后的数据都在显存里面的。
还有就是opengl不支持yuv,需要从yuv转成rgb才能够显示,还需要1920×1080x24/8=5.9326171875M(rgb888),如果有alpha就是32
在嵌入式的显卡里面pixel shader(fragment shader)现在好像只有一个?不确定,没有拿到什么数据,一般都只说支持opengles2.0。
而且性能不怎么样。所以做这个yuv转换性能可能也不太好,没专门测试过。
context太少,xv需要占用一个context来做shader。
Xorg的设计已经很老了,从各个方面来说。
暂时只想到这些,以后慢慢补充。
阅读(5901) | 评论(2) | 转发(1) |