第十七篇:使用窗口的cache属性加速SOUI的渲染
内容渲染速度是决定一个UI成败的关键。无论UI做得多华丽,没有速度都没有意义。
在MFC,WTL等开发框架下,每个控件都是一个窗口,窗口只需要画前景,背景。因为窗口之间的内容不需要做混合,一个子窗口的一次刷新只涉及该窗口本身,和其它窗口无关,因此这样效率很高。但是美中不足在于,窗口之间内容是孤立的,要想不同窗口之间的内容更协调,对美术有很高的要求,同时也基本只能适应个别窗口大小相对固定的场景。
要使UI更加漂亮,最简单有效的方法就是采用alpha混合的方式将各层的窗口相互混合,这样窗口之间没有了边界的感觉,从而使得UI更像一个整体,这也是现代UI的主要实现方式。
想像一下,如果一个最上层的子窗口内容发生了变化,UI系统如何把窗口内容绘制出来呢?
首先需要通知UI系统的渲染对象说我的窗口显示区域内容发生了变化,请求重绘。
UI系统拿到渲染对象后,对渲染范围设定剪裁区(clip),防止刷新那些不需要重绘的区域。
UI系统从最顶层的窗口开始依次绘制每一层的和剪裁区重叠的窗口的内容(不同窗口之间绘制内容的混合由绘制方法定义,例如图片可能是利用alpha通道)。
为了防止绘制过程中出现闪烁,一般上面绘制都是在一个内存绘图设备(如内存DC)上进行。在全部绘制完成后,将绘制内容再呈现到屏幕。
那么问题来了:一般子窗口会比父窗口小,子窗口请求重绘时,要执行父窗口的绘制函数,如果父窗口没有根据当前的剪裁范围来确定自己的绘制范围,那么尽管有剪裁区限制了不会绘制超出边界,在实际执行过程中,超出剪裁区的绘制行为也可能极大的影响UI的性能。
如何解决这个问题呢?
解决的方法可以有很多,比如在每个窗口的绘制方法都实现只绘制在剪裁区的那部分(实际上实现起来非常麻烦,附加的剪裁区计算也可能成为新的绘制瓶颈);又比如每个窗口都保留背景窗口的内容,当窗口需要刷新时,直接直接把背景内容拿过来在上面画。
第二种方法看起来效率是最高的,但是实际上可能并不高:虽然在绘制自己的内容时速度快了,问题是自己更新以后,还需要同时更新它的上层窗口的缓存,可能导致内存开销大,效率也不高。
在SOUI中,我们采用了第三种方法:给窗口加一个cache属性。
当cache=0时,窗口的绘制和前面提到的流程一样,只是如果窗口比较大,而需要一时半会的区域比较小时,速度慢一点。
如果cache=1,则窗口绘制的内容会被保存到一张缓存位图上,当其它窗口刷新并导致该窗口重绘时,直接从缓存中复制出来就可以了。
假定一个窗口使用一张小图片进行九宫格拉伸绘制出来,绘制整个窗口由于拉伸中的插值等一系列的计算,绘制可能需要消耗大量的CPU时间,而有了缓存以后,只在第一次绘制的时候使用图片绘制方法进行绘制,其它时间都是直接从缓存复制,效率能够极大的提高。
很显然,cache属性在提高渲染效率的同时,也需要开辟一块缓存来保存绘制内容,也就是常见的空间换时间的方法。因此如果绘制本身速度就足够快,那么完全可以不使用缓存(比如给一个窗口填充一个纯色的矩形)。
总结:
cache可以提高绘制速度,但是是以更高的内存占用为代价的,应该只在需要的地方使用(例如顶层背景窗口)。
第十七篇:使用窗口的cache属性加速SOUI的渲染的更多相关文章
- 第六十七篇:Vue的计算属性
好家伙, 1.什么是计算属性? 首先它是一种属性,其次他有计算这个特殊的性质, 它是一个依赖于其他属性的属性,当依赖的属性发生变化的时候就会触发我们计算属性的逻辑 它会对这个属性进行计算, 所以说它是 ...
- Python之路【第十七篇】:Django之【进阶篇】
Python之路[第十七篇]:Django[进阶篇 ] Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接 ...
- Python之路【第十七篇】:Django【进阶篇】
Python之路[第十七篇]:Django[进阶篇 ] Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接 ...
- Python之路【第十七篇】:Django【进阶篇 】
Python之路[第十七篇]:Django[进阶篇 ] Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接 ...
- 第十六篇:SWindow的布局属性pos2type及offset
当窗口大小需要根据内容来确定时,使用XML布局可能需要做一些特殊的处理. 例如:不管窗口多大,我需要将该窗口相对于父窗口居中在XML中应该怎么处理? 如果窗口大小是固定的(如, 100 *100),这 ...
- 解剖SQLSERVER 第十七篇 使用 OrcaMDF Corruptor 故意损坏数据库(译)
解剖SQLSERVER 第十七篇 使用 OrcaMDF Corruptor 故意损坏数据库(译) http://improve.dk/corrupting-databases-purpose-usin ...
- Document对象关于窗口的一些属性
在网上搜罗的,只为自己查用方便,不做他用 window.screen.availWidth 返回当前屏幕宽度(空白空间) window.screen.availHeight 返回当前屏幕高度(空白空间 ...
- 第六篇 ANDROID窗口系统机制之显示机制
第六篇 ANDROID窗口系统机制之显示机制 ANDROID的显示系统是整个框架中最复杂的系统之一,涉及包括窗口管理服务.VIEW视图系统.SurfaceFlinger本地服务.硬件加速等.窗口管理服 ...
- 跟我学SpringCloud | 第十七篇:服务网关Zuul基于Apollo动态路由
目录 SpringCloud系列教程 | 第十七篇:服务网关Zuul基于Apollo动态路由 Apollo概述 Apollo相比于Spring Cloud Config优势 工程实战 示例代码 Spr ...
随机推荐
- Node.JS初识
对Node.JS的认识 1.Node 是一个服务器端 JavaScript 解释器: 2.Node 的目标是帮助程序员构建高度可伸缩的应用程序,编写能够处理数万条同时连接到一个物理机的连接代码.处理高 ...
- POJ 2352
---恢复内容开始--- http://poj.org/problem?id=2352 这是一个树状数组的题目,也是我第一次接触这类的题目,也正是因为之前的一道题,TLE了,超时太严重了,我看disc ...
- 深入理解 Win32 PE 文件格式
深入理解 Win32 PE 文件格式 Matt Pietrek 这篇文章假定你熟悉C++和Win32. 概述 理解可移植可执行文件格式(PE)可以更好地了解操作系统.如果你知道DLL和EXE中都有些什 ...
- Unity3D研究院之手游开发中所有特殊的文件夹(转)
这里列举出手游开发中用到了所有特殊文件夹. 1.Editor Editor文件夹可以在根目录下,也可以在子目录里,只要名子叫Editor就可以.比如目录:/xxx/xxx/Editor 和 /Edi ...
- solr单机环境配置并包含外部单机zookeeper
首先和之前一样下载solr-5.3.1.tgz,然后执行下面命令释放文件并放置在/usr/目录下: $ .tgz $ /usr/ $ cd /usr/solr- 这个时候先不用启动solr,因为单机模 ...
- Win7下打开计算机管理时出现错误的解决办法
计算机管理是用户在使用计算机时经常用到的一个选项,可以在桌面上右击计算机,选择"管理"打开.也可以在运行框中输入:compmgmt.msc打开计算机管理程序,里面有常用系统工具如用 ...
- 如何为自己的windows 8系统的电脑更换锁屏壁纸
现在的人都喜欢个性,今天教大家如何设置自己想要的锁屏壁纸 工具/原料 Windows 8系统的笔记本电脑 方法/步骤 将鼠标移到电脑的右下方,点击设置按钮进入设置页面 找到更改电脑设置并点击进 ...
- ABAP 单位转换函数
CALL FUNCTION 'UNIT_CONVERSION_SIMPLE' EXPORTING input = wa_all-btg ...
- mysql 删除重复数据保留只保留一条
SELECT * FROM (SELECT addTime FROM motorcade.car_msg_info GROUP BY addTime HAVING COUNT(addTime) > ...
- 【opencv】轮廓相关
IplImage* contours_rect; IplImage* contours; CvMemStorage* countours_storage=NULL; if(contours_rect= ...