# HG changeset patch # User Thinker K.F. Li # Date 1217700511 -28800 # Node ID e598bc809c0f41e87b664919f0dbb5012a8e1927 # Parent 56f592f56ff7cd0e582545a14d4fb233c5ba67ea No more flash when animation. 1. Add a buffer surface. 2. Draw on the surface 3. Copy content of buffer surface to XLib surface. diff -r 56f592f56ff7 -r e598bc809c0f src/X_main.c --- a/src/X_main.c Sat Aug 02 23:10:42 2008 +0800 +++ b/src/X_main.c Sun Aug 03 02:08:31 2008 +0800 @@ -13,6 +13,8 @@ Display *display; void draw_path(cairo_t *cr, int w, int h) { + cairo_t *tmpcr; + cairo_surface_t *tmpsuf; redraw_man_t rdman; shape_t *path1, *path2, *path3; coord_t *coord1, *coord2; @@ -21,7 +23,10 @@ grad_stop_t fill3_stops[3]; int i; - redraw_man_init(&rdman, cr); + tmpsuf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); + tmpcr = cairo_create(tmpsuf); + cairo_set_source_surface(cr, tmpsuf, 0, 0); + redraw_man_init(&rdman, tmpcr, cr); coord1 = rdman_coord_new(&rdman, rdman.root_coord); coord2 = rdman_coord_new(&rdman, rdman.root_coord); @@ -94,6 +99,8 @@ redraw_man_destroy(&rdman); sh_path_free(path1); sh_path_free(path2); + cairo_destroy(tmpcr); + cairo_surface_destroy(tmpsuf); } void drawing(cairo_surface_t *surface, int w, int h) { diff -r 56f592f56ff7 -r e598bc809c0f src/redraw_man.c --- a/src/redraw_man.c Sat Aug 02 23:10:42 2008 +0800 +++ b/src/redraw_man.c Sun Aug 03 02:08:31 2008 +0800 @@ -181,7 +181,7 @@ return OK; } -int redraw_man_init(redraw_man_t *rdman, cairo_t *cr) { +int redraw_man_init(redraw_man_t *rdman, cairo_t *cr, cairo_t *backend) { extern void redraw_man_destroy(redraw_man_t *rdman); memset(rdman, 0, sizeof(redraw_man_t)); @@ -210,6 +210,7 @@ coord_init(rdman->root_coord, NULL); rdman->cr = cr; + rdman->backend = backend; return OK; } @@ -501,37 +502,49 @@ cairo_pattern_reference(pt); /* TODO: clean to background color. */ cairo_set_source_rgb(cr, 0, 0, 0); - cairo_fill_preserve(cr); + cairo_paint(cr); cairo_set_source(cr, pt); cairo_pattern_destroy(pt); } -static void make_clip(redraw_man_t *rdman, int n_dirty_areas, +static void make_clip(cairo_t *cr, int n_dirty_areas, area_t **dirty_areas) { int i; area_t *area; - cairo_t *cr; - - cr = rdman->cr; for(i = 0; i < n_dirty_areas; i++) { area = dirty_areas[i]; cairo_rectangle(cr, area->x, area->y, area->w, area->h); } - clean_clip(cr); cairo_clip(cr); } static void reset_clip(redraw_man_t *rdman) { cairo_reset_clip(rdman->cr); + cairo_reset_clip(rdman->backend); +} + +static void copy_cr_2_backend(redraw_man_t *rdman, int n_dirty_areas, + area_t **dirty_areas) { + if(n_dirty_areas) + make_clip(rdman->backend, n_dirty_areas, dirty_areas); + + cairo_paint(rdman->backend); } #else /* UNITTEST */ -static void make_clip(redraw_man_t *rdman, int n_dirty_areas, +static void clean_clip(cairo_t *cr) { +} + +static void make_clip(cairo_t *cr, int n_dirty_areas, area_t **dirty_areas) { } static void reset_clip(redraw_man_t *rdman) { } + +static void copy_cr_2_backend(redraw_man_t *rdman, int n_dirty_areas, + area_t **dirty_areas) { +} #endif /* UNITTEST */ static void draw_shapes_in_areas(redraw_man_t *rdman, @@ -554,6 +567,7 @@ } } + /*! \brief Re-draw all changed shapes or shapes affected by changed coords. * * A coord object has a geo to keep track the range that it's members will @@ -616,8 +630,10 @@ n_dirty_areas = rdman->n_dirty_areas; dirty_areas = rdman->dirty_areas; if(n_dirty_areas > 0) { - make_clip(rdman, n_dirty_areas, dirty_areas); + make_clip(rdman->cr, n_dirty_areas, dirty_areas); + clean_clip(rdman->cr); draw_shapes_in_areas(rdman, n_dirty_areas, dirty_areas); + copy_cr_2_backend(rdman, rdman->n_dirty_areas, rdman->dirty_areas); rdman->n_dirty_areas = 0; reset_clip(rdman); } @@ -639,6 +655,7 @@ clean_shape(geo->shape); draw_shape(rdman, geo->shape); } + copy_cr_2_backend(rdman, 0, NULL); rdman->n_dirty_geos = 0; return OK; @@ -826,7 +843,7 @@ int n; int i; - redraw_man_init(&rdman, NULL); + redraw_man_init(&rdman, NULL, NULL); coords[0] = rdman.root_coord; for(i = 1; i < 3; i++) { coords[i] = rdman_coord_new(&rdman, rdman.root_coord); @@ -879,7 +896,7 @@ dummys = (sh_dummy_t **)shapes; rdman = &_rdman; - redraw_man_init(rdman, NULL); + redraw_man_init(rdman, NULL, NULL); paint = dummy_paint_new(rdman); for(i = 0; i < 3; i++) { shapes[i] = sh_dummy_new(0, 0, 50, 50); diff -r 56f592f56ff7 -r e598bc809c0f src/redraw_man.h --- a/src/redraw_man.h Sat Aug 02 23:10:42 2008 +0800 +++ b/src/redraw_man.h Sun Aug 03 02:08:31 2008 +0800 @@ -48,9 +48,11 @@ area_t **dirty_areas; cairo_t *cr; + cairo_t *backend; } redraw_man_t; -extern int redraw_man_init(redraw_man_t *rdman, cairo_t *cr); +extern int redraw_man_init(redraw_man_t *rdman, cairo_t *cr, + cairo_t *backend); extern void redraw_man_destroy(redraw_man_t *rdman); extern int rdman_find_overlaid_shapes(redraw_man_t *rdman, geo_t *geo,