gis_view_get_location(self->view, &lat, &lon, &elev);
pan = MIN(elev/(EARTH_R/2), 30);
guint kv = event->keyval;
+ gdk_threads_leave();
if (kv == GDK_Left || kv == GDK_h) gis_view_pan(self->view, 0, -pan, 0);
else if (kv == GDK_Down || kv == GDK_j) gis_view_pan(self->view, -pan, 0, 0);
else if (kv == GDK_Up || kv == GDK_k) gis_view_pan(self->view, pan, 0, 0);
else if (kv == GDK_p) roam_sphere_merge_one(self->sphere);
else if (kv == GDK_r) roam_sphere_split_merge(self->sphere);
else if (kv == GDK_u) roam_sphere_update_errors(self->sphere);
+ gdk_threads_enter();
gtk_widget_queue_draw(GTK_WIDGET(self));
+#else
+ gdk_threads_enter();
#endif
return TRUE;
}
+static gboolean _update_errors_cb(gpointer sphere)
+{
+ roam_sphere_update_errors(sphere);
+ return FALSE;
+}
static void on_view_changed(GisView *view,
gdouble _1, gdouble _2, gdouble _3, GisOpenGL *self)
{
g_debug("GisOpenGL: on_view_changed");
+ gdk_threads_enter();
gis_opengl_begin(self);
set_visuals(self);
#ifndef ROAM_DEBUG
- roam_sphere_update_errors(self->sphere);
+ g_idle_add_full(G_PRIORITY_HIGH_IDLE+30, _update_errors_cb, self->sphere, NULL);
+ //roam_sphere_update_errors(self->sphere);
#endif
gis_opengl_redraw(self);
gis_opengl_end(self);
+ gdk_threads_leave();
}
static gboolean on_idle(GisOpenGL *self)
{
//g_debug("GisOpenGL: on_idle");
+ gdk_threads_enter();
gis_opengl_begin(self);
if (roam_sphere_split_merge(self->sphere))
gis_opengl_redraw(self);
gis_opengl_end(self);
+ gdk_threads_leave();
return TRUE;
}
g_assert(GIS_IS_OPENGL(self));
GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(self));
gdk_gl_drawable_gl_end(gldrawable);
+ gdk_threads_leave();
}
void gis_opengl_flush(GisOpenGL *self)
{
g_object_set(self, "can-focus", TRUE, NULL);
#ifndef ROAM_DEBUG
- self->sm_source = g_timeout_add(10, (GSourceFunc)on_idle, self);
+ self->sm_source = g_timeout_add_full(G_PRIORITY_HIGH_IDLE+30, 33, (GSourceFunc)on_idle, self, NULL);
#endif
g_signal_connect(self, "realize", G_CALLBACK(on_realize), NULL);
GisView *view = gis_view_new();
GisOpenGL *opengl = gis_opengl_new(world, view, plugins);
+ gdk_threads_enter();
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(window, "key-press-event", G_CALLBACK(on_key_press), NULL);
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(opengl));
gtk_widget_show_all(window);
- //gis_plugins_load(plugins, "bmng", world, view, opengl, prefs);
+ gdk_threads_leave();
+
+ gis_plugins_load(plugins, "bmng", world, view, opengl, prefs);
gis_plugins_load(plugins, "srtm", world, view, opengl, prefs);
gis_view_set_site(view, "KLSX");
+ gdk_threads_enter();
gtk_main();
g_object_unref(prefs);
g_object_unref(view);
g_object_unref(opengl);
gis_plugins_free(plugins);
+ gdk_threads_leave();
return 0;
}
#define TILE_WIDTH 1024
#define TILE_HEIGHT 512
-static void _load_tile(GisTile *tile, gpointer _self)
+struct _LoadTileData {
+ GisPluginBmng *self;
+ GisTile *tile;
+ GdkPixbuf *pixbuf;
+};
+static gboolean _load_tile_cb(gpointer _data)
{
- GisPluginBmng *self = _self;
- g_debug("GisPluginBmng: _load_tile start");
-
- char *path = gis_wms_make_local(self->wms, tile);
- GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(path, NULL);
- g_free(path);
+ struct _LoadTileData *data = _data;
+ GisPluginBmng *self = data->self;
+ GisTile *tile = data->tile;
+ GdkPixbuf *pixbuf = data->pixbuf;
+ g_free(data);
+ /* Create Texture */
+ g_debug("GisPluginBmng: _load_tile_cb start");
guchar *pixels = gdk_pixbuf_get_pixels(pixbuf);
gboolean alpha = gdk_pixbuf_get_has_alpha(pixbuf);
gint width = gdk_pixbuf_get_width(pixbuf);
tile->data = tex;
gis_opengl_redraw(self->opengl);
g_object_unref(pixbuf);
+ return FALSE;
}
-static void _free_tile(GisTile *tile, gpointer _self)
+static void _load_tile(GisTile *tile, gpointer _self)
{
GisPluginBmng *self = _self;
- g_debug("GisPluginBmng: _free_tile: %p=%d", tile->data, *(guint*)tile->data);
- guint *data = tile->data;
+ g_debug("GisPluginBmng: _load_tile start %p", g_thread_self());
+ char *path = gis_wms_make_local(self->wms, tile);
+ struct _LoadTileData *data = g_new0(struct _LoadTileData, 1);
+ data->self = self;
+ data->tile = tile;
+ data->pixbuf = gdk_pixbuf_new_from_file(path, NULL);
+ g_free(path);
+ g_idle_add_full(G_PRIORITY_LOW, _load_tile_cb, data, NULL);
+ g_debug("GisPluginBmng: _load_tile end %p", g_thread_self());
+}
+
+static gboolean _free_tile_cb(gpointer data)
+{
glDeleteTextures(1, data);
g_free(data);
+ return FALSE;
+}
+static void _free_tile(GisTile *tile, gpointer _self)
+{
+ GisPluginBmng *self = _self;
+ g_debug("GisPluginBmng: _free_tile: %p=%d", tile->data, *(guint*)tile->data);
+ g_idle_add_full(G_PRIORITY_LOW, _free_tile_cb, tile->data, NULL);
}
static gpointer _update_tiles(gpointer _self)
{
g_debug("GisPluginBmng: _update_tiles");
GisPluginBmng *self = _self;
+ g_mutex_lock(self->mutex);
gdouble lat, lon, elev;
gis_view_get_location(self->view, &lat, &lon, &elev);
gis_tile_update(self->tiles,
_load_tile, self);
gis_tile_gc(self->tiles, time(NULL)-10,
_free_tile, self);
+ g_mutex_unlock(self->mutex);
return NULL;
}
static void _on_location_changed(GisView *view, gdouble lat, gdouble lon, gdouble elev,
GisPluginBmng *self)
{
- _update_tiles(self);
+ g_thread_create(_update_tiles, self, FALSE, NULL);
}
/***********
/* Load initial tiles */
_load_tile(self->tiles, self);
- _update_tiles(self);
+ g_thread_create(_update_tiles, self, FALSE, NULL);
/* Connect signals */
g_signal_connect(self->view, "location-changed", G_CALLBACK(_on_location_changed), self);
{
g_debug("GisPluginBmng: init");
/* Set defaults */
+ self->mutex = g_mutex_new();
self->tiles = gis_tile_new(NULL, NORTH, SOUTH, EAST, WEST);
self->wms = gis_wms_new(
"http://www.nasa.network.com/wms", "bmng200406", "image/jpeg",
/* Free data */
gis_tile_free(self->tiles, _free_tile, self);
gis_wms_free(self->wms);
+ g_mutex_free(self->mutex);
G_OBJECT_CLASS(gis_plugin_bmng_parent_class)->finalize(gobject);
}
GisOpenGL *opengl;
GisTile *tiles;
GisWms *wms;
+ GMutex *mutex;
};
struct _GisPluginBmngClass {
* Loader and Freeers *
**********************/
#define LOAD_BIL TRUE
-#define LOAD_OPENGL TRUE
+#define LOAD_OPENGL FALSE
+struct _LoadTileData {
+ GisPluginSrtm *self;
+ GisTile *tile;
+ GdkPixbuf *pixbuf;
+ struct _TileData *data;
+};
static guint16 *_load_bil(gchar *path)
{
gchar *data;
g_debug("GisPluginSrtm: load_opengl %d", opengl);
return opengl;
}
-static void _load_tile(GisTile *tile, gpointer _self)
+static gboolean _load_tile_cb(gpointer _load)
{
- GisPluginSrtm *self = _self;
- g_debug("GisPluginSrtm: _load_tile");
+ struct _LoadTileData *load = _load;
+ GisPluginSrtm *self = load->self;
+ GisTile *tile = load->tile;
+ GdkPixbuf *pixbuf = load->pixbuf;
+ struct _TileData *data = load->data;
+ g_free(load);
- struct _TileData *data = g_new0(struct _TileData, 1);
- gchar *path = gis_wms_make_local(self->wms, tile);
- if (LOAD_BIL || LOAD_OPENGL)
- data->bil = _load_bil(path);
- g_free(path);
- if (LOAD_OPENGL) {
- GdkPixbuf *pixbuf = _load_pixbuf(data->bil);
+ if (LOAD_OPENGL)
data->opengl = _load_opengl(pixbuf);
- g_object_unref(pixbuf);
- }
/* Do necessasairy processing */
+ /* TODO: Lock this and move to thread, can remove self from _load then */
if (LOAD_BIL)
gis_opengl_set_height_func(self->opengl, tile,
_height_func, self, TRUE);
/* Cleanup unneeded things */
if (!LOAD_BIL)
g_free(data->bil);
+ if (LOAD_OPENGL)
+ g_object_unref(pixbuf);
tile->data = data;
+ return FALSE;
}
-
-static void _free_tile(GisTile *tile, gpointer _self)
+static void _load_tile(GisTile *tile, gpointer _self)
{
GisPluginSrtm *self = _self;
- struct _TileData *data = tile->data;
- g_debug("GisPluginSrtm: _free_tile: %p=%d", data, data->opengl);
+
+ g_debug("GisPluginSrtm: _load_tile");
+ gchar *path = gis_wms_make_local(self->wms, tile);
+ struct _LoadTileData *load = g_new0(struct _LoadTileData, 1);
+ load->self = self;
+ load->tile = tile;
+ load->data = g_new0(struct _TileData, 1);
+ if (LOAD_BIL || LOAD_OPENGL)
+ load->data->bil = _load_bil(path);
+ if (LOAD_OPENGL)
+ load->pixbuf = _load_pixbuf(load->data->bil);
+
+ g_idle_add_full(G_PRIORITY_LOW, _load_tile_cb, load, NULL);
+ g_free(path);
+}
+
+static gboolean _free_tile_cb(gpointer _data)
+{
+ struct _TileData *data = _data;
if (LOAD_BIL)
g_free(data->bil);
if (LOAD_OPENGL)
glDeleteTextures(1, &data->opengl);
g_free(data);
+ return FALSE;
+}
+static void _free_tile(GisTile *tile, gpointer _self)
+{
+ GisPluginSrtm *self = _self;
+ g_debug("GisPluginSrtm: _free_tile: %p=%d", tile->data, *(guint*)tile->data);
+ g_idle_add_full(G_PRIORITY_LOW, _free_tile_cb, tile->data, NULL);
}
static gpointer _update_tiles(gpointer _self)
{
GisPluginSrtm *self = _self;
+ g_mutex_lock(self->mutex);
gdouble lat, lon, elev;
gis_view_get_location(self->view, &lat, &lon, &elev);
gis_tile_update(self->tiles,
_load_tile, self);
gis_tile_gc(self->tiles, time(NULL)-10,
_free_tile, self);
+ g_mutex_unlock(self->mutex);
return NULL;
}
static void _on_location_changed(GisView *view, gdouble lat, gdouble lon, gdouble elev,
GisPluginSrtm *self)
{
- _update_tiles(self);
+ g_thread_create(_update_tiles, self, FALSE, NULL);
}
/***********
/* Load initial tiles */
_load_tile(self->tiles, self);
- _update_tiles(self);
+ g_thread_create(_update_tiles, self, FALSE, NULL);
/* Connect signals */
g_signal_connect(view, "location-changed", G_CALLBACK(_on_location_changed), self);
{
g_debug("GisPluginSrtm: init");
/* Set defaults */
+ self->mutex = g_mutex_new();
self->tiles = gis_tile_new(NULL, NORTH, SOUTH, EAST, WEST);
self->wms = gis_wms_new(
"http://www.nasa.network.com/elev", "srtm30", "application/bil",
/* Free data */
gis_tile_free(self->tiles, _free_tile, self);
gis_wms_free(self->wms);
+ g_mutex_free(self->mutex);
G_OBJECT_CLASS(gis_plugin_srtm_parent_class)->finalize(gobject);
}
GisOpenGL *opengl;
GisTile *tiles;
GisWms *wms;
+ GMutex *mutex;
};
struct _GisPluginSrtmClass {