6,render的一些概念和可用库
一,概念解释
什么是渲染?这是高大上的说法,翻译成正常语言,就是把图像缓冲区的数据显示到屏幕的过程,就是渲染。
原理说白了很简单,但实际操作中有太多因素需要考量。
OS/硬件提供的加速机制/解码后图像数据格式/字幕数据的格式。。。。
刚开始查找资料时,我总是试图找到所有的渲染方式,后来发现这实在错的比较离谱。因为说到底,这是一个图形学的问题:如何在计算机屏幕上绘图。不同的图形库有不同的绘图接口,太多的厂商有自己的图形库,根本不可能穷举出所有的图形库。我们只能讨论一些相对主流的方式。另外去找所有的图形渲染方式也是没有意义的,因为他们的理念大体上又是差不多的,只是API不同。唯一的要求是,你要画的足够快,因为如果你想一张张图像看起来是连续的,那么速度要达到24帧以上。当然,对于一些特殊应用,比如视频会议,15帧的速度不会让人有卡顿感,这个帧数也完全Ok。
二,问题的概念空间与一些解决方案
说完了,回到开始的问题,如何渲染。
这里又有两个问题需要解释:
1.图像缓冲区里面的数据是什么样的?RGB还是YUV,又是哪种RGB,哪种YUV?
2.如何把缓冲区的数据搬到屏幕?CPU,普通的2D加速,还是GPU,用GPU时,是OpenGL还是D3D?
第一个问题:
这里我们只说几个常见的。这里的图像缓冲区,特指解码后的数据,而非对应屏幕显示的那块。因为对于目前的真彩色显示器来说,屏幕对应的数据只有一种,就是RGB888。无论你给到的数据如何,传输到屏幕点亮色点的数据都会被驱动/硬件/总线给处理成这种格式。这是由屏幕的物理属性决定的,物理屏幕就是TTL电路点亮的一堆小灯。
常见的有RGB888/RGB565/YV12/I420p。
ps:实际解码器出来的都是YUV数据,如果得到RGB数据,通常也都是解码器后面加了一步YUV2RGB的转换,不过通常我们也会把这块功能算成是解码器的。不过不绝对,需要看lib的作者如何看待这个问题。
第二个问题:
1.纯粹的CPU(现在貌似很少有这种了),就是一个一个的往屏幕上画点了,一个pixel一个pixel的画,不太常见,也比较慢,因为操作内存太过频繁。有些库封装了overlay/bitblt等操作,虽然看起来像CPU在做,实际上已经调用了2D加速了。
2.用2D加速的
Overlay
以前看资料,老看到Overlay什么的东东,找了很久,似乎也没有谁专门给出一个标准定义,说什么才叫Overlay。说下我的理解,Overlay通常是一个硬件意义上的名词,因为屏幕上的东西,通常有很多层次,Overlay可以做的就是直接把这层放到所有图层上面。通常的用法是YUV数据直接给屏幕,Overlay硬件会替你做YUV2RGB转换。这个词貌似来自ms的directshow,有什么主表面,离屏表面,overlay之分,实际上就是硬件图层的意思。貌似有些硬件可以支持RGB Overlay,很少见。有些图形硬件可以支持多个Overlay图层,也就是说,你可以使用Overlay同时在屏幕上显示几个不同的视频。视频监控的宫格多半就是这样来的。
嵌入式里面,Overlay还有一种常见做法,比如:一些有很高优先级的提示,要给用户,这时就得把普通的提示框做成YUV的,然后提示显示出来,可以直接盖到所有的图层上去。
关于模拟Overlay,呵呵,凌乱了吧,实际上就是接口叫xxxOverlay,实际上是把YUV转成RGB,然后画点的方式显示,SDL中有这种接口。
最常见的Overlay类型是YV12,一是数据量小,二视频压缩的标准有关,因为Mpeg2/h264等标准,都强制要求这种格式,当然这两点是相符相成的。
优点就是快,缺点也比较明显,如果要做视频图像后处理,比如放大缩小,人脸识别等操作,会比较麻烦。
Bitblt
比较常见的2d加速方式,把内存数据的数据直接传输到屏幕,或者搬到另一块内存中(内存拷贝)。
blit是个有渊源的词语,这个词的本意就是块(block)移动(transfer)的缩写blt,因为这个缩写缺少元音不好读,所以后来加上了i,就变成blit。
实际上我搞不清这和DMA有什么区别,希望有人指点一下区别。难道区别仅仅是BitBlt可以同时缩放/旋转,而DMA不能?
另外与Android提出的CopyBit有区别么?我看没啥区别啊。
优点是在内存拷贝时,可以同时做缩放/旋转,缺点是只能用RGB格式。
(2014.03.30更新:
1.查了一些资料,看了一下bitblt实现原理,除去缩放/旋转的算法之外,涉及到内存搬移的应该是调用memcpy实现的,从这个角度来看,是用到了dma功能的,看来是没有什么区别的。只是memcpy的实现通常是考验硬件性能和程序员水平的地方。
2.从copybit规定的interface来看,实际就是bitblt,估计只是bitlt这个单词是ms提出的,google觉得不爽,起个新名子而已。
实际android到了4.0之后,已经取消掉了copybit HAL module,2d加速全部采用了GPU操作。在android 2.3代码里还残存着一些痕迹。)
3.GPU
其实OpenGL和D3D就是GPU在软件接口层面上的抽象。用opengl和d3d显示视频通常都是用texture方式来实现的,把一帧一帧图像生成纹理数据,然后贴到vertex上去。
简单解释一下就是,先建立顶点坐标,再建立纹理坐标,再把顶点坐标与纹理坐标一一映射,完成贴图。具体的要看一下OpenGL编程书籍了,这实在是一个复杂的题目。
先把屏幕四个点当成两个三角形(因为3d api用三角形来表示平面,当然多边形也支持,但遇到不支持的情况,用两个三角形就可以组成一个矩形),把数据的一个点一个点对应到这个矩形上,就显示了一帧。因为GPU通常是并行操作,像素生成率通常也足够高。
这块了解不够多。不多说了。
三,常见的库
这个通常又与OS有关系了,讨厌死了。
先说Windows,又分几个层次。先从底层说起。
纯api就是
Windows GDI,windows平台对图形硬件的抽象,很多年了,比较成熟,效率应该比较OK。
DirectDraw,这个封装的就是Overlay的操作接口,但是微软已经停止支持了,不建议使用。
D3D,微软的3D API,门槛比较高一些。
Direct2D,层级和GDI貌似差不多,Win7时代出现新玩意,看过一些资料,说这套API是取代GDI的,不过貌似微软已经尾大不调了。
上述几个API,VLC播放器里面都有一些具体的实现,可以看一下下。
另外就是DirectShow中的filter级别的。
VMR7,底层用DirectDraw封装的,资料说只有XP好用,更老更新的平台都不支持。
VMR9,底层用D3D实现,还在支持。
EVR,vista时代出现的东西,好像也是D3D做的(微软你到底要闹哪样。。。。这么多选择)
其实dshow还有什么overlay mixer,video render之类的filter,我觉得都没有跑出我上面说的范围。
说Linux吧。
X-window的api算一种,虽然一直用X,但对X的超多bug也很不满,从来没看过。。。(吐血)
DirectFB,通常在嵌入式平台才会使用,桌面平台上极少见到,抽象了几乎所有的2D加速机制,接口操作和DirectDraw几乎一模一样。
直接用FrameBuffer提供的接口,嵌入式多见,不过通常这些接口里面已经封装了Overlay/BitBlt接口,不要只见树木不见森林就好。
跨平台的
SDL,算是比较常用的,API的使用还比较简单,但是看代码真心觉得太乱了,不过人家是跨平台的,代码乱真心是难以避免。
最后有个比较惨痛的事实,因为你在写播放器时,这些API可能都没用,因为。。。。。你的图形库会再给你提供一套。。。。好吧,懂得原理,很多事情会简单一些。
6,render的一些概念和可用库的更多相关文章
- linux下一些可用库
1. musl: 为了夸平台,采用小巧玲珑的libc进行静态编译.
- C++面试基础概念之动态库篇
编写DLL所学所思(1)——导出函数 编写DLL所学所思(2)——导出类 C++ DLL导出类 知识大全 C++类库开发详解
- jQuery学习笔记之概念(1)
jQuery学习笔记之概念(1) ----------------------学习目录-------------------- 1.概念 2.特点 3.选择器 4.DOM操作 5.事件 6.jQuer ...
- 最新的jQuery插件和JavaScript库
每一个前端开发人员很清楚的重要性和功能的JavaScript库提供.它提供了一个简单的接口,用于构建快速动态的接口,而无需大量的代码. 谢谢你的超级从事jQuery开发者社区,人始终是创造新的和令人惊 ...
- c++标准库
Technical Report 1不是正式的库只是一个草案,作为C++ 2003标准的附加库被大多数编译器厂商所支持,它是个过渡性质的库,其实现将会作为C++11标准的一部分.很多编译器对C++11 ...
- linux库
将库函数打包成一个单元使之能够在运行时被多个进程共享的技术,这种技术能够节省磁盘空间和RAM. 一. 静态库:1.概念: 静态库就是一些目标文件的集合,以.a结尾.静态库在程序链接的时候使用, ...
- boost库的安装,使用,介绍,库分类
1)首先去官网下载boost源码安装包:http://www.boost.org/ 选择下载对应的boost源码包.本次下载使用的是 boost_1_60_0.tar.gz (2)解压文件:tar - ...
- Linux 静态库与共享库的使用
申明: 正如题如示,本篇讲的是Linux下是静态库与共享库,而Window下的动态链接库详细情况可见这篇文章:windows动态链接库 DLL 浅析.虽然原理,思想差不多,但是细节却各有不同. 一.静 ...
- 在linux下制作静态库和动态链接库的方法
静态库 .o文件的集合 制作 ar -cr libxxx.a xxx1.o xxx2.o xxx3.o ... 编译 gcc main.c -l xxx [-L 库路径] (如果不加-L则在标准库路径 ...
随机推荐
- 4柱汉诺塔(zz)
多柱汉诺塔可以用Frame–Stewart算法来解决. The Frame–Stewart algorithm, giving a presumably optimal solution for fo ...
- UNIX线程之间的关系
我们在一个线程中经常会创建另外的新线程,如果主线程退出,会不会影响它所创建的新线程呢?下面就来讨论一下. 1. 主线程等待新线程先结束退出,主线程后退出.正常执行. 示例代码: #include & ...
- XML序列化/反序列化数据库形式保存和读取。
直接上码: 首先创建class1类 public class Class1 { public string name { get; set; } public int age { get; set; ...
- C#测量程序运行时间及cpu使用时间
转载:http://www.cnblogs.com/yanpeng/archive/2008/10/15/1943369.html 对一个服务器程序想统计每秒可以处理多少数据包,要如何做?答案是用处理 ...
- import com.sun.image.codec.jpeg.JPEGCodec不通过 Eclipse找不到包
Eclipse默认把这些受访问限制的API设成了ERROR.只要把Windows-Preferences-Java-Complicer-Errors/Warnings里面的Deprecated and ...
- JavaWeb_Day10_学习笔记1_response(3、4、5、6、7、8、9)发送状态码、响应、重定向、定时刷新、禁用浏览器缓存、响应字节数据、快捷重定向方法、完成防盗链
今天学习重点: 1.response和request响应和应答分别学习: 请求响应流程图 response 1 response概述 response是Servlet.service方法 ...
- HTML解析引擎:Jumony
Jumony Core首先提供了一个近乎完美的HTML解析引擎,其解析结果无限逼近浏览器的解析结果.不论是无结束标签的元素,可选结束标签的元素,或是标记属性,或是CSS选择器和样式,一切合法的,不合法 ...
- swing容器继承重绘问题解决
swing容器继承重绘问题解决 以JPanel为例,继承JPanel,想动态为器更换背景,这就涉及到重绘问题.一下是本人重写代码: package ui; import java.awt.Grap ...
- 上传代码到cocoapod ,自己的框架提供给开发者使用
1.注册trunk 1 $sudo gem install cocoapods 1 pod trunk register 382782411@qq.com 'Henry519' --verbose ...
- 代码:Masonry 第三方框架
必备宏使用前提: //define this constant if you want to use Masonry without the 'mas_' prefix #define MAS_SHO ...