Mercurial > MadButterfly
diff src/redraw_man.c @ 537:3a7e3c1cd6e6 Android_Skia
[mq]: propagate_areas.diff
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Sat, 22 May 2010 22:31:18 +0800 |
parents | b6b3dbeaedf3 |
children | a1d49b6355c3 |
line wrap: on
line diff
--- a/src/redraw_man.c Fri May 21 22:59:26 2010 +0800 +++ b/src/redraw_man.c Sat May 22 22:31:18 2010 +0800 @@ -471,7 +471,7 @@ return OK; } -static int add_dirty_pcache_area_coord(rdraw_man_t *rdman, coord_t *coord) { +static int add_dirty_pcache_area_coord(redraw_man_t *rdman, coord_t *coord) { coord_set_flags(coord, COF_DIRTY_PCACHE_AREA); ADD_DATA(coords, dirty_pcache_area_coords, coord); return OK; @@ -1246,7 +1246,7 @@ if(!coord_is_cached(coord)) { /* canvas is assigned latter, in zeroing_coord() */ coord->canvas_info = coord_canvas_info_new(rdman, coord, NULL); - coord_set_flags(coord->flags, COF_OWN_CANVAS); + coord_set_flags(coord, COF_OWN_CANVAS); } } else { if(coord_is_cached(coord)) { @@ -1308,8 +1308,12 @@ co_aix cached2pdev[6]; int c_w, c_h; canvas_t *canvas; + coord_canvas_info_t *canvas_info; co_aix poses[4][2]; + canvas_info = coord->canvas_info; + SWAP(canvas_info->pcache_cur_area, canvas_info->pcache_last_area, + area_t *); compute_cached_2_pdev_matrix(coord, cached2pdev); canvas = _coord_get_canvas(coord); @@ -1329,6 +1333,8 @@ matrix_trans_pos(cached2pdev, &poses[3][0], &poses[3][1]); area_init(coord_get_pcache_area(coord), 4, poses); + + coord_set_flags(coord, COF_DIRTY_PCACHE_AREA); } /*! \brief Compute area of a coord. @@ -1406,8 +1412,8 @@ if(r != OK) return ERR; - add_dirty_area(rdman, coord->cur_area); - add_dirty_area(rdman, coord->last_area); + add_dirty_area(rdman, coord, coord->cur_area); + add_dirty_area(rdman, coord, coord->last_area); coord_clear_flags(coord, COF_DIRTY); coord_set_flags(coord, COF_JUST_CLEAN); @@ -1442,7 +1448,7 @@ coord = dirty_coords[i]; if(!coord_get_flags(coord, COF_DIRTY | COF_JUST_CLEAN)) continue; - SWAP(coord->cur_area, coord->last_area, coord_t *); + SWAP(coord->cur_area, coord->last_area, area_t *); r = clean_coord(rdman, coord); if(r != OK) return ERR; @@ -1526,7 +1532,7 @@ max_x = x; if(y > max_y) max_y = y; - if(coord_is_cached(cur->flags)) + if(coord_is_cached(cur)) preorder_coord_skip_subtree(cur); } @@ -1543,11 +1549,17 @@ * of the coord have not changed since last time of zeroing. So, * if canvas box cover all descendants, we don't need rezeroing, * and avoid redraw all descendants. + * + * Width and height of actually drawing area should not be smaller + * than half of canvas's width and height. */ if(!coord_get_flags(coord, COF_JUST_CLEAN) && - min_x >= 0 && min_y >= 0 && max_x <= c_w && max_y <= c_h) + min_x >= 0 && min_y >= 0 && max_x <= c_w && max_y <= c_h && + h >= (c_h >> 2) && w >= (c_w >> 2)) { /* Canvas fully cover sub-graphic. */ + coord_set_flags(coord, COF_SKIP_ZERO); return; + } /* * Adjust matrics of descendants to align left-top corner of @@ -1584,22 +1596,6 @@ _coord_set_canvas(coord, canvas); } - compute_pcache_area(coord); - - /* Since aggregated matrix had been changed to make descendants - * falling on the canvas, size or/and position of all descendants - * are chagned, and new canvas was created. So, a dirty area that - * covers all space of the canvas is created to force redrawing - * all descendants. - */ - area = &coord->canvas_info->cached_dirty_area; - area->x = 0; - area->y = 0; - area->w = w; - area->h = h; - DARRAY_CLEAN(_coord_get_dirty_areas(coord)); - add_dirty_area(rdman, coord, area); - coord_set_flags(coord, COF_JUST_ZERO); } @@ -1670,11 +1666,32 @@ coord_t *coord; all_zeroing = &rdman->zeroing_coords; - for(i = 0; i < all_zeroing->num; i++) { + /* From leaft to root. + * REASON: The size of canvas is also effected by cached descedants. + */ + for(i = all_zeroing->num - 1; i >= 0; i--) { coord = all_zeroing->ds[i]; zeroing_coord(rdman, coord); + compute_pcache_area(coord); } + + return OK; +} +/*! \brief Compute pcache_area for coords whoes pcache_area is dirty. + */ +static int +compute_rdman_coords_pcache_area(redraw_man_t *rdman) { + coords_t *all_coords; + coord_t *coord; + int i; + + all_coords = &rdman->dirty_pcache_area_coords; + for(i = 0; i < all_coords->num; i++) { + coord = all_coords->ds[i]; + if(coord_get_flags(coord, COF_DIRTY_PCACHE_AREA)) + compute_pcache_area(coord); + } return OK; } @@ -1786,6 +1803,11 @@ add_dirty_area(rdman, pcached_coord, coord->last_area); } +/*! \brief To test if redrawing all elements on the canvas of a cached coord. + */ +#define IS_CACHE_REDRAW_ALL(co) \ + (coord_get_flags((co), COF_JUST_CLEAN | COF_JUST_ZERO)) + /* Aggregate dirty areas and propagate them to ancestor cached coord. * * The aggregation is performed from leaves to root. But, this @@ -1799,14 +1821,63 @@ int n_zeroing; coord_t **zeroings; coord_t *coord, *pcached_coord; + int n_dpca_coords; /* number of dirty pcache area coords */ + coord_t **dpca_coords; /* dirty pcache area coords */ + /* Add aggregated areas to parent cached one for coords in zeroing + * list + */ n_zeroing = rdman->zeroing_coords.num; zeroings = rdman->zeroing_coords.ds; - for(i = n_zeroing - 1; i >= 0; i--) { + for(i = 0; i < n_zeroing; i++) { + if(coord_get_flags(coord, COF_TEMP_MARK)) + continue; + coord_set_flags(coord, COF_TEMP_MARK); + coord = zeroings[i]; pcached_coord = coord_get_cached(coord_get_parent(coord)); - if(!coord_is_root(coord) && !coord_is_zeroing(pcached_coord)) + + if(coord_is_root(coord) || IS_CACHE_REDRAW_ALL(pcached_coord)) + continue; + + if(IS_CACHE_REDRAW_ALL(coord)) { + add_dirty_area(rdman, pcached_coord, + coord_get_pcache_area(coord)); + add_dirty_area(rdman, pcached_coord, + coord_get_pcache_last_area(coord)); + } else { add_aggr_dirty_areas_to_ancestor(rdman, coord); + } + } + + /* Add pcache_areas to parent cached one for coord that is + * non-zeroing and its parent is changed. + */ + n_dpca_coords = rdman->dirty_pcache_area_coords.num; + dpca_coords = rdman->dirty_pcache_area_coords.ds; + for(i = 0; i < n_dpca_coords; i++) { + if(coord_get_flags(coord, COF_TEMP_MARK)) + continue; + coord_set_flags(coord, COF_TEMP_MARK); + + coord = dpca_coords[i]; + pcached_coord = coord_get_cached(coord_get_parent(coord)); + + if(coord_is_root(coord) || IS_CACHE_REDRAW_ALL(pcached_coord)) + continue; + + add_dirty_area(rdman, pcached_coord, + coord_get_pcache_area(coord)); + add_dirty_area(rdman, pcached_coord, + coord_get_pcache_last_area(coord)); + } + + /* Remove temporary mark */ + for(i = 0; i < n_zeroing; i++) { + coord_clear_flags(zeroing[i], COF_TEMP_MARK); + } + for(i = 0; i < n_dpca_coords; i++) { + coord_clear_flags(dpca_coords[i], COF_TEMP_MARK); } return OK; @@ -1916,6 +1987,10 @@ if(r != OK) return ERR; + r = compute_rdman_coords_pcache_area(rdman); + if(r != OK) + return ERR; + r = add_rdman_aggr_dirty_areas(rdman); if(r != OK) return ERR;