asmcos 发表于 2006-6-23 10:49:55

窗口裁减讨论-2

EGui的窗口裁减的设计

1.窗口暴露和覆盖的计算
1).EGui在kernel里通过窗口的矩形坐标可以计算出2个窗口的相交后的矩形坐标。
   文件:src-gui/driver/kegui.c
   函数:void calc_rect_intersection (window_list * list1,window_list * list2);

2).计算后将相交的矩形参数传给被覆盖的窗口。
   如图所示窗口A,B相交。(B完全在A里面,B是A的上层窗口)。

   所以计算的结果传给A。

3).A窗口维护一条被覆盖其他窗口覆盖的矩形参数的链表。

4).通过这个链表计算出A窗口当前暴露的矩形。
   如图所示应该为红色表示的4个矩形。

2.覆盖后的显示方法

当窗口A被遮挡住以后,窗口A再次发生绘画事件,我们应该怎么处理?
不管怎么处理都必须遵守以下原则:
1).被遮挡的不应该显示;
2).暴露的部分需要显示出来;

怎么实现呢?
方法一:
1).将A窗口分配一个等窗口大小的内存空间;
2).将所有要更新的内容写到内存里;
3).将可视的矩形都复制出来。

这种实现方法简单可行,但有一些问题:
1).消耗内存空间大,每个窗口都保存一个同窗口大小的空间一个就需要1M以上。
2).全部复制消耗时间多。
   例如图中有两个线段,暴露在外面的极少,大部分都被覆盖。
   但按照EGui的实现方法,就需要复制2个矩形区域。

方法二:
1).将遮挡的部分分配内存空间;
2).当作更新区域时,需要做判断是在可视或者不可视区域。
   如果是可视区域就直接显示,不做任何保存动作,
   否则写到覆盖的内存。等到B窗口移走后显示出来。
   
   这样做每个更新的点都要判断。如果出现大量的点需要更新和快速更新的话,效率非常低。

不知道大家有没有更好的方法。

muddog 发表于 2006-6-23 10:56:03

判断点,可比内存拷贝效率要高不少哦。
还是建议做优化。两种模式同时采用。但是第一种模式下,不必为窗口分配大小相等的buffer.
可以只分配绘制涉及到的范围,然后将这个范围和可视区域做 clip
最后再拷贝。

asmcos 发表于 2006-6-23 11:32:35

需要结合控件本身来考虑。

我现在规划EGui的任何显示操作都在控件里面来实现。(window的特征操作除外,标题栏,外边框等)

如果这样暴露和隐藏显示要做控件的覆盖算法。

muddog 发表于 2006-6-23 21:52:30

控件不能也维护一个可视列表马?又窗口维护

AnthonyLee 发表于 2006-6-25 01:35:16

以前接触过一个DOS下VESA模式的类似情况(仅root窗口采用内存缓冲机制),
当时的处理:

第一种情况:任何窗口均不移动,同时有若干个窗口有写点
处理:
将画点、线、弧、填充等生成过程添加一个被不可视区域剪裁的过程
(比如一宽度为0的线被一个矩形区域剪裁可能成为不大于两段的线条),
然后绘制到root窗口的缓冲区中,再根据需要更新的最大区域整体写到显存中去。

第二种情况:没有任何的绘制动作,仅有窗口的移动和放缩
处理:
对移动或放缩的窗口内容进行内存拷贝到新的位置并绘制边框,
移动或放缩的窗口的旧可视区域裁减去新可视区域后填上背景,
对所有与其新旧两个范围有相交而且又是可视的窗口调用重绘,
上面的动作做完后也是根据需要更新的最大区域整体写到显存中去。


另外建议不要对每个窗口均保存内容,这些工作让客户端的lib去决定
或提供一个类似X11的Pixmap的可绘位图接口。

feelcycle 发表于 2006-9-8 13:29:12

控件完全在容器中,只需要考虑容器类顶级窗体类型,该类型的窗体负责分发重绘信息给它的子窗体。

lilofreeman 发表于 2006-10-26 20:27:59

alpha混合
页: [1]
查看完整版本: 窗口裁减讨论-2