We have found a regression that block us to migrate our existing apps from GTK 2.16.x to GTK 2.24.10 (20120208), it seems there is a memory leak in g_idle_add() use or something related to queue_draw(), anyway the following code (that I think is correct) do not leak in linux (ubuntu 12.04, gtk 2.24.10) nor on win32 (GTK 2.16) while it leaks about 12kbyte/sec with GTK 2.24.10 on win32.
I'm posting the code here before creating a bugzilla entry for it since I'm not sure I can use g_idle_add to notify a new frame is available without freeing the source, that works in linux and in older WIN32 versions and it seems correct since g_idle_add() documentation says: *If the function returns FALSE it is automatically removed from the list of event sources and will not be called again.* The (real) code is a video player with multiple realtime streams, this code use g_timeout_add() to simulate the 25fps of the video, I fill the drawing area with a simple red/blue pattern without thinking to much to endianness of the pixel components, but this is a sample, the code leaks on win32/2.24.10 also if I do not draw inside the GdkImage... Anyway here is the code, as short as I could make it :) #include <gtk/gtk.h> #include <stdint.h> double last_update; GtkWidget *dest; GdkImage *img; GdkGC *gc; int frames = 0; int queue_draw() { gtk_widget_queue_draw(dest); return FALSE; } double get_timer() { GTimeVal now; g_get_current_time(&now); return (double)now.tv_sec + ((double)now.tv_usec / 1000000.0f); } void on_expose() { gdk_draw_image(dest->window, gc, img, 0, 0, 0, 0, img->width, img->height); frames++; } int draw_func() { static int pos = 0; uint32_t *ptr = (uint32_t *)img->mem; int x, y; for (x = 0; x < img->width; ++x) { for (y = 0; y < pos; ++y) ptr[x + y * img->width] = 0xff0000; for (y = pos; y < pos + (img->height / 2) && y < img->height; ++y) ptr[x + y * img->width] = 0x00ff; for (y = pos + img->height / 2 ; y < img->height; ++y) ptr[x + y * img->width] = 0xff0000; } g_idle_add((GSourceFunc)queue_draw, NULL); if (++pos >= img->height) pos = 0; return TRUE; } int main(int argc, char *argv[]) { gtk_init(&argc, &argv); GtkWidget *w = gtk_window_new(GTK_WINDOW_TOPLEVEL); dest = gtk_drawing_area_new(); gtk_container_add(GTK_CONTAINER(w), dest); gtk_widget_set_usize(dest, 352, 288); g_signal_connect(dest, "expose-event", on_expose, NULL); gtk_widget_set_app_paintable(w, TRUE); gtk_widget_set_double_buffered(w, FALSE); gtk_widget_show_all(w); last_update = get_timer(); double secs = get_timer(); img = gdk_image_new(GDK_IMAGE_FASTEST, gdk_visual_get_system(), 352, 288); gc = gdk_gc_new(w->window); g_signal_connect(w, "delete-event", (GCallback)gtk_main_quit, NULL); g_timeout_add(40, (GSourceFunc)draw_func, NULL); gtk_main(); secs = get_timer() - secs; g_printf("%d frames in %f seconds, %f fps\n", frames, secs, (double)frames / secs); } -- Ing. Gabriele Greco, DARTS Engineering Tel: +39-0100980150 Fax: +39-0100980184 s-mail: Piazza Della Vittoria 9/3 - 16121 GENOVA (ITALY) _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list