[grits] Fix memory leaks in tile loading
- From: Andy Spencer <andys src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [grits] Fix memory leaks in tile loading
- Date: Thu, 16 Feb 2012 23:18:49 +0000 (UTC)
commit 6ec0202fba35eb878af793ed6086ff928f13ce5b
Author: Andy Spencer <andy753421 gmail com>
Date: Mon Feb 13 23:12:20 2012 +0000
Fix memory leaks in tile loading
- Splitting a tile could accidentally overwrite a already split tile if
one (but not all) of the children were garbage collected.
- Garbage collection never actually happened.. because tile always had
empty children. To fix this a `load' flag was added so that the
children could be garbage collected as well without having to check
the data flag which may always be null.
tile->load: set when texture loading has started
tile->data: set when texture loading has finished
src/objects/grits-tile.c | 66 ++++++++++++++++++++++++++++-----------------
src/objects/grits-tile.h | 1 +
2 files changed, 42 insertions(+), 25 deletions(-)
---
diff --git a/src/objects/grits-tile.c b/src/objects/grits-tile.c
index f536c96..f269e5e 100644
--- a/src/objects/grits-tile.c
+++ b/src/objects/grits-tile.c
@@ -64,8 +64,10 @@ GritsTile *grits_tile_new(GritsTile *parent,
tile->atime = time(NULL);
grits_bounds_set_bounds(&tile->coords, 0, 1, 1, 0);
grits_bounds_set_bounds(&tile->edge, n, s, e, w);
- if (parent)
- tile->proj = parent->proj;
+ if (parent) {
+ tile->proj = parent->proj;
+ tile->zindex = parent->zindex+1;
+ }
return tile;
}
@@ -149,12 +151,18 @@ static void _grits_tile_split_latlon(GritsTile *tile)
const gdouble lon_step = lon_dist / cols;
int row, col;
- grits_tile_foreach_index(tile, row, col)
- tile->children[row][col] = grits_tile_new(tile,
- tile->edge.n - lat_step*(row+0), // north
- tile->edge.n - lat_step*(row+1), // south
- tile->edge.w + lon_step*(col+1), // east
- tile->edge.w + lon_step*(col+0)); // west
+ grits_tile_foreach_index(tile, row, col) {
+ if (!tile->children[row][col])
+ tile->children[row][col] =
+ grits_tile_new(tile, 0, 0, 0, 0);
+ /* Set edges aferwards so that north and south
+ * get reset for mercator projections */
+ GritsTile *child = tile->children[row][col];
+ child->edge.n = tile->edge.n - lat_step*(row+0);
+ child->edge.s = tile->edge.n - lat_step*(row+1);
+ child->edge.e = tile->edge.w + lon_step*(col+1);
+ child->edge.w = tile->edge.w + lon_step*(col+0);
+ }
}
static void _grits_tile_split_mercator(GritsTile *tile)
@@ -196,26 +204,30 @@ void grits_tile_update(GritsTile *tile, GritsPoint *eye,
gdouble res, gint width, gint height,
GritsTileLoadFunc load_func, gpointer user_data)
{
- //g_debug("GritsTile: update - %p->atime = %u",
- // tile, (guint)tile->atime);
GritsTile *child;
if (tile == NULL)
return;
- if (!tile->data)
- load_func(tile, user_data);
-
- tile->atime = time(NULL);
+ //g_debug("GritsTile: update - %p->atime = %u",
+ // tile, (guint)tile->atime);
- /* Is this tile high enough resolution? */
- if (_grits_tile_precise(eye, &tile->edge, res, width, height)) {
- grits_tile_foreach(tile, child)
- if (child)
- GRITS_OBJECT(child)->hidden = TRUE;
+ /* Is the parent tile's texture high enough
+ * resolution for this part? */
+ gint xs = G_N_ELEMENTS(tile->children);
+ gint ys = G_N_ELEMENTS(tile->children[0]);
+ if (_grits_tile_precise(eye, &tile->edge, res, width/xs, height/ys)) {
+ GRITS_OBJECT(tile)->hidden = TRUE;
return;
}
+ /* Load the tile */
+ if (!tile->load && !tile->data)
+ load_func(tile, user_data);
+ tile->atime = time(NULL);
+ tile->load = TRUE;
+ GRITS_OBJECT(tile)->hidden = FALSE;
+
/* Split tile if needed */
grits_tile_foreach(tile, child) {
if (child == NULL) {
@@ -227,12 +239,9 @@ void grits_tile_update(GritsTile *tile, GritsPoint *eye,
}
/* Update recursively */
- grits_tile_foreach(tile, child) {
- GRITS_OBJECT(child)->hidden = FALSE;
+ grits_tile_foreach(tile, child)
grits_tile_update(child, eye, res, width, height,
load_func, user_data);
- }
-
}
/**
@@ -303,8 +312,10 @@ GritsTile *grits_tile_gc(GritsTile *root, time_t atime,
}
//g_debug("GritsTile: gc - %p->atime=%u < atime=%u",
// root, (guint)root->atime, (guint)atime);
- if (!has_children && root->atime < atime && root->data) {
- free_func(root, user_data);
+ if (!has_children && root->atime < atime &&
+ (root->data || !root->load)) {
+ if (root->data)
+ free_func(root, user_data);
g_object_unref(root);
return NULL;
}
@@ -459,6 +470,11 @@ static void grits_tile_draw_one(GritsTile *tile, GritsOpenGL *opengl, GList *tri
/* Draw the tile */
static gboolean grits_tile_draw_rec(GritsTile *tile, GritsOpenGL *opengl)
{
+ //g_debug("GritsTile: draw_rec - tile=%p, data=%d, load=%d, hide=%d", tile,
+ // tile ? !!tile->data : 0,
+ // tile ? !!tile->load : 0,
+ // tile ? !!GRITS_OBJECT(tile)->hidden : 0);
+
if (!tile || !tile->data || GRITS_OBJECT(tile)->hidden)
return FALSE;
diff --git a/src/objects/grits-tile.h b/src/objects/grits-tile.h
index f2b706f..b13e1c3 100644
--- a/src/objects/grits-tile.h
+++ b/src/objects/grits-tile.h
@@ -37,6 +37,7 @@ struct _GritsTile {
/* Pointer to the tile data */
gpointer data;
+ gboolean load;
/* Drawing order */
gint zindex;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]