zoukankan      html  css  js  c++  java
  • 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里面的活了

  • 相关阅读:
    sed cat 命令
    Datetime 时间模块求日期差
    Selenium:截图显示等待
    SAS常用函数
    SAS笔记
    python 简明教程 【转】
    numpy 笔记
    android Adapter使用详解
    Eclipse的使用技巧之eclipse里的查找:
    Hierarchy Viewer之官方文档翻译之中英对照之未完不续版之使用详解.
  • 原文地址:https://www.cnblogs.com/Arnold-Zhang/p/15314709.html
Copyright © 2011-2022 走看看