在google+上看到的一篇不错的文章,考虑到国内网络状况,直接把关键部分搬过来了。原文请移步https://plus.google.com/communities/101300618741389614166
下面我直接拷贝过来了。
又到一年的年末,秉承传统,继续为这一年写一篇总结的文章。今年依旧延续了进入公司后每年都更换不同小组的传统,下半年调到了内核渲染组,不过之前在技术研究组的工作也一直是专注于浏览器渲染相关的技术研究,所以这次调动也算是顺理成章了,工作内容基本上没有任何变化。
今年一年以来的工作都跟硬件加速渲染有关,除了在不断完善和优化原有的硬件加速/图层混合加速的渲染架构,保证UC加速版的顺利发布外,另外最主要的工作就是设计和实现2D Canvas的加速渲染架构,从年初的初始实现版本到UC9.4加速版的版本,其间一共更替了三套不同的架构,而且每一次基本上都是完全推倒重来,但也解决了前一版本无法克服的一些内在缺陷,当前最新的架构基本上已经没有什么性能上明显的瓶颈,也足够灵活地根据不同的设备动态调整自己的行为,在兼容性,资源占用,性能这三者之间取得一个较好的平衡。 回顾自己这一年的收获,通过研究Android图形子系统的底层实现,研究GPU和其它各种硬件的工作原理,自己对渲染架构和性能的理解也越来越深刻。“物尽其用,要事优先”是自己对高性能渲染架构的总结,一个高性能的渲染架构,设计者需要对硬件有相当的认识,知道如何将一个完整的渲染任务合理地进行分解,然后调度不同的硬件尽可能并发地完成它;要了解哪里是性能的瓶颈,哪部分是关键的任务,要保证关键任务优先获得资源的分配,尽可能降低瓶颈的影响。 下半年开始,在和主管的工作总结中,还有职业等级评定的答辩会议上,都不断地被问到下面这两个问题,同时自己也在不断地进行思考。- 浏览器的渲染架构还有没有可能有更大的性能突破?
- 浏览器能不能够成为一个承载游戏运行的良好平台,使得H5游戏能够跟原生游戏在同一层面竞争?
- 为了保证渲染性能和效果,浏览器需要大量的图层缓存,尤其对于是一些图层非常复杂,数量非常多的网页,这个问题在移动设备上更加明显;
- 由于绘制仍然使用CPU,对于普通的网页,绘制任务主要由图片,文本,各种不同图形的填充(使用纯色,渐变或者纹理)组成,CPU在大部份情况下的确做的比GPU更好,而且资源消耗更少,另外也有助于让GPU更专注于混合任务;但是对一些复杂的动态特效,像是CSS Filter的使用,单纯靠CPU会很困难,并且这种先绘制再混合的方式对于这些动态特效来说反而会造成性能上的损失,并且需要更多缓存;
- Canvas元素只是网页中所有元素的其中一个,所以它的绘制必须先绘制到一个单独的缓存中,仍然再跟其它元素的图层缓存进行混合输出,这个会带来一些额外的开销,导致性能损耗。不过这个问题还好,对PC来说这个额外开销不算高,而移动设备GPU的性能也越来越好(不过分辨率飙升过快也是一个问题…)
- 2D Canvas只提供了最基础的绘图API,难以通过这些API高效实现各种复杂的特效,比如说要实现一个粒子效果,不得不调用几十次甚至上百次drawRect或者drawBitmap,这样的效率非常低。而WebGL还好,可以允许游戏自己直接控制Buffer,自己编写Shader实现各种特效,直接交由GPU运行,从这点看,长远来说WebGL对游戏还是更有前途一些,不过相对来说,它的开发难度就要高不少(即使是使用2D Canvas开发的游戏,很多游戏也会在一些静态不需要太高性能的场景改成使用CSS+DIV来降低开发难度);
- 无论是2D Canvas也好,WebGL也好,它们都只提供了绘图API,离一个完整的游戏引擎相去甚远,而要依靠JS实现一个高性能的大型游戏引擎(包括物理运动引擎等)用来支撑一个大型游戏,受限于JS本身的性能,并且缺少底层硬件的直接控制能力,这点不得不说是最大的困难;
- Chrome通过Native Client允许原生代码直接在浏览器提供的一个受限环境里面运行;
- Firefox通过ASM.js + WebGL的方式,遵循ASM.js语法的代码仍然是标准的JS代码,但是特殊的语法使得JS虚拟机可以直接将它们翻译成机器码,高效地运行;