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 }