Mercurial > MadButterfly
comparison src/redraw_man.c @ 322:c1afd14caa85
Remove out-of-date comments and refactor code and fix a small bug.
- When collect descendant areas in zeroing_coord(), cached coord itself
should use coord_canvas_info_t::owner_mems_area instead of
coord_t::cur_area.
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Thu, 05 Mar 2009 14:07:49 +0800 |
parents | d0f8642d3508 |
children | 85b8bb36fe71 |
comparison
equal
deleted
inserted
replaced
321:44cc65e7e234 | 322:c1afd14caa85 |
---|---|
969 coord_clear_zeroing(coord); | 969 coord_clear_zeroing(coord); |
970 | 970 |
971 /* | 971 /* |
972 * Compute minimum overing area of sub-graphic | 972 * Compute minimum overing area of sub-graphic |
973 */ | 973 */ |
974 area = coord_get_area(coord); | 974 area = &coord->canvas_info->owner_mems_area; |
975 min_x = area->x; | 975 min_x = area->x; |
976 min_y = area->y; | 976 min_y = area->y; |
977 max_x = min_x + area->w; | 977 max_x = min_x + area->w; |
978 max_y = min_y + area->h; | 978 max_y = min_y + area->h; |
979 | 979 |
980 FOR_COORDS_PREORDER(coord, cur) { | 980 for(cur = preorder_coord_subtree(coord, coord); |
981 cur != NULL; | |
982 cur = preorder_coord_subtree(coord, cur)) { | |
981 area = coord_get_area(cur); | 983 area = coord_get_area(cur); |
982 if(area->x < min_x) | 984 if(area->x < min_x) |
983 min_x = area->x; | 985 min_x = area->x; |
984 if(area->y < min_y) | 986 if(area->y < min_y) |
985 min_y = area->y; | 987 min_y = area->y; |
1079 if(coord->flags & COF_OWN_CANVAS) | 1081 if(coord->flags & COF_OWN_CANVAS) |
1080 compute_aggr_of_cached_coord(coord); | 1082 compute_aggr_of_cached_coord(coord); |
1081 else | 1083 else |
1082 compute_aggr_of_coord(coord); | 1084 compute_aggr_of_coord(coord); |
1083 | 1085 |
1086 /* Areas of cached coords are computed in two phase. | |
1087 * Phase 1 works like other normal ones. Phase 2, is collect | |
1088 * all areas of descendants to compute a minimum covering area. | |
1089 * Phase 2 is performed by zeroing_coord(). | |
1090 */ | |
1084 r = coord_clean_members_n_compute_area(coord); | 1091 r = coord_clean_members_n_compute_area(coord); |
1085 if(r != OK) | 1092 if(r != OK) |
1086 return ERR; | 1093 return ERR; |
1087 | 1094 |
1088 coord->flags &= ~COF_DIRTY; | 1095 coord->flags &= ~COF_DIRTY; |
1340 | 1347 |
1341 matrix_trans_pos(canvas2pdev_matrix, poses1[0], poses1[0] + 1); | 1348 matrix_trans_pos(canvas2pdev_matrix, poses1[0], poses1[0] + 1); |
1342 matrix_trans_pos(canvas2pdev_matrix, poses1[1], poses1[1] + 1); | 1349 matrix_trans_pos(canvas2pdev_matrix, poses1[1], poses1[1] + 1); |
1343 area_init(area1, 2, poses1); | 1350 area_init(area1, 2, poses1); |
1344 if(area1->w != 0 || area1->h != 0) | 1351 if(area1->w != 0 || area1->h != 0) |
1345 add_dirty_area(rdman, pcached_coord, area1); | 1352 if(area0->x != area1->x || area0->y != area1->y || |
1353 area0->w != area1->w || area0->h != area1->h) | |
1354 add_dirty_area(rdman, pcached_coord, area1); | |
1346 | 1355 |
1347 if(coord_get_flags(coord, COF_JUST_CLEAN) && | 1356 if(coord_get_flags(coord, COF_JUST_CLEAN) && |
1348 !coord_get_flags(pcached_coord, COF_JUST_CLEAN)) | 1357 !coord_get_flags(pcached_coord, COF_JUST_CLEAN)) |
1349 add_dirty_area(rdman, pcached_coord, coord->last_area); | 1358 add_dirty_area(rdman, pcached_coord, coord->last_area); |
1350 } | 1359 } |
1385 } | 1394 } |
1386 | 1395 |
1387 static int clean_rdman_dirties(redraw_man_t *rdman) { | 1396 static int clean_rdman_dirties(redraw_man_t *rdman) { |
1388 int r; | 1397 int r; |
1389 int i; | 1398 int i; |
1390 coord_t **coords; | 1399 coord_t **coords, *coord; |
1391 geo_t **geos; | 1400 geo_t **geos; |
1392 | 1401 |
1402 /* coord_t::cur_area of coords are temporary pointed to | |
1403 * coord_canvas_info_t::owner_mems_area for store area | |
1404 * by clean_coor(). | |
1405 */ | |
1393 coords = rdman->dirty_coords.ds; | 1406 coords = rdman->dirty_coords.ds; |
1394 for(i = 0; i < rdman->dirty_coords.num; i++) | 1407 for(i = 0; i < rdman->dirty_coords.num; i++) { |
1395 if(coords[i]->flags & COF_DIRTY) | 1408 coord = coords[i]; |
1396 SWAP(coords[i]->cur_area, coords[i]->last_area, area_t *); | 1409 if(coord->flags & COF_DIRTY) { |
1397 | 1410 if(!coord_get_flags(coord, COF_OWN_CANVAS)) |
1411 SWAP(coord->cur_area, coord->last_area, area_t *); | |
1412 else { | |
1413 coord->last_area = coord->cur_area; | |
1414 coord->cur_area = &coord->canvas_info->owner_mems_area; | |
1415 } | |
1416 } | |
1417 } | |
1418 | |
1398 geos = rdman->dirty_geos.ds; | 1419 geos = rdman->dirty_geos.ds; |
1399 for(i = 0; i < rdman->dirty_geos.num; i++) | 1420 for(i = 0; i < rdman->dirty_geos.num; i++) |
1400 if(geos[i]->flags & GEF_DIRTY) | 1421 if(geos[i]->flags & GEF_DIRTY) |
1401 SWAP(geos[i]->cur_area, geos[i]->last_area, area_t *); | 1422 SWAP(geos[i]->cur_area, geos[i]->last_area, area_t *); |
1402 | 1423 |
1403 r = clean_rdman_coords(rdman); | 1424 r = clean_rdman_coords(rdman); |
1404 if(r != OK) | 1425 if(r != OK) |
1405 return ERR; | 1426 return ERR; |
1406 | 1427 |
1407 for(i = 0; i < rdman->dirty_coords.num; i++) | 1428 coords = rdman->dirty_coords.ds; |
1408 coord_set_flags(rdman->dirty_coords.ds[i], COF_JUST_CLEAN); | 1429 for(i = 0; i < rdman->dirty_coords.num; i++) { |
1430 coord = coords[i]; | |
1431 coord_set_flags(coord, COF_JUST_CLEAN); | |
1432 coord->cur_area = | |
1433 (coord->last_area == coord->areas)? | |
1434 coord->areas + 1: coord->areas; | |
1435 } | |
1409 | 1436 |
1410 r = clean_rdman_geos(rdman); | 1437 r = clean_rdman_geos(rdman); |
1411 if(r != OK) | 1438 if(r != OK) |
1412 return ERR; | 1439 return ERR; |
1413 | 1440 |
1425 | 1452 |
1426 r = add_rdman_cached_dirty_areas(rdman); | 1453 r = add_rdman_cached_dirty_areas(rdman); |
1427 if(r != OK) | 1454 if(r != OK) |
1428 return ERR; | 1455 return ERR; |
1429 | 1456 |
1457 coords = rdman->dirty_coords.ds; | |
1430 for(i = 0; i < rdman->dirty_coords.num; i++) | 1458 for(i = 0; i < rdman->dirty_coords.num; i++) |
1431 coord_clear_flags(rdman->dirty_coords.ds[i], COF_JUST_CLEAN); | 1459 coord_clear_flags(coords[i], COF_JUST_CLEAN); |
1432 | 1460 |
1433 return OK; | 1461 return OK; |
1434 } | 1462 } |
1435 | 1463 |
1436 | 1464 |
1521 cairo_set_operator(canvas, CAIRO_OPERATOR_CLEAR); | 1549 cairo_set_operator(canvas, CAIRO_OPERATOR_CLEAR); |
1522 cairo_paint(canvas); | 1550 cairo_paint(canvas); |
1523 cairo_set_operator(canvas, old_op); | 1551 cairo_set_operator(canvas, old_op); |
1524 } | 1552 } |
1525 | 1553 |
1526 static void clean_canvas(cairo_t *cr, co_aix w, co_aix h) { | |
1527 cairo_operator_t saved_op; | |
1528 | |
1529 saved_op = cairo_get_operator(cr); | |
1530 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); | |
1531 | |
1532 /*! \todo clean to background color. */ | |
1533 cairo_set_source_rgba(cr, 1, 1, 1, 1); | |
1534 | |
1535 /* For some unknown reasons, cairo_paint() can not erease | |
1536 * painted graphic cleanly. So, cairo_fill() are used to | |
1537 * replace it. | |
1538 */ | |
1539 cairo_rectangle(cr, 0, 0, w, h); | |
1540 cairo_fill(cr); | |
1541 | |
1542 cairo_set_operator(cr, saved_op); | |
1543 } | |
1544 | |
1545 static void clean_canvas_black(cairo_t *cr, co_aix w, co_aix h) { | |
1546 clear_canvas(cr); | |
1547 | |
1548 /*! \todo clean to background color. */ | |
1549 cairo_set_source_rgba(cr, 0, 0, 0, 0); | |
1550 cairo_paint(cr); | |
1551 } | |
1552 | |
1553 static void make_clip(cairo_t *cr, int n_dirty_areas, | 1554 static void make_clip(cairo_t *cr, int n_dirty_areas, |
1554 area_t **dirty_areas) { | 1555 area_t **dirty_areas) { |
1555 int i; | 1556 int i; |
1556 area_t *area; | 1557 area_t *area; |
1557 | 1558 |
1578 cairo_set_operator(rdman->backend, CAIRO_OPERATOR_SOURCE); | 1579 cairo_set_operator(rdman->backend, CAIRO_OPERATOR_SOURCE); |
1579 cairo_paint(rdman->backend); | 1580 cairo_paint(rdman->backend); |
1580 cairo_set_operator(rdman->backend, saved_op); | 1581 cairo_set_operator(rdman->backend, saved_op); |
1581 } | 1582 } |
1582 #else /* UNITTEST */ | 1583 #else /* UNITTEST */ |
1583 static void clean_canvas(cairo_t *cr, co_aix w, co_aix h) { | 1584 static void clear_canvas(canvas_t *canvas) { |
1584 } | |
1585 | |
1586 static void clean_canvas_black(cairo_t *cr, co_aix w, co_aix h) { | |
1587 } | 1585 } |
1588 | 1586 |
1589 static void reset_clip(canvas_t *cr) { | 1587 static void reset_clip(canvas_t *cr) { |
1590 } | 1588 } |
1591 | 1589 |
2177 * - rdman_shape_*_new() | 2175 * - rdman_shape_*_new() |
2178 * - rdman_shape_free() | 2176 * - rdman_shape_free() |
2179 */ | 2177 */ |
2180 | 2178 |
2181 /* | 2179 /* |
2182 * When redraw an area, the affected elements may also extend to | |
2183 * outside of the area. Since the order of drawing will change | |
2184 * the result, it will infect more and more elements to keep | |
2185 * drawing order althrough they are overlaid directly with | |
2186 * specified area. | |
2187 * | |
2188 * To fix the problem, we don't extend the set of redrawing to | |
2189 * elements they are not overliad directly. The redrawing is | |
2190 * performed on a temporary surface, clipped to fit the area, and | |
2191 * update only specified area on the destinate surface. | |
2192 */ | |
2193 | |
2194 /* | |
2195 * To accelerate speed of transformation, when a matrix changed, | 2180 * To accelerate speed of transformation, when a matrix changed, |
2196 * transformation should be aggregated and computed in a loop. | 2181 * transformation should be aggregated and computed in a loop. |
2197 * It can get intereset of higher hit rate of cache. | 2182 * It can get intereset of higher hit rate of cache. |
2198 * - shapes prvoide list of positions needed to be transformed. | 2183 * - shapes prvoide list of positions needed to be transformed. |
2199 * - redraw_man transforms positions from shapes. | 2184 * - redraw_man transforms positions from shapes. |
2200 * - shapes drawing with result of transforms. | 2185 * - shapes drawing with result of transforms. |
2201 * - shapes should be called to give them a chance to update geometries. | 2186 * - shapes should be called to give them a chance to update geometries. |
2202 */ | 2187 */ |
2203 | 2188 |
2204 /* | 2189 |
2205 * functions: | 2190 /* \defgroup rdman_observer Observer memory management |
2206 * - redraw all | 2191 * |
2207 * - redraw changed | 2192 * Implment factory and strategy functions for observers and subjects. |
2208 */ | 2193 * @{ |
2209 | |
2210 /* Implment factory and strategy functions for observers and subjects. | |
2211 */ | 2194 */ |
2212 static subject_t *ob_subject_alloc(ob_factory_t *factory) { | 2195 static subject_t *ob_subject_alloc(ob_factory_t *factory) { |
2213 redraw_man_t *rdman; | 2196 redraw_man_t *rdman; |
2214 subject_t *subject; | 2197 subject_t *subject; |
2215 | 2198 |
2272 } | 2255 } |
2273 | 2256 |
2274 return parent; | 2257 return parent; |
2275 } | 2258 } |
2276 | 2259 |
2260 /* @} */ | |
2261 | |
2277 #ifdef UNITTEST | 2262 #ifdef UNITTEST |
2278 /* Test cases */ | 2263 /* Test cases */ |
2279 | 2264 |
2280 #include <CUnit/Basic.h> | 2265 #include <CUnit/Basic.h> |
2281 #include "mb_paint.h" | 2266 #include "mb_paint.h" |