From: Andy Spencer Date: Thu, 27 Dec 2012 09:26:28 +0000 (+0000) Subject: Add thread safe grits_viewer_queue_draw function X-Git-Url: http://pileus.org/git/?p=grits;a=commitdiff_plain;h=ecb7a9abd329d604506ea1734d2db72760fcb4f4 Add thread safe grits_viewer_queue_draw function This should be used by threads when they finish loading something. Any additional loading which must be done by the main thread will ideally be done during the next draw. --- diff --git a/src/grits-opengl.c b/src/grits-opengl.c index 90e830b..0e803ba 100644 --- a/src/grits-opengl.c +++ b/src/grits-opengl.c @@ -290,7 +290,7 @@ static gboolean run_mouse_move(GritsOpenGL *opengl, GdkEventMotion *event) static gboolean on_motion_notify(GritsOpenGL *opengl, GdkEventMotion *event, gpointer _) { opengl->mouse_queue = *event; - gtk_widget_queue_draw(GTK_WIDGET(opengl)); + grits_viewer_queue_draw(GRITS_VIEWER(opengl)); return FALSE; } @@ -402,18 +402,18 @@ static gboolean on_key_press(GritsOpenGL *opengl, GdkEventKey *event, gpointer _ /* Testing */ if (kv == GDK_w) { opengl->wireframe = !opengl->wireframe; - gtk_widget_queue_draw(GTK_WIDGET(opengl)); + grits_viewer_queue_draw(GRITS_VIEWER(opengl)); } if (kv == GDK_p) { opengl->pickmode = !opengl->pickmode; - gtk_widget_queue_draw(GTK_WIDGET(opengl)); + grits_viewer_queue_draw(GRITS_VIEWER(opengl)); } #ifdef ROAM_DEBUG else if (kv == GDK_n) roam_sphere_split_one(opengl->sphere); else if (kv == GDK_p) roam_sphere_merge_one(opengl->sphere); else if (kv == GDK_r) roam_sphere_split_merge(opengl->sphere); else if (kv == GDK_u) roam_sphere_update_errors(opengl->sphere); - gtk_widget_queue_draw(GTK_WIDGET(opengl)); + grits_viewer_queue_draw(GRITS_VIEWER(opengl)); #endif return FALSE; } diff --git a/src/grits-viewer.c b/src/grits-viewer.c index aa5c3a5..67d25fb 100644 --- a/src/grits-viewer.c +++ b/src/grits-viewer.c @@ -71,6 +71,14 @@ static void _grits_viewer_fix_rotation(GritsViewer *viewer) while (viewer->rotation[2] > 180) viewer->rotation[2] -= 360; } +static gboolean _grits_viewer_queue_draw_cb(gpointer _viewer) +{ + GritsViewer *viewer = _viewer; + gtk_widget_queue_draw(GTK_WIDGET(viewer)); + viewer->draw_source = 0; + return FALSE; +} + /* Signal helpers */ static void _grits_viewer_emit_location_changed(GritsViewer *viewer) { @@ -187,7 +195,7 @@ static gboolean on_motion_notify(GritsViewer *viewer, GdkEventMotion *event, gpo static void on_view_changed(GritsViewer *viewer, gdouble _1, gdouble _2, gdouble _3) { - gtk_widget_queue_draw(GTK_WIDGET(viewer)); + grits_viewer_queue_draw(viewer); } /*********** @@ -424,6 +432,20 @@ gboolean grits_viewer_get_offline(GritsViewer *viewer) return viewer->offline; } +/** + * grits_viewer_queue_draw: + * @viewer: the viewer + * + * Causes the viewer to redraw the screen. This has the safe effect as + * gtk_widget_queue_draw, but is thread safe, and probably faster. + */ +void grits_viewer_queue_draw(GritsViewer *viewer) +{ + if (!viewer->draw_source) + viewer->draw_source = g_idle_add_full(G_PRIORITY_HIGH, + _grits_viewer_queue_draw_cb, viewer, NULL); +} + /*********************************** * To be implemented by subclasses * ***********************************/ @@ -610,6 +632,14 @@ static void grits_viewer_init(GritsViewer *viewer) g_signal_connect(viewer, "location-changed", G_CALLBACK(on_view_changed), NULL); g_signal_connect(viewer, "rotation-changed", G_CALLBACK(on_view_changed), NULL); } +static void grits_viewer_dispose(GObject *gobject) +{ + g_debug("GritsViewer: dispose"); + GritsViewer *viewer = GRITS_VIEWER(gobject); + if (viewer->draw_source) + g_source_remove(viewer->draw_source); + G_OBJECT_CLASS(grits_viewer_parent_class)->dispose(gobject); +} static void grits_viewer_finalize(GObject *gobject) { g_debug("GritsViewer: finalize"); @@ -620,6 +650,7 @@ static void grits_viewer_class_init(GritsViewerClass *klass) { g_debug("GritsViewer: class_init"); GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + gobject_class->dispose = grits_viewer_dispose; gobject_class->finalize = grits_viewer_finalize; /** diff --git a/src/grits-viewer.h b/src/grits-viewer.h index 4b04e3f..fa9fc07 100644 --- a/src/grits-viewer.h +++ b/src/grits-viewer.h @@ -119,6 +119,9 @@ struct _GritsViewer { /* For dragging */ gint drag_mode; gdouble drag_x, drag_y; + + /* For queue_draw */ + guint draw_source; }; struct _GritsViewerClass { @@ -187,4 +190,6 @@ void grits_viewer_add(GritsViewer *viewer, GritsObject *object, gint level, gboolean sort); void grits_viewer_remove(GritsViewer *viewer, GritsObject *object); +void grits_viewer_queue_draw(GritsViewer *viewer); + #endif diff --git a/src/objects/grits-object.c b/src/objects/grits-object.c index 4674e8a..2eb6b5c 100644 --- a/src/objects/grits-object.c +++ b/src/objects/grits-object.c @@ -163,7 +163,7 @@ void grits_object_hide(GritsObject *object, gboolean hidden) void grits_object_queue_draw(GritsObject *object) { if (object->viewer) - gtk_widget_queue_draw(GTK_WIDGET(object->viewer)); + grits_viewer_queue_draw(object->viewer); } void grits_object_set_cursor(GritsObject *object, GdkCursorType cursor)