Mercurial > MadButterfly
comparison src/redraw_man.c @ 24:e598bc809c0f
No more flash when animation.
1. Add a buffer surface.
2. Draw on the surface
3. Copy content of buffer surface to XLib surface.
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Sun, 03 Aug 2008 02:08:31 +0800 |
parents | 56f592f56ff7 |
children | 29937c26bb01 |
comparison
equal
deleted
inserted
replaced
23:56f592f56ff7 | 24:e598bc809c0f |
---|---|
179 rdman->n_dirty_coords = 0; | 179 rdman->n_dirty_coords = 0; |
180 } | 180 } |
181 return OK; | 181 return OK; |
182 } | 182 } |
183 | 183 |
184 int redraw_man_init(redraw_man_t *rdman, cairo_t *cr) { | 184 int redraw_man_init(redraw_man_t *rdman, cairo_t *cr, cairo_t *backend) { |
185 extern void redraw_man_destroy(redraw_man_t *rdman); | 185 extern void redraw_man_destroy(redraw_man_t *rdman); |
186 | 186 |
187 memset(rdman, 0, sizeof(redraw_man_t)); | 187 memset(rdman, 0, sizeof(redraw_man_t)); |
188 | 188 |
189 rdman->geo_pool = elmpool_new(sizeof(geo_t), 128); | 189 rdman->geo_pool = elmpool_new(sizeof(geo_t), 128); |
208 redraw_man_destroy(rdman); | 208 redraw_man_destroy(rdman); |
209 rdman->n_coords = 1; | 209 rdman->n_coords = 1; |
210 coord_init(rdman->root_coord, NULL); | 210 coord_init(rdman->root_coord, NULL); |
211 | 211 |
212 rdman->cr = cr; | 212 rdman->cr = cr; |
213 rdman->backend = backend; | |
213 | 214 |
214 return OK; | 215 return OK; |
215 } | 216 } |
216 | 217 |
217 void redraw_man_destroy(redraw_man_t *rdman) { | 218 void redraw_man_destroy(redraw_man_t *rdman) { |
499 | 500 |
500 pt = cairo_get_source(cr); | 501 pt = cairo_get_source(cr); |
501 cairo_pattern_reference(pt); | 502 cairo_pattern_reference(pt); |
502 /* TODO: clean to background color. */ | 503 /* TODO: clean to background color. */ |
503 cairo_set_source_rgb(cr, 0, 0, 0); | 504 cairo_set_source_rgb(cr, 0, 0, 0); |
504 cairo_fill_preserve(cr); | 505 cairo_paint(cr); |
505 cairo_set_source(cr, pt); | 506 cairo_set_source(cr, pt); |
506 cairo_pattern_destroy(pt); | 507 cairo_pattern_destroy(pt); |
507 } | 508 } |
508 | 509 |
509 static void make_clip(redraw_man_t *rdman, int n_dirty_areas, | 510 static void make_clip(cairo_t *cr, int n_dirty_areas, |
510 area_t **dirty_areas) { | 511 area_t **dirty_areas) { |
511 int i; | 512 int i; |
512 area_t *area; | 513 area_t *area; |
513 cairo_t *cr; | |
514 | |
515 cr = rdman->cr; | |
516 | 514 |
517 for(i = 0; i < n_dirty_areas; i++) { | 515 for(i = 0; i < n_dirty_areas; i++) { |
518 area = dirty_areas[i]; | 516 area = dirty_areas[i]; |
519 cairo_rectangle(cr, area->x, area->y, area->w, area->h); | 517 cairo_rectangle(cr, area->x, area->y, area->w, area->h); |
520 } | 518 } |
521 clean_clip(cr); | |
522 cairo_clip(cr); | 519 cairo_clip(cr); |
523 } | 520 } |
524 | 521 |
525 static void reset_clip(redraw_man_t *rdman) { | 522 static void reset_clip(redraw_man_t *rdman) { |
526 cairo_reset_clip(rdman->cr); | 523 cairo_reset_clip(rdman->cr); |
524 cairo_reset_clip(rdman->backend); | |
525 } | |
526 | |
527 static void copy_cr_2_backend(redraw_man_t *rdman, int n_dirty_areas, | |
528 area_t **dirty_areas) { | |
529 if(n_dirty_areas) | |
530 make_clip(rdman->backend, n_dirty_areas, dirty_areas); | |
531 | |
532 cairo_paint(rdman->backend); | |
527 } | 533 } |
528 #else /* UNITTEST */ | 534 #else /* UNITTEST */ |
529 static void make_clip(redraw_man_t *rdman, int n_dirty_areas, | 535 static void clean_clip(cairo_t *cr) { |
536 } | |
537 | |
538 static void make_clip(cairo_t *cr, int n_dirty_areas, | |
530 area_t **dirty_areas) { | 539 area_t **dirty_areas) { |
531 } | 540 } |
532 | 541 |
533 static void reset_clip(redraw_man_t *rdman) { | 542 static void reset_clip(redraw_man_t *rdman) { |
543 } | |
544 | |
545 static void copy_cr_2_backend(redraw_man_t *rdman, int n_dirty_areas, | |
546 area_t **dirty_areas) { | |
534 } | 547 } |
535 #endif /* UNITTEST */ | 548 #endif /* UNITTEST */ |
536 | 549 |
537 static void draw_shapes_in_areas(redraw_man_t *rdman, | 550 static void draw_shapes_in_areas(redraw_man_t *rdman, |
538 int n_areas, | 551 int n_areas, |
552 } | 565 } |
553 } | 566 } |
554 } | 567 } |
555 } | 568 } |
556 | 569 |
570 | |
557 /*! \brief Re-draw all changed shapes or shapes affected by changed coords. | 571 /*! \brief Re-draw all changed shapes or shapes affected by changed coords. |
558 * | 572 * |
559 * A coord object has a geo to keep track the range that it's members will | 573 * A coord object has a geo to keep track the range that it's members will |
560 * draw on. Geo of a coord should be recomputed when the coord is changed. | 574 * draw on. Geo of a coord should be recomputed when the coord is changed. |
561 * Geo of a coord used to accelerate finding overlay shape objects of | 575 * Geo of a coord used to accelerate finding overlay shape objects of |
614 } | 628 } |
615 | 629 |
616 n_dirty_areas = rdman->n_dirty_areas; | 630 n_dirty_areas = rdman->n_dirty_areas; |
617 dirty_areas = rdman->dirty_areas; | 631 dirty_areas = rdman->dirty_areas; |
618 if(n_dirty_areas > 0) { | 632 if(n_dirty_areas > 0) { |
619 make_clip(rdman, n_dirty_areas, dirty_areas); | 633 make_clip(rdman->cr, n_dirty_areas, dirty_areas); |
634 clean_clip(rdman->cr); | |
620 draw_shapes_in_areas(rdman, n_dirty_areas, dirty_areas); | 635 draw_shapes_in_areas(rdman, n_dirty_areas, dirty_areas); |
636 copy_cr_2_backend(rdman, rdman->n_dirty_areas, rdman->dirty_areas); | |
621 rdman->n_dirty_areas = 0; | 637 rdman->n_dirty_areas = 0; |
622 reset_clip(rdman); | 638 reset_clip(rdman); |
623 } | 639 } |
624 rdman->n_dirty_areas = 0; | 640 rdman->n_dirty_areas = 0; |
625 | 641 |
637 geo = STAILQ_NEXT(geo_t, next, geo)) { | 653 geo = STAILQ_NEXT(geo_t, next, geo)) { |
638 if(geo->flags & GEF_DIRTY) | 654 if(geo->flags & GEF_DIRTY) |
639 clean_shape(geo->shape); | 655 clean_shape(geo->shape); |
640 draw_shape(rdman, geo->shape); | 656 draw_shape(rdman, geo->shape); |
641 } | 657 } |
658 copy_cr_2_backend(rdman, 0, NULL); | |
642 rdman->n_dirty_geos = 0; | 659 rdman->n_dirty_geos = 0; |
643 | 660 |
644 return OK; | 661 return OK; |
645 } | 662 } |
646 | 663 |
824 geo_t **overlays; | 841 geo_t **overlays; |
825 co_aix pos[2][2]; | 842 co_aix pos[2][2]; |
826 int n; | 843 int n; |
827 int i; | 844 int i; |
828 | 845 |
829 redraw_man_init(&rdman, NULL); | 846 redraw_man_init(&rdman, NULL, NULL); |
830 coords[0] = rdman.root_coord; | 847 coords[0] = rdman.root_coord; |
831 for(i = 1; i < 3; i++) { | 848 for(i = 1; i < 3; i++) { |
832 coords[i] = rdman_coord_new(&rdman, rdman.root_coord); | 849 coords[i] = rdman_coord_new(&rdman, rdman.root_coord); |
833 } | 850 } |
834 for(i = 0; i < 5; i++) { | 851 for(i = 0; i < 5; i++) { |
877 int i; | 894 int i; |
878 | 895 |
879 dummys = (sh_dummy_t **)shapes; | 896 dummys = (sh_dummy_t **)shapes; |
880 | 897 |
881 rdman = &_rdman; | 898 rdman = &_rdman; |
882 redraw_man_init(rdman, NULL); | 899 redraw_man_init(rdman, NULL, NULL); |
883 paint = dummy_paint_new(rdman); | 900 paint = dummy_paint_new(rdman); |
884 for(i = 0; i < 3; i++) { | 901 for(i = 0; i < 3; i++) { |
885 shapes[i] = sh_dummy_new(0, 0, 50, 50); | 902 shapes[i] = sh_dummy_new(0, 0, 50, 50); |
886 rdman_paint_fill(rdman, paint, shapes[i]); | 903 rdman_paint_fill(rdman, paint, shapes[i]); |
887 coords[i] = rdman_coord_new(rdman, rdman->root_coord); | 904 coords[i] = rdman_coord_new(rdman, rdman->root_coord); |