Mercurial > MadButterfly
comparison src/redraw_man.c @ 536:b6b3dbeaedf3 Android_Skia
[mq]: pcached_area1.diff
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Fri, 21 May 2010 22:59:26 +0800 |
parents | a545f126d2bf |
children | 3a7e3c1cd6e6 |
comparison
equal
deleted
inserted
replaced
535:a545f126d2bf | 536:b6b3dbeaedf3 |
---|---|
469 coord_set_zeroing(coord); | 469 coord_set_zeroing(coord); |
470 ADD_DATA(coords, zeroing_coords, coord); | 470 ADD_DATA(coords, zeroing_coords, coord); |
471 return OK; | 471 return OK; |
472 } | 472 } |
473 | 473 |
474 static int add_dirty_pcache_area_coord(rdraw_man_t *rdman, coord_t *coord) { | |
475 coord_set_flags(coord, COF_DIRTY_PCACHE_AREA); | |
476 ADD_DATA(coords, dirty_pcache_area_coords, coord); | |
477 return OK; | |
478 } | |
479 | |
474 static int add_free_obj(redraw_man_t *rdman, void *obj, | 480 static int add_free_obj(redraw_man_t *rdman, void *obj, |
475 free_func_t free_func) { | 481 free_func_t free_func) { |
476 int max; | 482 int max; |
477 free_obj_t *new_objs, *free_obj; | 483 free_obj_t *new_objs, *free_obj; |
478 | 484 |
614 extern void addrm_monitor_hdlr(event_t *evt, void *arg); | 620 extern void addrm_monitor_hdlr(event_t *evt, void *arg); |
615 | 621 |
616 memset(rdman, 0, sizeof(redraw_man_t)); | 622 memset(rdman, 0, sizeof(redraw_man_t)); |
617 | 623 |
618 DARRAY_INIT(&rdman->dirty_coords); | 624 DARRAY_INIT(&rdman->dirty_coords); |
625 DARRAY_INIT(&rdman->dirty_pcache_area_coords); | |
619 DARRAY_INIT(&rdman->dirty_geos); | 626 DARRAY_INIT(&rdman->dirty_geos); |
620 DARRAY_INIT(&rdman->gen_geos); | 627 DARRAY_INIT(&rdman->gen_geos); |
621 DARRAY_INIT(&rdman->zeroing_coords); | 628 DARRAY_INIT(&rdman->zeroing_coords); |
622 | 629 |
623 rdman->geo_pool = elmpool_new(sizeof(geo_t), 128); | 630 rdman->geo_pool = elmpool_new(sizeof(geo_t), 128); |
660 coord_init(rdman->root_coord, NULL); | 667 coord_init(rdman->root_coord, NULL); |
661 mb_prop_store_init(&rdman->root_coord->obj.props, rdman->pent_pool); | 668 mb_prop_store_init(&rdman->root_coord->obj.props, rdman->pent_pool); |
662 rdman->root_coord->mouse_event = subject_new(&rdman->ob_factory, | 669 rdman->root_coord->mouse_event = subject_new(&rdman->ob_factory, |
663 rdman->root_coord, | 670 rdman->root_coord, |
664 OBJT_COORD); | 671 OBJT_COORD); |
665 rdman->root_coord->flags |= COF_OWN_CANVAS; | 672 coord_set_flags(rdman->root_coord, COF_OWN_CANVAS); |
666 rdman->root_coord->canvas_info = | 673 rdman->root_coord->canvas_info = |
667 coord_canvas_info_new(rdman, rdman->root_coord, cr); | 674 coord_canvas_info_new(rdman, rdman->root_coord, cr); |
668 rdman->root_coord->opacity = 1; | 675 rdman->root_coord->opacity = 1; |
669 | 676 |
670 rdman->cr = cr; | 677 rdman->cr = cr; |
699 if(rdman->pent_pool) | 706 if(rdman->pent_pool) |
700 elmpool_free(rdman->pent_pool); | 707 elmpool_free(rdman->pent_pool); |
701 if(rdman->coord_canvas_pool) | 708 if(rdman->coord_canvas_pool) |
702 elmpool_free(rdman->coord_canvas_pool); | 709 elmpool_free(rdman->coord_canvas_pool); |
703 DARRAY_DESTROY(&rdman->dirty_coords); | 710 DARRAY_DESTROY(&rdman->dirty_coords); |
711 DARRAY_DESTROY(&rdman->dirty_pcache_area_coords); | |
704 DARRAY_DESTROY(&rdman->dirty_geos); | 712 DARRAY_DESTROY(&rdman->dirty_geos); |
705 DARRAY_DESTROY(&rdman->gen_geos); | 713 DARRAY_DESTROY(&rdman->gen_geos); |
706 DARRAY_DESTROY(&rdman->zeroing_coords); | 714 DARRAY_DESTROY(&rdman->zeroing_coords); |
707 return ERR; | 715 return ERR; |
708 } | 716 } |
719 | 727 |
720 /* Mark rdman clean that shapes and coords can be freed | 728 /* Mark rdman clean that shapes and coords can be freed |
721 * successfully. | 729 * successfully. |
722 */ | 730 */ |
723 DARRAY_CLEAN(&rdman->dirty_coords); | 731 DARRAY_CLEAN(&rdman->dirty_coords); |
732 DARRAY_CLEAN(&rdman->dirty_pcache_area_coords); | |
724 DARRAY_CLEAN(&rdman->dirty_geos); | 733 DARRAY_CLEAN(&rdman->dirty_geos); |
725 | 734 |
726 coord = postorder_coord_subtree(rdman->root_coord, NULL); | 735 coord = postorder_coord_subtree(rdman->root_coord, NULL); |
727 while(coord) { | 736 while(coord) { |
728 saved_coord = coord; | 737 saved_coord = coord; |
754 elmpool_free(rdman->paint_color_pool); | 763 elmpool_free(rdman->paint_color_pool); |
755 elmpool_free(rdman->pent_pool); | 764 elmpool_free(rdman->pent_pool); |
756 elmpool_free(rdman->coord_canvas_pool); | 765 elmpool_free(rdman->coord_canvas_pool); |
757 | 766 |
758 DARRAY_DESTROY(&rdman->dirty_coords); | 767 DARRAY_DESTROY(&rdman->dirty_coords); |
768 DARRAY_DESTROY(&rdman->dirty_pcache_area_coords); | |
759 DARRAY_DESTROY(&rdman->dirty_geos); | 769 DARRAY_DESTROY(&rdman->dirty_geos); |
760 DARRAY_DESTROY(&rdman->gen_geos); | 770 DARRAY_DESTROY(&rdman->gen_geos); |
761 DARRAY_DESTROY(&rdman->zeroing_coords); | 771 DARRAY_DESTROY(&rdman->zeroing_coords); |
762 } | 772 } |
763 | 773 |
1026 | 1036 |
1027 if(cm_cnt || rdman_is_dirty(rdman)) | 1037 if(cm_cnt || rdman_is_dirty(rdman)) |
1028 return rdman_coord_free_postponse(rdman, coord); | 1038 return rdman_coord_free_postponse(rdman, coord); |
1029 | 1039 |
1030 /* Free canvas and canvas_info (\ref redraw) */ | 1040 /* Free canvas and canvas_info (\ref redraw) */ |
1031 if(coord->flags & COF_OWN_CANVAS) { | 1041 if(coord_is_cached(coord)) { |
1032 canvas_free(_coord_get_canvas(coord)); | 1042 canvas_free(_coord_get_canvas(coord)); |
1033 coord_canvas_info_free(rdman, coord->canvas_info); | 1043 coord_canvas_info_free(rdman, coord->canvas_info); |
1034 } | 1044 } |
1035 | 1045 |
1036 RM_CHILD(parent, coord); | 1046 RM_CHILD(parent, coord); |
1125 if(child->flags & (COF_DIRTY | COF_HIDDEN)) { | 1135 if(child->flags & (COF_DIRTY | COF_HIDDEN)) { |
1126 preorder_coord_skip_subtree(child); | 1136 preorder_coord_skip_subtree(child); |
1127 continue; | 1137 continue; |
1128 } | 1138 } |
1129 | 1139 |
1130 if(child->flags & COF_OWN_CANVAS) { | 1140 if(coord_is_cached(child)) { |
1131 preorder_coord_skip_subtree(child); | 1141 preorder_coord_skip_subtree(child); |
1132 continue; | 1142 continue; |
1133 } | 1143 } |
1134 | 1144 |
1135 add_dirty_coord(rdman, child); | 1145 add_dirty_coord(rdman, child); |
1231 static void setup_canvas_info(redraw_man_t *rdman, coord_t *coord) { | 1241 static void setup_canvas_info(redraw_man_t *rdman, coord_t *coord) { |
1232 if(coord->parent == NULL) | 1242 if(coord->parent == NULL) |
1233 return; | 1243 return; |
1234 | 1244 |
1235 if(coord->opacity != 1 || coord_is_cached(coord)) { | 1245 if(coord->opacity != 1 || coord_is_cached(coord)) { |
1236 if(!(coord->flags & COF_OWN_CANVAS)) { | 1246 if(!coord_is_cached(coord)) { |
1237 /* canvas is assigned latter, in zeroing_coord() */ | 1247 /* canvas is assigned latter, in zeroing_coord() */ |
1238 coord->canvas_info = coord_canvas_info_new(rdman, coord, NULL); | 1248 coord->canvas_info = coord_canvas_info_new(rdman, coord, NULL); |
1239 coord->flags |= COF_OWN_CANVAS; | 1249 coord_set_flags(coord->flags, COF_OWN_CANVAS); |
1240 } | 1250 } |
1241 } else { | 1251 } else { |
1242 if(coord->flags & COF_OWN_CANVAS) { | 1252 if(coord_is_cached(coord)) { |
1243 canvas_free(_coord_get_canvas(coord)); | 1253 canvas_free(_coord_get_canvas(coord)); |
1244 coord_canvas_info_free(rdman, coord->canvas_info); | 1254 coord_canvas_info_free(rdman, coord->canvas_info); |
1245 coord->flags &= ~COF_OWN_CANVAS; | 1255 coord_clear_flags(coord, COF_OWN_CANVAS); |
1246 } | 1256 } |
1247 /* This must here to keep coords that do not own canvas | 1257 /* This must here to keep coords that do not own canvas |
1248 * can always point to right canvas_info. Since, they | 1258 * can always point to right canvas_info. Since, they |
1249 * don't know when will parent change it's canvas_info. | 1259 * don't know when will parent change it's canvas_info. |
1250 */ | 1260 */ |
1365 } | 1375 } |
1366 | 1376 |
1367 r = compute_area(coord); | 1377 r = compute_area(coord); |
1368 if(r != OK) | 1378 if(r != OK) |
1369 return ERR; | 1379 return ERR; |
1370 | 1380 |
1371 return OK; | 1381 return OK; |
1372 } | 1382 } |
1373 | 1383 |
1374 /*! \brief Clean dirty coords. | 1384 /*! \brief Clean dirty coords. |
1375 * | 1385 * |
1378 * normal one. (see compute_aggr_of_cached_coord()). | 1388 * normal one. (see compute_aggr_of_cached_coord()). |
1379 * | 1389 * |
1380 * \note coords their opacity != 1 are also traded as cached ones. | 1390 * \note coords their opacity != 1 are also traded as cached ones. |
1381 */ | 1391 */ |
1382 static int clean_coord(redraw_man_t *rdman, coord_t *coord) { | 1392 static int clean_coord(redraw_man_t *rdman, coord_t *coord) { |
1393 coord_t *child; | |
1383 int r; | 1394 int r; |
1384 | 1395 |
1385 setup_canvas_info(rdman, coord); | 1396 setup_canvas_info(rdman, coord); |
1386 | 1397 |
1387 compute_aggr(coord); | 1398 compute_aggr(coord); |
1393 */ | 1404 */ |
1394 r = coord_clean_members_n_compute_area(coord); | 1405 r = coord_clean_members_n_compute_area(coord); |
1395 if(r != OK) | 1406 if(r != OK) |
1396 return ERR; | 1407 return ERR; |
1397 | 1408 |
1398 coord->flags &= ~COF_DIRTY; | 1409 add_dirty_area(rdman, coord->cur_area); |
1399 | 1410 add_dirty_area(rdman, coord->last_area); |
1411 | |
1412 coord_clear_flags(coord, COF_DIRTY); | |
1413 coord_set_flags(coord, COF_JUST_CLEAN); | |
1414 | |
1415 FORCHILDREN(coord, child) { | |
1416 if(coord_is_cached(child)) | |
1417 add_dirty_pcache_area_coord(rdman, child); | |
1418 } | |
1419 | |
1400 return OK; | 1420 return OK; |
1401 } | 1421 } |
1402 | 1422 |
1403 /*! \brief Clean coord_t objects. | 1423 /*! \brief Clean coord_t objects. |
1404 * | 1424 * |
1418 dirty_coords = rdman->dirty_coords.ds; | 1438 dirty_coords = rdman->dirty_coords.ds; |
1419 _insert_sort((void **)dirty_coords, n_dirty_coords, | 1439 _insert_sort((void **)dirty_coords, n_dirty_coords, |
1420 OFFSET(coord_t, order)); /* ascend order */ | 1440 OFFSET(coord_t, order)); /* ascend order */ |
1421 for(i = 0; i < n_dirty_coords; i++) { | 1441 for(i = 0; i < n_dirty_coords; i++) { |
1422 coord = dirty_coords[i]; | 1442 coord = dirty_coords[i]; |
1423 if(!(coord->flags & COF_DIRTY)) | 1443 if(!coord_get_flags(coord, COF_DIRTY | COF_JUST_CLEAN)) |
1424 continue; | 1444 continue; |
1445 SWAP(coord->cur_area, coord->last_area, coord_t *); | |
1425 r = clean_coord(rdman, coord); | 1446 r = clean_coord(rdman, coord); |
1426 if(r != OK) | 1447 if(r != OK) |
1427 return ERR; | 1448 return ERR; |
1428 /* TODO: ponstponse adding dirty areas until zeroing. | |
1429 * Because, aggregated matrix would changed when | |
1430 * zeroing | |
1431 */ | |
1432 /* These two steps can be avoided for drawing all. */ | |
1433 add_dirty_area(rdman, coord, &coord->areas[0]); | |
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 } | |
1449 } | 1449 } |
1450 } | 1450 } |
1451 return OK; | 1451 return OK; |
1452 } | 1452 } |
1453 | 1453 |
1524 | 1524 |
1525 if(x > max_x) | 1525 if(x > max_x) |
1526 max_x = x; | 1526 max_x = x; |
1527 if(y > max_y) | 1527 if(y > max_y) |
1528 max_y = y; | 1528 max_y = y; |
1529 if(cur->flags & COF_OWN_CANVAS) | 1529 if(coord_is_cached(cur->flags)) |
1530 preorder_coord_skip_subtree(cur); | 1530 preorder_coord_skip_subtree(cur); |
1531 } | 1531 } |
1532 | 1532 |
1533 w = max_x - min_x; | 1533 w = max_x - min_x; |
1534 h = max_y - min_y; | 1534 h = max_y - min_y; |
1553 * Adjust matrics of descendants to align left-top corner of | 1553 * Adjust matrics of descendants to align left-top corner of |
1554 * minimum covering area with origin of space defined by | 1554 * minimum covering area with origin of space defined by |
1555 * zeroing coord. | 1555 * zeroing coord. |
1556 */ | 1556 */ |
1557 FOR_COORDS_PREORDER(coord, cur) { | 1557 FOR_COORDS_PREORDER(coord, cur) { |
1558 if(coord_get_flags(cur, COF_OWN_CANVAS) && coord != cur) { | 1558 if(coord_is_cached(cur) && coord != cur) { |
1559 /* | 1559 /* |
1560 * Cached coords are zeroed from root to leaves, so | 1560 * Cached coords are zeroed from root to leaves, so |
1561 * changes of aggr_matrix would be propagated to next | 1561 * changes of aggr_matrix would be propagated to next |
1562 * level of cached. | 1562 * level of cached. |
1563 */ | 1563 */ |
1597 area->y = 0; | 1597 area->y = 0; |
1598 area->w = w; | 1598 area->w = w; |
1599 area->h = h; | 1599 area->h = h; |
1600 DARRAY_CLEAN(_coord_get_dirty_areas(coord)); | 1600 DARRAY_CLEAN(_coord_get_dirty_areas(coord)); |
1601 add_dirty_area(rdman, coord, area); | 1601 add_dirty_area(rdman, coord, area); |
1602 | |
1603 coord_set_flags(coord, COF_JUST_ZERO); | |
1602 } | 1604 } |
1603 | 1605 |
1604 /*! \brief Add canvas owner of dirty geos to redraw_man_t::zeroing_coords. | 1606 /*! \brief Add canvas owner of dirty geos to redraw_man_t::zeroing_coords. |
1605 * | 1607 * |
1606 * All possible coords that need a zeroing have at least one dirty geo. | 1608 * All possible coords that need a zeroing have at least one dirty geo. |
1639 } | 1641 } |
1640 } | 1642 } |
1641 | 1643 |
1642 /* Add all marked coords into redraw_man_t::zeroing_coords list */ | 1644 /* Add all marked coords into redraw_man_t::zeroing_coords list */ |
1643 FOR_COORDS_PREORDER(rdman->root_coord, coord) { | 1645 FOR_COORDS_PREORDER(rdman->root_coord, coord) { |
1644 if(!coord_get_flags(coord, COF_OWN_CANVAS)) | 1646 if(!coord_is_cached(coord)) |
1645 continue; /* skip coords that is not cached */ | 1647 continue; /* skip coords that is not cached */ |
1646 | 1648 |
1647 if(!coord_get_flags(coord, COF_TEMP_MARK)) { | 1649 if(!coord_get_flags(coord, COF_TEMP_MARK)) { |
1650 if(coord_get_flags(coord, COF_DIRTY_PCACHE_AREA)) | |
1651 add_dirty_pcache_area_coord(rdman, coord); | |
1648 preorder_coord_skip_subtree(coord); | 1652 preorder_coord_skip_subtree(coord); |
1649 continue; | 1653 continue; |
1650 } | 1654 } |
1651 add_zeroing_coord(rdman, coord); | 1655 add_zeroing_coord(rdman, coord); |
1652 | 1656 |
1821 | 1825 |
1822 n_dirty_coords = rdman->dirty_coords.num; | 1826 n_dirty_coords = rdman->dirty_coords.num; |
1823 dirty_coords = rdman->dirty_coords.ds; | 1827 dirty_coords = rdman->dirty_coords.ds; |
1824 for(i = 0; i < n_dirty_coords; i++) { | 1828 for(i = 0; i < n_dirty_coords; i++) { |
1825 coord = dirty_coords[i]; | 1829 coord = dirty_coords[i]; |
1826 if(coord_get_flags(coord, COF_OWN_CANVAS) && | 1830 if(coord_is_cached(coord) && !coord_is_root(coord)) { |
1827 !coord_is_root(coord)) { | |
1828 add_dirty_area(rdman, coord->parent, coord->cur_area); | 1831 add_dirty_area(rdman, coord->parent, coord->cur_area); |
1829 add_dirty_area(rdman, coord->parent, coord->last_area); | 1832 add_dirty_area(rdman, coord->parent, coord->last_area); |
1830 } | 1833 } |
1831 } | 1834 } |
1832 | 1835 |
1892 | 1895 |
1893 r = clean_rdman_coords(rdman); | 1896 r = clean_rdman_coords(rdman); |
1894 if(r != OK) | 1897 if(r != OK) |
1895 return ERR; | 1898 return ERR; |
1896 | 1899 |
1897 /* Mark COF_JUST_CLEAN */ | |
1898 coords = rdman->dirty_coords.ds; | |
1899 for(i = 0; i < rdman->dirty_coords.num; i++) { | |
1900 /* Mark dirty coords COF_JUST_CLEAN to identify coords that | |
1901 * has changed their matrix and respective coordination | |
1902 * system. It helps zeroing_coord() to avoid fully redrawing | |
1903 * all descednants of a cached coord that had not changed its | |
1904 * matrix. | |
1905 */ | |
1906 coord = coords[i]; | |
1907 coord_set_flags(coord, COF_JUST_CLEAN); | |
1908 } | |
1909 /* TODO: save area of cached coord and descendants in | 1900 /* TODO: save area of cached coord and descendants in |
1910 * cached_dirty_area for parent cached coord space. | 1901 * cached_dirty_area for parent cached coord space. |
1911 */ | 1902 */ |
1912 | 1903 |
1913 r = clean_rdman_geos(rdman); | 1904 r = clean_rdman_geos(rdman); |
2118 member = FIRST_MEMBER(coord); | 2109 member = FIRST_MEMBER(coord); |
2119 mem_idx = 0; | 2110 mem_idx = 0; |
2120 child = FIRST_CHILD(coord); | 2111 child = FIRST_CHILD(coord); |
2121 while(child != NULL || member != NULL) { | 2112 while(child != NULL || member != NULL) { |
2122 if(child && child->before_pmem == mem_idx) { | 2113 if(child && child->before_pmem == mem_idx) { |
2123 if(child->flags & COF_OWN_CANVAS) { | 2114 if(coord_is_cached(child)) { |
2124 if(!(child->flags & COF_HIDDEN) && | 2115 if(!(child->flags & COF_HIDDEN) && |
2125 is_area_in_areas(coord_get_area(child), n_areas, areas)) { | 2116 is_area_in_areas(coord_get_area(child), n_areas, areas)) { |
2126 update_cached_canvas_2_parent(rdman, child); | 2117 update_cached_canvas_2_parent(rdman, child); |
2127 dirty = 1; | 2118 dirty = 1; |
2128 } | 2119 } |