comparison src/redraw_man.c @ 324:0f0a3da11390

merge
author wycc
date Thu, 05 Mar 2009 14:31:59 +0800
parents c1afd14caa85
children 85b8bb36fe71
comparison
equal deleted inserted replaced
323:33e8ff8b7ad2 324:0f0a3da11390
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"