Mercurial > MadButterfly
comparison src/redraw_man.c @ 535:a545f126d2bf Android_Skia
pcached_area replaces owner_mems_area
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Sun, 16 May 2010 22:59:24 +0800 |
parents | 9f2d07a60493 |
children | b6b3dbeaedf3 |
comparison
equal
deleted
inserted
replaced
534:9f2d07a60493 | 535:a545f126d2bf |
---|---|
37 * clean in preorder of tree traversal. The redraw_man_t::dirty_coords | 37 * clean in preorder of tree traversal. The redraw_man_t::dirty_coords |
38 * list are sorted to keep ordering before cleaning. | 38 * list are sorted to keep ordering before cleaning. |
39 * Whenever a coord is marked dirty and put into redraw_man_t::dirty_coords | 39 * Whenever a coord is marked dirty and put into redraw_man_t::dirty_coords |
40 * list, all it's children should also be marked. | 40 * list, all it's children should also be marked. |
41 * | 41 * |
42 * The procedure of clean coords comprises recomputing aggregate | 42 * The procedure of clean coords comprises recomputing aggregated |
43 * transform matrix and area where members spreading in. The aggregated | 43 * transform matrix and area where members spreading in. The aggregated |
44 * transform matrix can reduce number of matrix mul to transform | 44 * transform matrix can reduce number of matrix mul to transform |
45 * positions from space of a coord to the closest cached ancestor coord. | 45 * positions from space of a coord to the closest cached ancestor coord. |
46 * | 46 * |
47 * The list is inspected before drawing to recompute new shape, size, | 47 * The list is inspected before drawing to recompute new shape, size, |
285 * - Cached ancestors of redraw_man_t::dirty_geos | 285 * - Cached ancestors of redraw_man_t::dirty_geos |
286 * - Cached ancestors of redraw_man_t::dirty_coords | 286 * - Cached ancestors of redraw_man_t::dirty_coords |
287 * - Cached ancestors of zeroed ones should also be zeroed. | 287 * - Cached ancestors of zeroed ones should also be zeroed. |
288 * - zeroing | 288 * - zeroing |
289 * - Add more dirty areas if canvas should be fully redrawed. | 289 * - Add more dirty areas if canvas should be fully redrawed. |
290 * - From leaf to root. | 290 * - From leaves to root. |
291 * - Adjust area of child cached coords. | |
291 * - add aggregated dirty areas from descendant cached coords to ancestors. | 292 * - add aggregated dirty areas from descendant cached coords to ancestors. |
292 * - Must include old area of cached coords if it is just clean and | 293 * - Must include old area of cached coords if it is just clean and |
293 * parent cached one is not just clean. | 294 * parent cached one is not just clean. |
294 * - Just clean is a coord cleaned in last time of cleaning coords. | 295 * - Just clean is a coord cleaned in last time of cleaning coords. |
295 * - draw dirty areas | 296 * - draw dirty areas |
296 * - areas are rounded to N at first. | 297 * - areas are rounded to N at first. |
297 * - from leaf to root. | 298 * - from leaves to root. |
298 */ | 299 */ |
299 | 300 |
300 #ifndef ASSERT | 301 #ifndef ASSERT |
301 #define ASSERT(x) | 302 #define ASSERT(x) |
302 #endif | 303 #endif |
587 return info; | 588 return info; |
588 | 589 |
589 info->owner = coord; | 590 info->owner = coord; |
590 info->canvas = canvas; | 591 info->canvas = canvas; |
591 DARRAY_INIT(&info->dirty_areas); | 592 DARRAY_INIT(&info->dirty_areas); |
593 | |
594 bzero(info->pcache_areas, sizeof(area_t) * 2); | |
595 info->pcache_cur_area = &info->pcache_areas[0]; | |
596 info->pcache_last_area = &info->pcache_areas[1]; | |
592 | 597 |
593 return info; | 598 return info; |
594 } | 599 } |
595 | 600 |
596 static void coord_canvas_info_free(redraw_man_t *rdman, | 601 static void coord_canvas_info_free(redraw_man_t *rdman, |
725 FORMEMBERS(saved_coord, member) { | 730 FORMEMBERS(saved_coord, member) { |
726 rdman_shape_free(rdman, member->shape); | 731 rdman_shape_free(rdman, member->shape); |
727 } | 732 } |
728 rdman_coord_free(rdman, saved_coord); | 733 rdman_coord_free(rdman, saved_coord); |
729 } | 734 } |
730 #if 0 | |
731 FORMEMBERS(saved_coord, member) { | |
732 rdman_shape_free(rdman, member->shape); | |
733 } | |
734 #endif | |
735 /* Resources of root_coord is free by elmpool_free() or | 735 /* Resources of root_coord is free by elmpool_free() or |
736 * caller; for canvas | 736 * caller; for canvas |
737 */ | 737 */ |
738 | 738 |
739 shape = saved_shape = STAILQ_HEAD(rdman->shapes); | 739 while((shape = STAILQ_HEAD(rdman->shapes)) != NULL) { |
740 while(shape && (shape = STAILQ_NEXT(shape_t, sh_next, shape))) { | 740 rdman_shape_free(rdman, shape); |
741 rdman_shape_free(rdman, saved_shape); | 741 } |
742 #if 0 | |
743 STAILQ_REMOVE(rdman->shapes, shape_t, sh_next, saved_shape); | |
744 #endif | |
745 saved_shape = shape; | |
746 } | |
747 if(saved_shape != NULL) | |
748 rdman_shape_free(rdman, saved_shape); | |
749 | 742 |
750 coord_canvas_info_free(rdman, rdman->root_coord->canvas_info); | 743 coord_canvas_info_free(rdman, rdman->root_coord->canvas_info); |
751 | 744 |
752 /* XXX: paints are not freed, here. All resources of paints would | 745 /* XXX: paints are not freed, here. All resources of paints would |
753 * be reclaimed by freeing elmpools. | 746 * be reclaimed by freeing elmpools. |
1288 canvas2p[5] = shift_y; | 1281 canvas2p[5] = shift_y; |
1289 | 1282 |
1290 matrix_mul(paggr, canvas2p, canvas2pdev_matrix); | 1283 matrix_mul(paggr, canvas2p, canvas2pdev_matrix); |
1291 } | 1284 } |
1292 | 1285 |
1293 /*! \brief Compute area for a cached coord. | 1286 /*! \brief Compute area in parent cached coord for a cached coord. |
1294 * | 1287 * |
1295 * The coordination system of cached coord and descendants is resized, | 1288 * The coordination system of cached coord and descendants is resized, |
1296 * and shifted. It makes all descendants bound by a box, canvas box, | 1289 * and shifted. It makes all descendants bound by a box, canvas box, |
1297 * at 0, 0 and size is the same as the canvas. | 1290 * at 0, 0 and size is the same as the canvas. |
1298 * | 1291 * |
1299 * The bounding box where the canvas would be draw on the canvas on | 1292 * The bounding box where the canvas would be draw on the canvas on |
1300 * ancestral cached coord can be retreived by shifting and resizing | 1293 * ancestral cached coord can be retreived by shifting and resizing |
1301 * canvas box in reverse and transform to coordination system of | 1294 * canvas box in reverse and transform to coordination system of |
1302 * ancestral cached coord. | 1295 * ancestral cached coord. |
1303 */ | 1296 */ |
1304 static void compute_cached_coord_area(coord_t *coord) { | 1297 static void compute_pcache_area(coord_t *coord) { |
1305 co_aix *cached2pdev; | 1298 co_aix cached2pdev[6]; |
1306 int c_w, c_h; | 1299 int c_w, c_h; |
1307 canvas_t *canvas; | 1300 canvas_t *canvas; |
1308 co_aix poses[4][2]; | 1301 co_aix poses[4][2]; |
1309 | 1302 |
1310 compute_cached_2_pdev_matrix(coord, cached2pdev); | 1303 compute_cached_2_pdev_matrix(coord, cached2pdev); |
1323 matrix_trans_pos(cached2pdev, &poses[0][0], &poses[0][1]); | 1316 matrix_trans_pos(cached2pdev, &poses[0][0], &poses[0][1]); |
1324 matrix_trans_pos(cached2pdev, &poses[1][0], &poses[1][1]); | 1317 matrix_trans_pos(cached2pdev, &poses[1][0], &poses[1][1]); |
1325 matrix_trans_pos(cached2pdev, &poses[2][0], &poses[2][1]); | 1318 matrix_trans_pos(cached2pdev, &poses[2][0], &poses[2][1]); |
1326 matrix_trans_pos(cached2pdev, &poses[3][0], &poses[3][1]); | 1319 matrix_trans_pos(cached2pdev, &poses[3][0], &poses[3][1]); |
1327 | 1320 |
1328 area_init(coord_get_area(coord), 4, poses); | 1321 area_init(coord_get_pcache_area(coord), 4, poses); |
1329 } | 1322 } |
1330 | 1323 |
1331 static int coord_update_area_4_cached_children(coord_t *coord) { | 1324 /*! \brief Compute area of a coord. |
1332 coord_t *child; | 1325 */ |
1333 /*! \note poses is shared by invokings, it is not support reentrying. */ | 1326 static int |
1327 compute_area(coord_t *coord) { | |
1334 static co_aix (*poses)[2]; | 1328 static co_aix (*poses)[2]; |
1335 static int max_poses = 0; | 1329 static int max_poses = 0; |
1336 area_t *cur_area; | 1330 geo_t *geo; |
1337 int cnt, pos_cnt; | 1331 int cnt, pos_cnt; |
1338 | 1332 |
1339 cnt = 1; | 1333 cnt = 0; |
1340 FORCHILDREN(coord, child) { | 1334 FORMEMBERS(coord, geo) { |
1341 if(child->flags & COF_OWN_CANVAS) { | 1335 cnt++; |
1342 compute_cached_coord_area(child); | 1336 } |
1343 cnt++; | 1337 |
1344 } | |
1345 } | |
1346 | |
1347 if(max_poses < (cnt * 2)) { | 1338 if(max_poses < (cnt * 2)) { |
1348 free(poses); | 1339 free(poses); |
1349 max_poses = cnt * 2; | 1340 max_poses = cnt * 2; |
1350 poses = (co_aix (*)[2])malloc(sizeof(co_aix [2]) * max_poses); | 1341 poses = (co_aix (*)[2])malloc(sizeof(co_aix [2]) * max_poses); |
1351 if(poses == NULL) | 1342 if(poses == NULL) |
1352 return ERR; | 1343 return ERR; |
1353 } | 1344 } |
1354 | 1345 |
1355 pos_cnt = 0; | |
1356 FORCHILDREN(coord, child) { | |
1357 if(child->flags & COF_OWN_CANVAS) { | |
1358 area_to_positions(coord_get_area(child), poses + pos_cnt); | |
1359 pos_cnt += 2; | |
1360 } | |
1361 } | |
1362 | |
1363 cur_area = coord_get_area(coord); | |
1364 area_to_positions(cur_area, poses + pos_cnt); | |
1365 pos_cnt += 2; | |
1366 | |
1367 area_init(cur_area, pos_cnt, poses); | |
1368 | |
1369 return OK; | |
1370 } | |
1371 | |
1372 static int coord_clean_members_n_compute_area(coord_t *coord) { | |
1373 geo_t *geo; | |
1374 /*! \note poses is shared by invokings, it is not support reentrying. */ | |
1375 static co_aix (*poses)[2]; | |
1376 static int max_poses = 0; | |
1377 int cnt, pos_cnt; | |
1378 | |
1379 /* Clean member shapes. */ | |
1380 cnt = 0; | |
1381 FORMEMBERS(coord, geo) { | |
1382 clean_shape(geo->shape); | |
1383 cnt++; | |
1384 } | |
1385 | |
1386 if(max_poses < (cnt * 2)) { | |
1387 free(poses); | |
1388 max_poses = cnt * 2; | |
1389 poses = (co_aix (*)[2])malloc(sizeof(co_aix [2]) * max_poses); | |
1390 if(poses == NULL) | |
1391 return ERR; | |
1392 } | |
1393 | |
1394 /* Compute area of the coord. */ | |
1395 pos_cnt = 0; | 1346 pos_cnt = 0; |
1396 FORMEMBERS(coord, geo) { | 1347 FORMEMBERS(coord, geo) { |
1397 area_to_positions(geo->cur_area, poses + pos_cnt); | 1348 area_to_positions(geo->cur_area, poses + pos_cnt); |
1398 pos_cnt += 2; | 1349 pos_cnt += 2; |
1399 } | 1350 } |
1400 | 1351 |
1401 area_init(coord->cur_area, pos_cnt, poses); | 1352 area_init(coord_get_area(coord), pos_cnt, poses); |
1402 | 1353 |
1354 return OK; | |
1355 } | |
1356 | |
1357 static int coord_clean_members_n_compute_area(coord_t *coord) { | |
1358 geo_t *geo; | |
1359 int r; | |
1360 /*! \note poses is shared by invokings, it is not support reentrying. */ | |
1361 | |
1362 /* Clean member shapes. */ | |
1363 FORMEMBERS(coord, geo) { | |
1364 clean_shape(geo->shape); | |
1365 } | |
1366 | |
1367 r = compute_area(coord); | |
1368 if(r != OK) | |
1369 return ERR; | |
1370 | |
1403 return OK; | 1371 return OK; |
1404 } | 1372 } |
1405 | 1373 |
1406 /*! \brief Clean dirty coords. | 1374 /*! \brief Clean dirty coords. |
1375 * | |
1376 * This function compute aggregation matrix and area for dirty | |
1377 * coords. But, aggregation matrix of a cached coord is different from | |
1378 * normal one. (see compute_aggr_of_cached_coord()). | |
1407 * | 1379 * |
1408 * \note coords their opacity != 1 are also traded as cached ones. | 1380 * \note coords their opacity != 1 are also traded as cached ones. |
1409 */ | 1381 */ |
1410 static int clean_coord(redraw_man_t *rdman, coord_t *coord) { | 1382 static int clean_coord(redraw_man_t *rdman, coord_t *coord) { |
1411 int r; | 1383 int r; |
1412 | 1384 |
1413 setup_canvas_info(rdman, coord); | 1385 setup_canvas_info(rdman, coord); |
1414 | 1386 |
1415 if(coord->flags & COF_OWN_CANVAS) | 1387 compute_aggr(coord); |
1416 compute_aggr_of_cached_coord(coord); | |
1417 else | |
1418 compute_aggr_of_coord(coord); | |
1419 | 1388 |
1420 /* Areas of cached coords are computed in two phase. | 1389 /* Areas of cached coords are computed in two phase. |
1421 * Phase 1 works like other normal ones. Phase 2, collects | 1390 * Phase 1 works like other normal ones. Phase 2, collects |
1422 * all areas of descendants to compute a minimum covering area. | 1391 * all areas of descendants to compute a minimum covering area. |
1423 * Phase 2 is performed by zeroing_coord(). | 1392 * Phase 2 is performed by zeroing_coord(). |
1424 */ | 1393 */ |
1425 r = coord_clean_members_n_compute_area(coord); | 1394 r = coord_clean_members_n_compute_area(coord); |
1426 if(r != OK) | 1395 if(r != OK) |
1427 return ERR; | 1396 return ERR; |
1428 | 1397 |
1429 r = coord_update_area_4_cached_children(coord); | |
1430 if(r != OK) | |
1431 return ERR; | |
1432 | |
1433 coord->flags &= ~COF_DIRTY; | 1398 coord->flags &= ~COF_DIRTY; |
1434 | 1399 |
1435 return OK; | 1400 return OK; |
1436 } | 1401 } |
1437 | 1402 |
1438 /*! \brief Clean coord_t objects. | 1403 /*! \brief Clean coord_t objects. |
1439 * | 1404 * |
1440 * It computes aggregation matrix and area for dirty coords. | 1405 * It computes aggregation matrix and area for dirty coords. |
1406 * | |
1407 * This function also responsible for computing area of parent cached | |
1408 * coord, coord_canvas_info_t::pcache_cur_area, for its cached children. | |
1441 */ | 1409 */ |
1442 static int clean_rdman_coords(redraw_man_t *rdman) { | 1410 static int clean_rdman_coords(redraw_man_t *rdman) { |
1443 coord_t *coord; | 1411 coord_t *coord, *child; |
1444 coord_t **dirty_coords; | 1412 coord_t **dirty_coords; |
1445 int n_dirty_coords; | 1413 int n_dirty_coords; |
1446 int i, r; | 1414 int i, r; |
1447 | 1415 |
1448 n_dirty_coords = rdman->dirty_coords.num; | 1416 n_dirty_coords = rdman->dirty_coords.num; |
1455 if(!(coord->flags & COF_DIRTY)) | 1423 if(!(coord->flags & COF_DIRTY)) |
1456 continue; | 1424 continue; |
1457 r = clean_coord(rdman, coord); | 1425 r = clean_coord(rdman, coord); |
1458 if(r != OK) | 1426 if(r != OK) |
1459 return ERR; | 1427 return ERR; |
1428 /* TODO: ponstponse adding dirty areas until zeroing. | |
1429 * Because, aggregated matrix would changed when | |
1430 * zeroing | |
1431 */ | |
1460 /* These two steps can be avoided for drawing all. */ | 1432 /* These two steps can be avoided for drawing all. */ |
1461 add_dirty_area(rdman, coord, &coord->areas[0]); | 1433 add_dirty_area(rdman, coord, &coord->areas[0]); |
1462 add_dirty_area(rdman, coord, &coord->areas[1]); | 1434 add_dirty_area(rdman, coord, &coord->areas[1]); |
1435 | |
1436 /* Computes coord_canvas_info_t::pcache_cur_area */ | |
1437 FORCHILDREN(coord, child) { | |
1438 if(coord_get_flags(child, COF_OWN_CANVAS)) { | |
1439 SWAP(child->canvas_info->pcache_cur_area, | |
1440 child->canvas_info->pcache_last_area, | |
1441 area_t *); | |
1442 compute_pcache_area(child); | |
1443 add_dirty_area(rdman, coord, | |
1444 coord_get_pcache_area(child)); | |
1445 add_dirty_area(rdman, coord, | |
1446 coord_get_pcache_last_area(child)); | |
1447 } | |
1448 } | |
1463 } | 1449 } |
1464 } | 1450 } |
1465 return OK; | 1451 return OK; |
1466 } | 1452 } |
1467 | 1453 |
1516 coord_clear_zeroing(coord); | 1502 coord_clear_zeroing(coord); |
1517 | 1503 |
1518 /* | 1504 /* |
1519 * Compute minimum overing area of sub-graphic | 1505 * Compute minimum overing area of sub-graphic |
1520 */ | 1506 */ |
1521 area = &coord->canvas_info->owner_mems_area; | 1507 area = coord_get_area(coord); |
1522 min_x = area->x; | 1508 min_x = area->x; |
1523 min_y = area->y; | 1509 min_y = area->y; |
1524 max_x = min_x + area->w; | 1510 max_x = min_x + area->w; |
1525 max_y = min_y + area->h; | 1511 max_y = min_y + area->h; |
1526 | 1512 |
1566 /* | 1552 /* |
1567 * Adjust matrics of descendants to align left-top corner of | 1553 * Adjust matrics of descendants to align left-top corner of |
1568 * minimum covering area with origin of space defined by | 1554 * minimum covering area with origin of space defined by |
1569 * zeroing coord. | 1555 * zeroing coord. |
1570 */ | 1556 */ |
1571 saved_area = coord_get_area(coord); | |
1572 coord->cur_area = &coord->canvas_info->owner_mems_area; | |
1573 FOR_COORDS_PREORDER(coord, cur) { | 1557 FOR_COORDS_PREORDER(coord, cur) { |
1558 if(coord_get_flags(cur, COF_OWN_CANVAS) && coord != cur) { | |
1559 /* | |
1560 * Cached coords are zeroed from root to leaves, so | |
1561 * changes of aggr_matrix would be propagated to next | |
1562 * level of cached. | |
1563 */ | |
1564 preorder_coord_skip_subtree(cur); | |
1565 } | |
1566 /* Shift space */ | |
1574 aggr = coord_get_aggr_matrix(cur); | 1567 aggr = coord_get_aggr_matrix(cur); |
1575 aggr[3] -= min_x; | 1568 aggr[3] -= min_x; |
1576 aggr[5] -= min_y; | 1569 aggr[5] -= min_y; |
1577 if(coord_get_flags(cur, COF_OWN_CANVAS) && coord != cur) { | 1570 |
1578 /* | 1571 coord_clean_members_n_compute_area(cur); |
1579 * Coords, zeroing, is zeroed in preorder of tree. | 1572 } |
1580 * So, they are zeroed after ancesters with correctly | |
1581 * coord_t::aggr_matrix of parent coord to zeroing. | |
1582 */ | |
1583 preorder_coord_skip_subtree(cur); | |
1584 #if 0 | |
1585 /* Parent had called coord_clean_members_n_compute_area(). | |
1586 * So, the area of this coord had been recomputed. | |
1587 */ | |
1588 area = coord_get_area(cur); | |
1589 area->x -= min_x; | |
1590 area->y -= min_y; | |
1591 #endif | |
1592 } else { | |
1593 coord_clean_members_n_compute_area(cur); | |
1594 coord_update_area_4_cached_children(cur); | |
1595 } | |
1596 } | |
1597 coord->cur_area = saved_area; | |
1598 | 1573 |
1599 /* | 1574 /* |
1600 * Setup canvas | 1575 * Setup canvas |
1576 * | |
1577 * Canvas of a cached coord is not setted in | |
1578 * coord_canvas_info_new(). It should be setted, here. | |
1601 */ | 1579 */ |
1602 if(canvas == NULL || w > c_w || h > c_w) { | 1580 if(canvas == NULL || w > c_w || h > c_w) { |
1603 if(canvas) | 1581 if(canvas) |
1604 canvas_free(canvas); | 1582 canvas_free(canvas); |
1605 canvas = canvas_new(w, h); | 1583 canvas = canvas_new(w, h); |
1606 _coord_set_canvas(coord, canvas); | 1584 _coord_set_canvas(coord, canvas); |
1607 } | 1585 } |
1608 | 1586 |
1609 compute_cached_coord_area(coord); | 1587 compute_pcache_area(coord); |
1610 | 1588 |
1611 /* Since aggregated matrix had been changed to make descendants | 1589 /* Since aggregated matrix had been changed to make descendants |
1612 * falling on the canvas, size or/and position of all descendants | 1590 * falling on the canvas, size or/and position of all descendants |
1613 * are chagned, and new canvas was created. So, a dirty area that | 1591 * are chagned, and new canvas was created. So, a dirty area that |
1614 * covers all space of the canvas is created to force redrawing | 1592 * covers all space of the canvas is created to force redrawing |
1637 /* Mark all cached ancestral coords of dirty geos */ | 1615 /* Mark all cached ancestral coords of dirty geos */ |
1638 n_dirty_geos = rdman->dirty_geos.num; | 1616 n_dirty_geos = rdman->dirty_geos.num; |
1639 dirty_geos = rdman->dirty_geos.ds; | 1617 dirty_geos = rdman->dirty_geos.ds; |
1640 for(i = 0; i < n_dirty_geos; i++) { | 1618 for(i = 0; i < n_dirty_geos; i++) { |
1641 geo = dirty_geos[i]; | 1619 geo = dirty_geos[i]; |
1642 coord = geo_get_coord(geo)->canvas_info->owner; | 1620 coord = coord_get_cached(geo_get_coord(geo)); |
1643 while(!coord_get_flags(coord, COF_MUST_ZEROING | COF_TEMP_MARK)) { | 1621 while(!coord_get_flags(coord, COF_MUST_ZEROING | COF_TEMP_MARK)) { |
1644 if(coord_is_root(coord)) | 1622 if(coord_is_root(coord)) |
1645 break; | 1623 break; |
1646 coord_set_flags(coord, COF_TEMP_MARK); | 1624 coord_set_flags(coord, COF_TEMP_MARK); |
1647 coord = coord->parent->canvas_info->owner; | 1625 coord = coord_get_cached(coord_get_parent(coord)); |
1648 } | 1626 } |
1649 } | 1627 } |
1650 | 1628 |
1651 /* Mark all cached ancestral coords of dirty coords */ | 1629 /* Mark all cached ancestral coords of dirty coords */ |
1652 n_dirty_coords = rdman->dirty_coords.num; | 1630 n_dirty_coords = rdman->dirty_coords.num; |
1653 dirty_coords = rdman->dirty_coords.ds; | 1631 dirty_coords = rdman->dirty_coords.ds; |
1654 for(i = 0; i < n_dirty_coords; i++) { | 1632 for(i = 0; i < n_dirty_coords; i++) { |
1655 coord = dirty_coords[i]->canvas_info->owner; | 1633 coord = coord_get_cached(dirty_coords[i]); |
1656 while(!coord_get_flags(coord, COF_MUST_ZEROING | COF_TEMP_MARK)) { | 1634 while(!coord_get_flags(coord, COF_MUST_ZEROING | COF_TEMP_MARK)) { |
1657 if(coord_is_root(coord)) | 1635 if(coord_is_root(coord)) |
1658 break; | 1636 break; |
1659 coord_set_flags(coord, COF_TEMP_MARK); | 1637 coord_set_flags(coord, COF_TEMP_MARK); |
1660 coord = coord->parent->canvas_info->owner; | 1638 coord = coord_get_cached(coord_get_parent(coord)); |
1661 } | 1639 } |
1662 } | 1640 } |
1663 | 1641 |
1664 /* Add all marked coords into redraw_man_t::zeroing_coords list */ | 1642 /* Add all marked coords into redraw_man_t::zeroing_coords list */ |
1665 FOR_COORDS_PREORDER(rdman->root_coord, coord) { | 1643 FOR_COORDS_PREORDER(rdman->root_coord, coord) { |
1686 int i; | 1664 int i; |
1687 coords_t *all_zeroing; | 1665 coords_t *all_zeroing; |
1688 coord_t *coord; | 1666 coord_t *coord; |
1689 | 1667 |
1690 all_zeroing = &rdman->zeroing_coords; | 1668 all_zeroing = &rdman->zeroing_coords; |
1691 for(i = all_zeroing->num - 1; i >= 0; i--) { | 1669 for(i = 0; i < all_zeroing->num; i++) { |
1692 coord = all_zeroing->ds[i]; | 1670 coord = all_zeroing->ds[i]; |
1693 zeroing_coord(rdman, coord); | 1671 zeroing_coord(rdman, coord); |
1694 } | 1672 } |
1695 | 1673 |
1696 return OK; | 1674 return OK; |
1704 */ | 1682 */ |
1705 static void add_aggr_dirty_areas_to_ancestor(redraw_man_t *rdman, | 1683 static void add_aggr_dirty_areas_to_ancestor(redraw_man_t *rdman, |
1706 coord_t *coord) { | 1684 coord_t *coord) { |
1707 int i; | 1685 int i; |
1708 int n_areas; | 1686 int n_areas; |
1687 int enable_poses1 = 0; | |
1709 co_aix poses0[2][2], poses1[2][2]; | 1688 co_aix poses0[2][2], poses1[2][2]; |
1710 co_aix reverse[6]; | 1689 co_aix reverse[6]; |
1711 co_aix canvas2pdev_matrix[6]; | 1690 co_aix canvas2pdev_matrix[6]; |
1712 area_t **areas, *area; | 1691 area_t **areas, *area; |
1713 area_t *area0, *area1; | 1692 area_t *area0, *area1; |
1716 n_areas = _coord_get_dirty_areas(coord)->num; | 1695 n_areas = _coord_get_dirty_areas(coord)->num; |
1717 areas = _coord_get_dirty_areas(coord)->ds; | 1696 areas = _coord_get_dirty_areas(coord)->ds; |
1718 if(n_areas == 0) | 1697 if(n_areas == 0) |
1719 abort(); /* should not happen! */ | 1698 abort(); /* should not happen! */ |
1720 | 1699 |
1721 area0 = coord->canvas_info->aggr_dirty_areas; | 1700 area0 = _coord_get_aggr_dirty_areas(coord); |
1722 area1 = area0 + 1; | 1701 area1 = area0 + 1; |
1723 | 1702 |
1724 /* TODO: Since both cur & last area of coords are added into dirty | 1703 /* TODO: Since both cur & last area of coords are added into dirty |
1725 * area list, position of both areas shoud be adjusted for | 1704 * area list, position of both areas shoud be adjusted for |
1726 * all descendants when zeroing a cached coord. | 1705 * all descendants when zeroing a cached coord. |
1729 area = areas[i]; | 1708 area = areas[i]; |
1730 if(area->w != 0 || area->h != 0) | 1709 if(area->w != 0 || area->h != 0) |
1731 break; | 1710 break; |
1732 } | 1711 } |
1733 | 1712 |
1734 if(i < n_areas) { | 1713 if(i >= n_areas) |
1735 area = areas[i++]; | 1714 return; |
1736 poses0[0][0] = area->x; | 1715 |
1737 poses0[0][1] = area->y; | 1716 area = areas[i++]; |
1738 poses0[1][0] = area->x + area->w; | 1717 poses0[0][0] = area->x; |
1739 poses0[1][1] = area->y + area->h; | 1718 poses0[0][1] = area->y; |
1740 } else { | 1719 poses0[1][0] = area->x + area->w; |
1741 poses0[0][0] = 0; | 1720 poses0[1][1] = area->y + area->h; |
1742 poses0[0][1] = 0; | |
1743 poses0[1][0] = 0; | |
1744 poses0[1][1] = 0; | |
1745 } | |
1746 | 1721 |
1747 if(i < n_areas) { | 1722 if(i < n_areas) { |
1748 area = areas[i++]; | 1723 area = areas[i++]; |
1749 poses1[0][0] = area->x; | 1724 poses1[0][0] = area->x; |
1750 poses1[0][1] = area->y; | 1725 poses1[0][1] = area->y; |
1754 poses1[0][0] = 0; | 1729 poses1[0][0] = 0; |
1755 poses1[0][1] = 0; | 1730 poses1[0][1] = 0; |
1756 poses1[1][0] = 0; | 1731 poses1[1][0] = 0; |
1757 poses1[1][1] = 0; | 1732 poses1[1][1] = 0; |
1758 } | 1733 } |
1759 | 1734 |
1760 for(; i < n_areas - 1;) { | 1735 for(; i < n_areas - 1;) { |
1761 /* Even areas */ | 1736 /* Even areas */ |
1762 area = areas[i++]; | 1737 area = areas[i++]; |
1763 if(area->w != 0 || area->h != 0) { | 1738 if(area->w != 0 || area->h != 0) { |
1764 poses0[0][0] = MB_MIN(poses0[0][0], area->x); | 1739 poses0[0][0] = MB_MIN(poses0[0][0], area->x); |
1773 poses1[0][1] = MB_MIN(poses1[0][1], area->y); | 1748 poses1[0][1] = MB_MIN(poses1[0][1], area->y); |
1774 poses1[1][0] = MB_MAX(poses1[1][0], area->x + area->w); | 1749 poses1[1][0] = MB_MAX(poses1[1][0], area->x + area->w); |
1775 poses1[1][1] = MB_MAX(poses1[1][1], area->y + area->h); | 1750 poses1[1][1] = MB_MAX(poses1[1][1], area->y + area->h); |
1776 } | 1751 } |
1777 } | 1752 } |
1778 | 1753 |
1779 if(i < n_areas) { | 1754 if(i < n_areas) { |
1780 area = areas[i]; | 1755 area = areas[i]; |
1781 if(area->w != 0 || area->h != 0) { | 1756 if(area->w != 0 || area->h != 0) { |
1782 poses0[0][0] = MB_MIN(poses0[0][0], area->x); | 1757 poses0[0][0] = MB_MIN(poses0[0][0], area->x); |
1783 poses0[0][1] = MB_MIN(poses0[0][1], area->y); | 1758 poses0[0][1] = MB_MIN(poses0[0][1], area->y); |
1784 poses0[1][0] = MB_MAX(poses0[1][0], area->x + area->w); | 1759 poses0[1][0] = MB_MAX(poses0[1][0], area->x + area->w); |
1785 poses0[1][1] = MB_MAX(poses0[1][1], area->y + area->h); | 1760 poses0[1][1] = MB_MAX(poses0[1][1], area->y + area->h); |
1786 } | 1761 } |
1787 } | 1762 } |
1788 | 1763 |
1789 parent = coord->parent; | 1764 parent = coord_get_parent(coord); |
1790 pcached_coord = parent->canvas_info->owner; | 1765 pcached_coord = coord_get_cached(parent); |
1791 | 1766 |
1792 compute_cached_2_pdev_matrix(coord, canvas2pdev_matrix); | 1767 compute_cached_2_pdev_matrix(coord, canvas2pdev_matrix); |
1793 | 1768 |
1794 /* Add dirty areas to parent cached coord. */ | 1769 /* Add dirty areas to parent cached coord. */ |
1795 matrix_trans_pos(canvas2pdev_matrix, poses0[0], poses0[0] + 1); | 1770 matrix_trans_pos(canvas2pdev_matrix, poses0[0], poses0[0] + 1); |
1796 matrix_trans_pos(canvas2pdev_matrix, poses0[1], poses0[1] + 1); | 1771 matrix_trans_pos(canvas2pdev_matrix, poses0[1], poses0[1] + 1); |
1797 area_init(area0, 2, poses0); | 1772 area_init(area0, 2, poses0); |
1798 add_dirty_area(rdman, pcached_coord, area0); | 1773 add_dirty_area(rdman, pcached_coord, area0); |
1799 | 1774 |
1800 matrix_trans_pos(canvas2pdev_matrix, poses1[0], poses1[0] + 1); | 1775 matrix_trans_pos(canvas2pdev_matrix, poses1[0], poses1[0] + 1); |
1801 matrix_trans_pos(canvas2pdev_matrix, poses1[1], poses1[1] + 1); | 1776 matrix_trans_pos(canvas2pdev_matrix, poses1[1], poses1[1] + 1); |
1802 area_init(area1, 2, poses1); | 1777 area_init(area1, 2, poses1); |
1803 if(area1->w != 0 || area1->h != 0) | 1778 add_dirty_area(rdman, pcached_coord, area1); |
1804 if(area0->x != area1->x || area0->y != area1->y || | |
1805 area0->w != area1->w || area0->h != area1->h) | |
1806 add_dirty_area(rdman, pcached_coord, area1); | |
1807 | 1779 |
1808 if(coord_get_flags(coord, COF_JUST_CLEAN) && | 1780 if(coord_get_flags(coord, COF_JUST_CLEAN) && |
1809 !coord_get_flags(pcached_coord, COF_JUST_CLEAN)) | 1781 !coord_get_flags(pcached_coord, COF_JUST_CLEAN)) |
1810 add_dirty_area(rdman, pcached_coord, coord->last_area); | 1782 add_dirty_area(rdman, pcached_coord, coord->last_area); |
1811 } | 1783 } |
1820 */ | 1792 */ |
1821 static int add_rdman_aggr_dirty_areas(redraw_man_t *rdman) { | 1793 static int add_rdman_aggr_dirty_areas(redraw_man_t *rdman) { |
1822 int i; | 1794 int i; |
1823 int n_zeroing; | 1795 int n_zeroing; |
1824 coord_t **zeroings; | 1796 coord_t **zeroings; |
1825 coord_t *coord; | 1797 coord_t *coord, *pcached_coord; |
1826 | 1798 |
1827 n_zeroing = rdman->zeroing_coords.num; | 1799 n_zeroing = rdman->zeroing_coords.num; |
1828 zeroings = rdman->zeroing_coords.ds; | 1800 zeroings = rdman->zeroing_coords.ds; |
1829 for(i = n_zeroing - 1; i >= 0; i--) { | 1801 for(i = n_zeroing - 1; i >= 0; i--) { |
1830 coord = zeroings[i]; | 1802 coord = zeroings[i]; |
1831 if(!coord_is_root(coord)) | 1803 pcached_coord = coord_get_cached(coord_get_parent(coord)); |
1804 if(!coord_is_root(coord) && !coord_is_zeroing(pcached_coord)) | |
1832 add_aggr_dirty_areas_to_ancestor(rdman, coord); | 1805 add_aggr_dirty_areas_to_ancestor(rdman, coord); |
1833 } | 1806 } |
1834 | 1807 |
1835 return OK; | 1808 return OK; |
1836 } | 1809 } |
1864 * | 1837 * |
1865 * The procedure of clean dirty coords and shapes include 3 major steps. | 1838 * The procedure of clean dirty coords and shapes include 3 major steps. |
1866 * | 1839 * |
1867 * - Add dirty coords and shapes to rdman. | 1840 * - Add dirty coords and shapes to rdman. |
1868 * - All descendants of a dirty coord are also dirty, except | 1841 * - All descendants of a dirty coord are also dirty, except |
1869 * descent coords and their descendants. | 1842 * descendants of cached descendants. |
1870 * - Recompute aggregated transformation matrix from root to leaves | 1843 * - Recompute aggregated transformation matrix from root to leaves |
1871 * for dirty coords. | 1844 * for dirty coords. |
1872 * - The aggregated transformation matrix for a cached coord is | 1845 * - The aggregated transformation matrix for a cached coord is |
1873 * different from other coords. | 1846 * different from other coords. |
1874 * - Compute new area for every dirty coord. | 1847 * - Compute new area for every dirty coord. |
1875 * - Area of a dirty coord is an aggregation of areas of all members. | 1848 * - Area of a dirty coord is an aggregation of areas of all members. |
1876 * - A cached coord has two type of areas, one is for members of the cached | 1849 * - A cached coord has two type of areas, one is for members of the cached |
1877 * coord, another one is for the block that cached coord and descendants | 1850 * coord, another one is for the block that cached coord and descendants |
1878 * will be mapped in parent cached coord. | 1851 * will be mapped in parent cached coord. |
1879 * - Areas, for parent cached coord, of non-dirty cached coord | 1852 * - Areas, for parent cached coord (pcache_cur_area), of |
1880 * would be recomputed when cleaning parent coord. | 1853 * non-dirty cached coord would be recomputed when cleaning |
1854 * parent coord. | |
1855 * - Areas, for parent cached coord (pcache_cur_area), of dirty | |
1856 * cached coord would be recomputed when zeroing the cached | |
1857 * coord. (because zeroing would change aggregated matrix, and | |
1858 * zeroing was performed after cleaning) | |
1881 * - Areas, for members, of dirty cached coord would only be | 1859 * - Areas, for members, of dirty cached coord would only be |
1882 * recomputed when cleaning the coord. | 1860 * recomputed when cleaning the coord. |
1861 * - Perform zeroing on some cached coords that | |
1862 * - dirty, is, | |
1863 * - dirty descendants, has. | |
1883 * - Propagate dirty areas to dirty area list of parent cached coord | 1864 * - Propagate dirty areas to dirty area list of parent cached coord |
1884 * for every cached coords, not only for dirty cached coords. | 1865 * for every cached coords, not only for dirty cached coords. |
1885 * | 1866 * |
1886 * The cur_area of a cached coord is where members of the coord will | 1867 * The cur_area of a cached coord is where members of the coord will |
1887 * be draw in cache buffer, i.e. surface. The area of the cached | 1868 * be draw in cache buffer, i.e. surface. The area of the cached |
1888 * coord and descendants is described by cached_cur_area and | 1869 * coord and descendants is described by pcache_cur_area and |
1889 * cached_last_area in coord_canvas_info_t. | 1870 * pcache_last_area in coord_canvas_info_t. |
1890 */ | 1871 */ |
1891 static int clean_rdman_dirties(redraw_man_t *rdman) { | 1872 static int rdman_clean_dirties(redraw_man_t *rdman) { |
1892 int r; | 1873 int r; |
1893 int i; | 1874 int i; |
1894 coord_t **coords, *coord; | 1875 coord_t **coords, *coord; |
1895 geo_t **geos; | 1876 geo_t **geos; |
1896 | 1877 |
1899 * by clean_coord(). | 1880 * by clean_coord(). |
1900 */ | 1881 */ |
1901 coords = rdman->dirty_coords.ds; | 1882 coords = rdman->dirty_coords.ds; |
1902 for(i = 0; i < rdman->dirty_coords.num; i++) { | 1883 for(i = 0; i < rdman->dirty_coords.num; i++) { |
1903 coord = coords[i]; | 1884 coord = coords[i]; |
1904 if(!coord_get_flags(coord, COF_OWN_CANVAS)) | 1885 SWAP(coord->cur_area, coord->last_area, area_t *); |
1905 SWAP(coord->cur_area, coord->last_area, area_t *); | |
1906 else { | |
1907 coord->last_area = coord->cur_area; | |
1908 coord->cur_area = &coord->canvas_info->owner_mems_area; | |
1909 /* coord->cur_area are reseted to another area at | |
1910 * #RST. | |
1911 * | |
1912 * coord->cur_area of a cached coord is aggregated | |
1913 * area. But, its meaning is changed back to be area | |
1914 * of members to compute. It can avoid specialized | |
1915 * code for cached coords to change meaning of | |
1916 * cur_area temporary when computing area of a cached | |
1917 * coord. | |
1918 */ | |
1919 } | |
1920 } | 1886 } |
1921 | 1887 |
1922 geos = rdman->dirty_geos.ds; | 1888 geos = rdman->dirty_geos.ds; |
1923 for(i = 0; i < rdman->dirty_geos.num; i++) | 1889 for(i = 0; i < rdman->dirty_geos.num; i++) |
1924 if(geos[i]->flags & GEF_DIRTY) | 1890 if(geos[i]->flags & GEF_DIRTY) |
1925 SWAP(geos[i]->cur_area, geos[i]->last_area, area_t *); | 1891 SWAP(geos[i]->cur_area, geos[i]->last_area, area_t *); |
1926 | 1892 |
1927 r = clean_rdman_coords(rdman); | 1893 r = clean_rdman_coords(rdman); |
1928 if(r != OK) | 1894 if(r != OK) |
1929 return ERR; | 1895 return ERR; |
1930 | 1896 |
1897 /* Mark COF_JUST_CLEAN */ | |
1931 coords = rdman->dirty_coords.ds; | 1898 coords = rdman->dirty_coords.ds; |
1932 for(i = 0; i < rdman->dirty_coords.num; i++) { | 1899 for(i = 0; i < rdman->dirty_coords.num; i++) { |
1933 /* Mark dirty coords COF_JUST_CLEAN to identify coords that | 1900 /* Mark dirty coords COF_JUST_CLEAN to identify coords that |
1934 * has changed their matrix and respective coordination | 1901 * has changed their matrix and respective coordination |
1935 * system. It helps zeroing_coord() to avoid fully redrawing | 1902 * system. It helps zeroing_coord() to avoid fully redrawing |
1936 * all descednants of a cached coord that had not changed its | 1903 * all descednants of a cached coord that had not changed its |
1937 * matrix. | 1904 * matrix. |
1938 */ | 1905 */ |
1939 coord = coords[i]; | 1906 coord = coords[i]; |
1940 coord_set_flags(coord, COF_JUST_CLEAN); | 1907 coord_set_flags(coord, COF_JUST_CLEAN); |
1941 | 1908 } |
1942 /* #RST: reset coord->cur_area, here */ | 1909 /* TODO: save area of cached coord and descendants in |
1943 coord->cur_area = | 1910 * cached_dirty_area for parent cached coord space. |
1944 (coord->last_area == coord->areas)? | 1911 */ |
1945 coord->areas + 1: coord->areas; | |
1946 } | |
1947 | 1912 |
1948 r = clean_rdman_geos(rdman); | 1913 r = clean_rdman_geos(rdman); |
1949 if(r != OK) | 1914 if(r != OK) |
1950 return ERR; | 1915 return ERR; |
1951 | 1916 |
2264 int i; | 2229 int i; |
2265 coord_t *coord, **coords; | 2230 coord_t *coord, **coords; |
2266 int n_areas; | 2231 int n_areas; |
2267 area_t **areas; | 2232 area_t **areas; |
2268 | 2233 |
2269 r = clean_rdman_dirties(rdman); | 2234 r = rdman_clean_dirties(rdman); |
2270 if(r != OK) | 2235 if(r != OK) |
2271 return ERR; | 2236 return ERR; |
2272 | 2237 |
2273 if(rdman->n_dirty_areas > 0) { | 2238 if(rdman->n_dirty_areas > 0) { |
2274 /*! \brief Draw shapes in preorder of coord tree and support opacity | 2239 /*! \brief Draw shapes in preorder of coord tree and support opacity |
2381 } | 2346 } |
2382 | 2347 |
2383 int rdman_force_clean(redraw_man_t *rdman) { | 2348 int rdman_force_clean(redraw_man_t *rdman) { |
2384 int r; | 2349 int r; |
2385 | 2350 |
2386 r = clean_rdman_dirties(rdman); | 2351 r = rdman_clean_dirties(rdman); |
2387 | 2352 |
2388 return r; | 2353 return r; |
2389 } | 2354 } |
2390 | 2355 |
2391 /*! \page man_obj Manage Objects. | 2356 /*! \page man_obj Manage Objects. |