[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [59055] trunk/blender/source: BGE: Fixing the memory leaks reported when the BlenderPlayer exits.

Mitchell Stokes mogurijin at gmail.com
Sat Aug 10 23:17:46 CEST 2013


Revision: 59055
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59055
Author:   moguri
Date:     2013-08-10 21:17:46 +0000 (Sat, 10 Aug 2013)
Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_screen.h
    trunk/blender/source/blender/blenkernel/intern/screen.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp

Modified: trunk/blender/source/blender/blenkernel/BKE_screen.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_screen.h	2013-08-10 19:05:17 UTC (rev 59054)
+++ trunk/blender/source/blender/blenkernel/BKE_screen.h	2013-08-10 21:17:46 UTC (rev 59055)
@@ -254,6 +254,7 @@
 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 */

Modified: trunk/blender/source/blender/blenkernel/intern/screen.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/screen.c	2013-08-10 19:05:17 UTC (rev 59054)
+++ trunk/blender/source/blender/blenkernel/intern/screen.c	2013-08-10 21:17:46 UTC (rev 59055)
@@ -136,6 +136,11 @@
 	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)

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c	2013-08-10 19:05:17 UTC (rev 59054)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c	2013-08-10 21:17:46 UTC (rev 59055)
@@ -6138,20 +6138,26 @@
 		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 @@
 		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 @@
 		
 		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);
 			

Modified: trunk/blender/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
===================================================================
--- trunk/blender/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp	2013-08-10 19:05:17 UTC (rev 59054)
+++ trunk/blender/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp	2013-08-10 21:17:46 UTC (rev 59055)
@@ -118,6 +118,14 @@
 	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 @@
 
 	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)




More information about the Bf-blender-cvs mailing list