GUI刷新机制研究(三) 脏区计算

回到我们刚才看到的调用栈:

CoreRoot_UpdateGE20

   CoreRoot_UpdateCanvas

       CoreGroup_drawContent

            ViewsRectangle_Draw

现在我们比较感兴趣的地方在于,CoreRoot是如何判断脏区数目以及,到底是怎么按照脏区来更新的。

回到CoreRoot_UpdateGE20, 上来先调用了CoreRoot_BeginUpdate来对CoreRoot进行脏区数目的判断。

所以我们暂时先把目光转向这里面一探究竟:

首先是两个bool变量,分别是preserveFrameBufferContent 和 fullScreenUpdate

可以看到这里主要是用来标记GUI每一帧的刷新方式,具体是在哪里定义的呢,

发现在ew的ewgfxdefs.h 中由一些#if 的条件来判断,一通操作下来,EW_PRESERVE_FRAMEBUFFER_CONTENT是1

==================================================

真正的关键在于 CoreGroup_InvalidateArea, 我们是在这里强行指定一个Invalid区域才影响到后面真正的脏区计算的

所以这里也要深入分析一下:

这个函数里面有一点递归的算法在里面,首先是对判断当前的CoreGroup的super2.owner是否为0,如果为0,说明已经层层遍历到自己的root上了

因此这里是递归return的地方【这里是为啥是super2还没有看的太清楚】

好的,如果没有到return的条件里,那么就进行以下的处理,首先从当前GraphicsCanvas中拿到上一帧 的invalidateArea, 然后与传入的Area做一个union得到一个新的Area, 如果新的Area和旧的Area不相等,那么就EwNotifyObjObservers((XObject)grp,  0) 以及EwNotifyObjObservers((XObject)buf,  0) 这里找到objObserbers中的grp和buf,直接触发对应的slot.

slot是通过EwAttachObjObservers注册的, 通过搜索,找到其中一个注册地在Views.c中,以其中一个ViewsImage_timerSlot为例

这个对应的就是应用层的Views::Image.timerSlot, 这个Slot里面就是判断一些用户操作或者根据定时器判断当前是否要InvalidateArea

这里所有人都在对自己的super2.owner进行判断,循环一次后也是令grp = grp->Super2.owner 然后再去InvalidateArea

Views.c中很多类似的代码,就是用来处理和视效相关代码,比如ViewsText_OnSetColorBL 里面就是修改一个颜色,然后invalidateArea

==================================================================================================

发现一个事情,CoreGroup里面没有 noOfRegions + 1的操作, 在CoreRoot里面有这个操作,所以,中间一定是以某种方式走到了

CoreRoot_InvalidateArea 这里面。打了一些trace发现了一些端倪

EwProcessSignals

XFlatHorzBarSlider_UpdateViewState

CoreRectView_OnSetBounds

CoreRoot_InvalidateArea

================================================================================================

CoreRoot_UpdateGE20

CoreRoot_BeginUpdate

CoreRoot_InvalidateArea

===============================================================

所以真正的关键在于CoreRoot_InvalidateArea

这里面也的确是真正的计算了脏区的数目,大致就是每传入一个area, 就和之前已经记录的脏区测试是否相交

如果相交,那么脏区做union, 个数不变,如果全部没有交集,那么看一下脏区的个数只要小于4,就可以直接+1

超过4的话就选择和其中某一个做一个union。

  

 ========================================

到了CoreRoot_BeginUpdate 结束,本地绘制的脏区实际个数和大小,也就真正算完了。

下面就是CoreRoot_UpdateCanvas里面的活了

原文地址:https://www.cnblogs.com/Arnold-Zhang/p/15314709.html