渲染timer开始工作啦!!!首先处理脏域(obj的脏域合到屏幕obj脏域数组中),然后对屏幕obj的三层layer的脏域进行处理,每层layer按照晚辈到长辈的方式进行处理obj,最后再对area做最后的clip.
1._lv_display_refr_timer
开始工作啦,首先更新布局(对屏幕对象的三层layer进行布局更新):
lv_obj_update_layout(disp_refr->bottom_layer);
lv_obj_update_layout(disp_refr->top_layer);
lv_obj_update_layout(disp_refr->sys_layer);
2.lv_refr_join_area();详细描述可以看下面的特别描述部分
该函数主要是处理脏域,判断是否是合并过的区域,如果没有合并过,就进行合并,join from 被合并的区域就需要设置一个合并的标志位:
/*Mark 'join_form' is joined into 'join_in'*/
disp_refr->inv_area_joined[join_from] = 1;
inv_area_joined[]是一个存储是否合并标志位的数组;
合并脏域并加入到屏幕obj的脏域数组中(lv_area_copy(&disp_refr->inv_areas[join_in], &joined_area);)
3.refr_sync_areas();
两个buffer的备份
4.refr_invalid_areas;
刷新处理后的脏域,所谓的处理就是第2点中的合并;由于脏域都放在屏幕obj的刷新数组中,现在只处理inv_area_joined标志没有置1的部分;这部分脏域就是没有参与过合并的区域和合并后的区域了。
5.refr_area(&disp_refr->inv_areas[i]);
开始绘制屏幕obj的脏区
4.refr_area_part(layer);
有全刷和局部刷新的区分,layer_reshape_draw_buf会调整刷新的区域,根据是全刷还是局部刷新,调整刷新面积
5.refr_obj_and_children;
对三层进行刷新,先是最下面的一层,然后是中间层,最后是最上面的一层。
lv_obj_t * bottom_layer; /**< @see lv_display_get_layer_bottom*/
lv_obj_t * top_layer; /**< @see lv_display_get_layer_top*/
lv_obj_t * sys_layer; /**< @see lv_display_get_layer_sys*/
在每一层上面,首先是对最小辈分的obj进行刷新,冒泡一样,往上递归处理。
parent = lv_obj_get_parent(parent);
6.refr_obj
7.lv_obj_redraw
对需要刷新的区域做最后的裁剪:针对obj area和layer area进行比较,决定layer->_clip_area 的范围。
lv_obj_send_event(obj, LV_EVENT_DRAW_MAIN_BEGIN, layer);
lv_obj_send_event(obj, LV_EVENT_DRAW_MAIN, layer);
lv_obj_send_event(obj, LV_EVENT_DRAW_MAIN_END, layer);
LV_EVENT_DRAW_MAIN_BEGIN, /**<开始主绘图阶段*/
LV_EVENT_DRAW_MAIN, /**<执行主绘图*/
LV_EVENT_DRAW_MAIN_END, /**<完成主绘图阶段*/
8.lv_obj_send_event
特别描述部分!!!
lv_refr_join_area:
对所有的脏域进行合并:
1.先对某一脏域的标志进行判断,如果不等于0,说明该脏域已经被合并过了,处理下一个脏域。
if(disp_refr->inv_area_joined[join_in] != 0) continue;
2.只处理未连接或者未处理的区域并忽略其本身
if(disp_refr->inv_area_joined[join_from] != 0 || join_in == join_from) {continue;}
3.检查这些区域是否有接触
if(_lv_area_is_on(&disp_refr->inv_areas[join_in], &disp_refr->inv_areas[join_from]) == false) {continue;}
4.计算合并区域
_lv_area_join(&joined_area, &disp_refr->inv_areas[join_in], &disp_refr->inv_areas[join_from]);
5.判断,仅仅当合并后的区域小于合并之前的面积,才会合并,并将合并后的区域加入inv_areas
lv_area_copy(&disp_refr->inv_areas[join_in], &joined_area);
6.对处理过的脏域,进行标记
disp_refr->inv_area_joined[join_from] = 1;
重要结构体信息
#define disp_refr LV_GLOBAL_DEFAULT()->disp_refresh
typedef struct _lv_global_t {
...
lv_ll_t disp_ll;
lv_display_t * disp_refresh;
lv_display_t * disp_default;
...
}
struct _lv_display_t {
...
/*---------------------
* Buffering
*--------------------*/
lv_draw_buf_t * buf_1;
lv_draw_buf_t * buf_2;
/** Internal, used by the library*/
lv_draw_buf_t * buf_act;
...
/** Invalidated (marked to redraw) areas*/
lv_area_t inv_areas[LV_INV_BUF_SIZE];
uint8_t inv_area_joined[LV_INV_BUF_SIZE];
uint32_t inv_p;
int32_t inv_en_cnt;
/** 双缓冲区同步区域(在上次刷新期间重新绘制,两个buffer直接进行备份) */
lv_ll_t sync_areas;
...
}