Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchell Stokes <mogurijin@gmail.com>2013-08-11 01:17:46 +0400
committerMitchell Stokes <mogurijin@gmail.com>2013-08-11 01:17:46 +0400
commit3627541894e2875b74d974abfe9ead60b68c4d05 (patch)
treeb4b24fc9e43b6873ea60ff1acc4793847a118d29
parent4c136881a5a17f411ea05588ee86479f94cc2429 (diff)
BGE: Fixing the memory leaks reported when the BlenderPlayer exits.
They were caused by not having a free_windowmanager_cb set and by not having registered SpaceTypes, which meant data allocated for thosse SpaceTypes could not be freed. These were solved by defining a free_windowmanager_cb for the player that just frees wmWindows, and by making sure we only allocate memory for registered SpaceTypes.
-rw-r--r--source/blender/blenkernel/BKE_screen.h1
-rw-r--r--source/blender/blenkernel/intern/screen.c5
-rw-r--r--source/blender/blenloader/intern/readfile.c46
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_ghost.cpp10
4 files changed, 47 insertions, 15 deletions
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index b5a6c6fb821..c883bdf74e0 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -254,6 +254,7 @@ struct SpaceType *BKE_spacetype_from_id(int spaceid);
struct ARegionType *BKE_regiontype_from_id(struct SpaceType *st, int regionid);
const struct ListBase *BKE_spacetypes_list(void);
void BKE_spacetype_register(struct SpaceType *st);
+int BKE_spacetype_exists(int spaceid);
void BKE_spacetypes_free(void); /* only for quitting blender */
/* spacedata */
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 01f57b95378..fe2f52d79fd 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -136,6 +136,11 @@ void BKE_spacetype_register(SpaceType *st)
BLI_addtail(&spacetypes, st);
}
+int BKE_spacetype_exists(int spaceid)
+{
+ return BKE_spacetype_from_id(spaceid) != NULL;
+}
+
/* ***************** Space handling ********************** */
void BKE_spacedata_freelist(ListBase *lb)
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 66fd58c42dc..1f8bbfbec88 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6138,20 +6138,26 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
ui_list->type = NULL;
}
- ar->regiondata = newdataadr(fd, ar->regiondata);
- if (ar->regiondata) {
- if (spacetype == SPACE_VIEW3D) {
- RegionView3D *rv3d = ar->regiondata;
-
- rv3d->localvd = newdataadr(fd, rv3d->localvd);
- rv3d->clipbb = newdataadr(fd, rv3d->clipbb);
-
- rv3d->depths = NULL;
- rv3d->gpuoffscreen = NULL;
- rv3d->ri = NULL;
- rv3d->render_engine = NULL;
- rv3d->sms = NULL;
- rv3d->smooth_timer = NULL;
+ if (spacetype == SPACE_EMPTY) {
+ /* unkown space type, don't leak regiondata */
+ ar->regiondata = NULL;
+ }
+ else {
+ ar->regiondata = newdataadr(fd, ar->regiondata);
+ if (ar->regiondata) {
+ if (spacetype == SPACE_VIEW3D) {
+ RegionView3D *rv3d = ar->regiondata;
+
+ rv3d->localvd = newdataadr(fd, rv3d->localvd);
+ rv3d->clipbb = newdataadr(fd, rv3d->clipbb);
+
+ rv3d->depths = NULL;
+ rv3d->gpuoffscreen = NULL;
+ rv3d->ri = NULL;
+ rv3d->render_engine = NULL;
+ rv3d->sms = NULL;
+ rv3d->smooth_timer = NULL;
+ }
}
}
@@ -6238,6 +6244,11 @@ static bool direct_link_screen(FileData *fd, bScreen *sc)
sa->handlers.first = sa->handlers.last = NULL;
sa->type = NULL; /* spacetype callbacks */
sa->region_active_win = -1;
+
+ /* if we do not have the spacetype registered (game player), we cannot
+ * free it, so don't allocate any new memory for such spacetypes. */
+ if (!BKE_spacetype_exists(sa->spacetype))
+ sa->spacetype = SPACE_EMPTY;
for (ar = sa->regionbase.first; ar; ar = ar->next)
direct_link_region(fd, ar, sa->spacetype);
@@ -6255,7 +6266,12 @@ static bool direct_link_screen(FileData *fd, bScreen *sc)
for (sl = sa->spacedata.first; sl; sl = sl->next) {
link_list(fd, &(sl->regionbase));
-
+
+ /* if we do not have the spacetype registered (game player), we cannot
+ * free it, so don't allocate any new memory for such spacetypes. */
+ if (!BKE_spacetype_exists(sl->spacetype))
+ sl->spacetype = SPACE_EMPTY;
+
for (ar = sl->regionbase.first; ar; ar = ar->next)
direct_link_region(fd, ar, sl->spacetype);
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
index 817a4d8efac..ccbcdd25639 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -118,6 +118,14 @@ static void mem_error_cb(const char *errorStr)
fflush(stderr);
}
+// library.c will only free window managers with a callback function.
+// We don't actually use a wmWindowManager, but loading a blendfile
+// loads wmWindows, so we need to free those.
+static void wm_free(bContext *C, wmWindowManager *wm)
+{
+ BLI_freelistN(&wm->windows);
+}
+
#ifdef WIN32
typedef enum {
SCREEN_SAVER_MODE_NONE = 0,
@@ -501,6 +509,8 @@ int main(int argc, char** argv)
sound_init_once();
+ set_free_windowmanager_cb(wm_free);
+
/* if running blenderplayer the last argument can't be parsed since it has to be the filename. */
isBlenderPlayer = !BLO_is_a_runtime(argv[0]);
if (isBlenderPlayer)