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);