GUI刷新机制研究(一) 状态更新

在gui的mainloop中,framework提供了一些接口用于处理内部或者外部的状态变化

 如EwBspKeyEventProcess, 这个地方是底层和framework打交道的地方,拿到底层上报的按键时间后,最后通过调CoreRoot__DriveKeyboardHitting 把时间上报给root object。具体的实现在Core.c 的CoreRoot_DriveKeyboardHitting中,首先是判断一下这次的key是按下还是抬起或者是长按,然后通过EwSignal走到chora层定义的各个slot回调中

 还有EwProcessSignals, ProcessSignals中可以看到,gui的所有signal是以list的形式管理的,每处理(通过对应的slot)一个signal, 就会free掉这个signal节点的资源,在此函数内完成对signal的遍历

与此类似还有EwProcessTimers, Timer也是用链表管理的,在EwProcessTimers遍历所有的timer, 查看是否有expired的,并通过注册的回调进行处理

然后就走到CoreRoot_DoesNeedUpdate中,这个函数的实现在生成的Core.c中,进去后可以看到是直接通过判断_this->noOfRegions来决定是否need update

所以到这一刻可以清楚的是,在前面的signal的处理,或者key的处理,亦或者timer的处理的slot中,肯定就完成了对noOfRegions的判断。

那么现在主线就是要搞清楚,更新之前脏区的判断,以及在脏区的基础上是如何完成画面更新的。

全局搜了一下noOfRegions, 发现只在Core.c中有,那么就要着重看一下哪些函数会操作这个变量:

大部分是在CoreGroup的InvalidateArea的方法内。下面就要用到一些技巧了,我在几个关键的位置把calltrace打印下来,这样可以方便我快速理清这里面的脉络。然后顺藤摸瓜,在draw的地方也打上trace,这样就大概知道是怎么更新和渲染的了。

首先发现在EwProcessSignals中,走到了XFlatHorzBarSlider_UpdateViewState (与此类似还有XFlatSwitch_UpdateViewState, ViewsText_reparseSlot)

那好,这个方法是类XFlatHorzBarSlider的一个方法,这个类的基类是CoreGroup

所谓的XFlatHorzBarSlider就是一个进度条,这样一个类的成员变量和成员函数的声明都在_XFlatHorzBarSlider.h中

刚才说了EwProcessSignals中有一个对全局变量signal链表的操作,应该是依次在调用每个signal对应的slot,然后就走到了

XFlatHorzBarSlider_UpdateViewState. 【这里signa的注册和触发不是本文要讲的内容,此处按下不表】

在这个函数中,首先得到了进度条的pos, 然后是走到了Core.c中的CoreRectView_OnSetBounds

这个函数简单分析一下,先判断本次的边界和之前是否一样,相同的话直接返回,不会触发CoreGroup_InvalidateArea

然后是判断一下这个控件对象的父对象是否为0,如果有父对象,且父对象的ViewState是Visible的,那就把父对象的这块Bounds区域也

触发成CoreGroup_InvalidateArea,子对象脏了,父对象的这块区域也要标记为脏,这很合理。

EwPostSignal( EwNewSlots(_this->Super1.owner, CoreGroup_updateComponent), (XObject)_this) );

这个地方又是一个触发signal的操作,暂时不说。

接着往下走,看下CoreGroup_InvalidateArea的内部实现到底是个什么机理

首先是GraphicsCanvas buf = grp->buffer 这里面buf的确切含义不是很清楚,这里后面会补充一下这个基础知识

然后判断一下用户选择的是否是fullOffscreenBufferUpdate的刷新方式,如果是

buf->InvalidArea就是grp->Super1.Bounds, 否则就是上一次的buf->InvalidArea和本次的Area的union

然后是开始对比EwCompRect( oldInvalidArea, buf->InvalidArea ), 如果两次的的invalidArea不一样,那么

EwNotifyObjObervers((XObject)grp, 0)

EwNotifyObjObervers((XObject)buf, 0)

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