RTGUI粗讲(个人见解篇之三、RTGUI WIDGET (3))

 

继续填坑。

这次讲下剪切域。

什么是剪切域呢?这是一个比较模糊的概念,并非什么专用名词,而是一个叫法而已,就算你去百度,也只会出来一些没多大用处的信息。我这么叫也是因为在0.3版本的rtt手册上介绍初版rtgui的时候用的这个叫法,所以我也就一直沿用了。具体是什么概念是可以不用理会的,真正要知道它是它的功能。剪切域的作用是通过判断最小刷新区域来实现控件有效显示区域的像素修改。这么说也许会觉得很拗口,不过应该不会离本来的意思差太多。什么是有效显示区域呢,就是指一个控件能真正显示的区域。这个也许会有人疑惑,因为一个控件从创建开始它的大小一位置就是确定的了,那它的刷新区域就是那个大小了。但是如果考虑到一种情况,就是在这个控件的上面覆盖着另一个控件呢?这时候就不能简单的整个刷新显示了,因为这样必然会把上面的那一个控件显示覆盖掉,因此在刷新的时候判断当前刷新的部分是否有上层控件覆盖着,但是作为一个gui,把大部分工作做好是基本要求,而对于用户,却是很少需要去管这些的,当然,你也能去研究下。

Widget的结构体里面保存着覆盖它的剪切域信息,而这些信息就保存在rtgui_region_t clip 这个属性里面,当然,它也是一个链表(你会发现rtgui里面很多的结构都是链表,而且我自己编程也很喜欢用链表,这是因为它可扩展性好,个人觉得对于嵌入式,比较重要的仍然是数据处理,其中包括了数据存放,也就是数据结构,而与之相比,硬件进来的只是01010101之类的编码,反而不需要关注那么多,而且那么多功能,其实也不就是处理数据做出来的吗)。剪切域信息的更新修改发生在控件创建,依赖于现有控件(也就是说,越先创建的控件越上层,那么后面新增加的控件就会可能给它覆盖,此外,当发生任何控件隐藏、显示的时候,也会更新信息,这样才能保证显示结果正确),运算模式也简单,通过对比各自的位置大小,然后求出被覆盖的区域,同时这个区域再与现有的区域比较,看是否重复了,如果重复就会将它合并,不重复就保存这个区域到链表中,这样有助于减少判断次数。当然,控件范围一般限定于当前的container里面,不过会存在一个例外,就是当存在多个窗口的情况,在前面内容里面曾经说过,如果是想要弹窗,可以让父窗口为root win,这时候toptree发生作用了,任何情况下,窗口都会是在最上层,包括它里面的控件,因此对于弹窗来说,就算它创建或者显示时间是最晚的,它的判断处理依旧会是最先的,相当于最先添加控件,而这个功能实现便是依赖从toptree得到当前窗口数目,然后执行算法的时候优先处理上层窗口,因此底层窗口会被上层窗口覆盖,当然,曾经出现过下层控件更新覆盖窗口的bug,但随着版本更新,rtgui的这些bug也慢慢的少了。

说到这里,如果有跑过rtguidemo的同学就会看到过,屏幕换页刷新的时候,并不是一下全刷完的,而是有控件的地方会先空着,等背景刷新完的时候,才会更新。这其实就是剪切域造成的,按照别人的理解,一个控件刷新需要判断它的区域是不是被别的控件覆盖了,而一个总的页面就是一个控件,而这个页面上所有的控件是相当于这个页面控件的上层,页面刷新程序在绘制自己的时候进行剪切域判断,从而把控件部位空了出来,按照官方说法。这个能减少绘制时间。其实这不是绝对的。

这里需要说到dc引擎,dc引擎是rtgui用来绘制显示像素的底层,包含了绘制地层的函数。一个控件在绘制的时候需要申请绘制引擎dc,具体是dc = rtgui_dc_begin_drawing(widget),这个函数会返回一个dc引擎,然后控件就利用这个引擎来进行显示操作了。但是重点是,返回的dc引擎其实是有差别的,因为rtgui里面存在着两种引擎,一种是硬件引擎(dc_hw),一种是客户端引擎(dc_client),两者的差别在于,用硬件引擎的时候,不会去判断剪切域,而是直接进行覆盖绘制,而客户端引擎则是没画一条线或者一个点的时候,都需要去判断剪切域是否可以画。这一看,好像是用硬件引擎比较快,毕竟不用判断嘛,但是如果当剪切域判断出来可以绘制的区域很小的时候,那么绘制的内容小于原来控件大小很多,明显也就比硬件殷勤要快了。而选择哪个引擎是系统决定的,主要依据就是rtgui_region_t clip这个链表是不是空的。

页面刷新的时候也就是这种情况,当控件比较多或者控件面积比较大的时候,明显的采用客户端引擎绘制时间能大大的减少。但是如果一个页面空间又小又分布零散,那样的话不仅不能减少绘制时间,反而是增加了负担。

所以这里其实是涉及到了一个技巧。很多人会喜欢用stm32去跑rtguistm3264ksram,放不下很多的控件,但是它的flash确可以到512k,很多人抱怨放置不了多少个控件,除非加外部sram,刷新也慢。但是如果整个页面只有一个没有控件,只有自己本身一个呢?这时候申请到的是硬件引擎,刷新速度快,又省资源,同时利用代码分段显示来实现控件的显示效果与功能,做的好能保证效果一致。当然,一些功能比较复杂的控件依旧还是需要利用现有控件做比较好,但是想大小芯片上又想控件又想省内存的想法是不切实际的,有这类想法的人要敲下警钟了。

另外一个,就是剪切域显示的这种方式,换页显示过程中存在着一个缺陷,就是刷新不同步的问题,会出现空洞过程。同样的问题在mfc上面也有,只不过mfc上面是大内存,可以设置缓冲,而对于小芯片来说,太耗费资源了,算下,如果是一个400/272的屏幕16色缓存可是要200k多的。

 

Ok,这次内容就到这,不想弄图了,虽然其实弄图会好理解很多,不过因为是填坑,没有多少心思弄图了。这次讲完,这个系列应该也不会再写了,因为毕竟对rtgui已经开始生疏了,好久没用了,现在也不知道该讲哪些知道,此外新版本快出来了,我懂的已经是很落后的了,跟不上新的,只能暂时这样了,只能对那些对我抱有希望的同学说声对不起了,学习还是要靠你们自己的。后面能找到板子,再考虑用新版本放下例程开始写实用篇吧,或者说有哪位大侠借下板子给我呢。

最后谢谢观看这几篇陋文的同学,希望你们能在里面学到东西。(茂似最后我自己看了也不知道自己在写什么了,应该没东西可学的,洗洗睡吧。。。。)

猜你喜欢

转载自blog.csdn.net/xuzhenglim/article/details/12366759
今日推荐