zoukankan      html  css  js  c++  java
  • 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)

  • 相关阅读:
    JavaScript内置函数
    JavaScript内置函数
    javascript入门之算术乘法表
    第三章 3 python运算符的优先级
    第三章 2 pyhon中的运算符
    第三章 1 input输入函数
    第二章 5 python中的注释
    第二章 4 数据类型的转换
    第二章 3 数据类型
    第二章 2 python中的标识符和保留字
  • 原文地址:https://www.cnblogs.com/Arnold-Zhang/p/15314642.html
Copyright © 2011-2022 走看看