I am using the X11 backend with Compiz.
I have run it with sysprof. sysprof tells me that most of the time is being spent in the X process but there is no further detail as to where in the X11 library.
I will experiment more to see if it is related to re-allocating the pixmap.
On Wed, Jan 27, 2010 at 9:12 PM, Robert Gibbs <gibbsrc@xxxxxxxxx> wrote:
I am running into a severe performance degradation when using the built in GtkDrawingArea double buffering to a 1600x1200 window. The program sets a default priority idle handler which calls gtk_widget_queue_draw. The expose event originally would draw about 1000 polygons, but I commented out the drawing portion and still saw the same poor performance. The best performance I can get is about 10 frames per second.
If call GTK_WIDGET_UNSET_FLAGS (drawing_area, GTK_DOUBLE_BUFFERED), then use my own pixmap for double buffering, the performance goes up to 50 frames per second.
Can anyone tell me why the built-in double buffering would yield such poor performance?
#include <math.h> #include <time.h> #include <string.h> #include <gtk/gtk.h> #include <gdk/gdk.h> #include <gdk/gdkkeysyms.h> typedef struct { guint idle_id; GtkWidget *da; GdkPixmap *pix; gboolean use_buffer; } AppData; static gboolean on_expose(GtkWidget *widget, GdkEventExpose *event, AppData *app) { GdkColor color; GdkDrawable *drawable; GdkGC *gc; if (app->use_buffer) { drawable = GDK_DRAWABLE(app->pix); gc = gdk_gc_new(drawable); gdk_color_parse("black", &color); gdk_gc_set_rgb_fg_color(gc, &color); gdk_draw_rectangle(drawable, gc, TRUE, 0, 0, widget->allocation.width, widget->allocation.height); } else { drawable = GDK_DRAWABLE(widget->window); gc = gdk_gc_new(drawable); } gdk_color_parse("red", &color); gdk_gc_set_rgb_fg_color(gc, &color); gdk_draw_line(drawable, gc, 0, 0, widget->allocation.width, widget->allocation.height); gdk_draw_line(drawable, gc, widget->allocation.width, 0, 0, widget->allocation.height); if (app->use_buffer) { gdk_draw_drawable(GDK_DRAWABLE(widget->window), gc, GDK_DRAWABLE(app->pix), 0, 0, 0, 0, -1, -1); } return TRUE; } static gboolean on_configure(GtkWidget *widget, GdkEventConfigure *event, AppData *app) { if (app->use_buffer) { if (app->pix) g_object_unref(app->pix); app->pix = gdk_pixmap_new(GDK_DRAWABLE(app->da->window), event->width, event->height, -1); } return TRUE; } static gboolean on_fps_idle(AppData *app) { static time_t t = 0; static float total = 0; if (t == 0) t = time(0); gtk_widget_queue_draw(app->da); total++; if (time(0) - t >= 10) { printf("%.1f FPS\n", total / ((float)(time(0)-t))); t = time(0); total = 0; } return TRUE; } static gboolean on_key_press_event(GtkWidget *widget, GdkEventKey *event, AppData *app) { switch (event->keyval) { case GDK_t: case GDK_T: if (!g_source_remove_by_user_data(app)) { g_idle_add((GSourceFunc) on_fps_idle, app); } break; case GDK_b: case GDK_B: if (app->use_buffer) { printf("Using GDK buffering\n"); app->use_buffer = FALSE; GTK_WIDGET_SET_FLAGS (app->da, GTK_DOUBLE_BUFFERED); if (app->pix) g_object_unref(app->pix); app->pix = NULL; } else { printf("Using internal buffer\n"); app->use_buffer = TRUE; GTK_WIDGET_UNSET_FLAGS (app->da, GTK_DOUBLE_BUFFERED); app->pix = gdk_pixmap_new(GDK_DRAWABLE( app->da->window), app->da->allocation.width, app->da->allocation.height, -1); } break; default: break; } return FALSE; } static char *keymaps = "\ t.T\t\tStart or stop a frame per second (FPS) timing test.\n\ b.B\t\tToggle internal buffering on or off..\n\ "; int main(int argc, char **argv) { GtkWidget *window; GdkColor color; AppData app; memset(&app, 0, sizeof(app)); gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); g_signal_connect(window, "delete-event", gtk_main_quit, NULL); app.da = gtk_drawing_area_new(); GTK_WIDGET_SET_FLAGS (app.da, GTK_CAN_FOCUS); gdk_color_parse("black", &color); gtk_widget_modify_bg(app.da, GTK_STATE_NORMAL, &color); gtk_widget_set_size_request(app.da, 400, 400); gtk_widget_set_events(app.da, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK | GDK_EXPOSURE_MASK); g_signal_connect(app.da, "key-press-event", G_CALLBACK(on_key_press_event), &app); g_signal_connect(app.da, "expose-event", G_CALLBACK(on_expose), &app); g_signal_connect(app.da, "configure-event", G_CALLBACK(on_configure), &app); gtk_container_add(GTK_CONTAINER(window), app.da); gtk_widget_show_all(window); printf("%s\n", keymaps); gtk_main(); return 0; }
_______________________________________________ gtk-list mailing list gtk-list@xxxxxxxxx http://mail.gnome.org/mailman/listinfo/gtk-list