[PATCH 14/14] tablet-shell: a workaround to prevent memory leak in drawing background.

tecton69 at gmail.com tecton69 at gmail.com
Tue Aug 21 04:49:28 PDT 2012


From: Ning Tang <ning.tang at intel.com>

 The origin method is to create a surface every time paint background
 and destroy it. But load_cairo_surface(1) and cairo_surface_destroy(1)
 will cause memory leak. Since sliding effect will cause background to
 be drawn many times, use this workaround to avoid out of memory.

 Signed-off-by: Ning Tang <tecton69 at gmail.com>

---
 clients/tablet-shell.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/clients/tablet-shell.c b/clients/tablet-shell.c
index 0294396..f96b3a2 100644
--- a/clients/tablet-shell.c
+++ b/clients/tablet-shell.c
@@ -48,6 +48,7 @@ struct homescreen {
 	struct widget *widget;
 	struct wl_list layout_list;
 	struct input *input;
+	cairo_surface_t *image;
 };
 
 /* container of launchers on background */
@@ -148,16 +149,14 @@ sigchild_handler(int s)
 }
 
 static void
-paint_background(cairo_t *cr, const char *path, struct rectangle *allocation)
+paint_background(cairo_t *cr, cairo_surface_t *image,
+		 struct rectangle *allocation)
 {
-	cairo_surface_t *image = NULL;
 	cairo_pattern_t *pattern;
 	cairo_matrix_t matrix;
 	double sx, sy;
 
 	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
-	if (path)
-		image = load_cairo_surface(path);
 	if (image) {
 		pattern = cairo_pattern_create_for_surface(image);
 		sx = (double) cairo_image_surface_get_width(image) /
@@ -168,10 +167,9 @@ paint_background(cairo_t *cr, const char *path, struct rectangle *allocation)
 		cairo_pattern_set_matrix(pattern, &matrix);
 		cairo_set_source(cr, pattern);
 		cairo_pattern_destroy (pattern);
-		cairo_surface_destroy(image);
 		cairo_paint(cr);
 	} else {
-		fprintf(stderr, "couldn't load background image: %s\n", path);
+		fprintf(stderr, "no background image.\n");
 		cairo_set_source_rgb(cr, 0.2, 0, 0);
 		cairo_paint(cr);
 	}
@@ -258,7 +256,11 @@ homescreen_draw(struct widget *widget, void *data)
 	cr = cairo_create(surface);
 
 	widget_get_allocation(widget, &allocation);
-	paint_background(cr, key_homescreen_background, &allocation);
+	if (homescreen->image == NULL && key_homescreen_background) {
+		homescreen->image =
+			load_cairo_surface(key_homescreen_background);
+	}
+	paint_background(cr, homescreen->image, &allocation);
 
 	/* draw current layout */
 	wl_list_for_each(layout, &homescreen->layout_list, link) {
-- 
1.7.11.5



More information about the wayland-devel mailing list