[Bf-blender-cvs] [fe3c796] free-refcount-ids: Free ID: Brush & World.

Bastien Montagne noreply at git.blender.org
Wed Sep 30 22:00:16 CEST 2015


Commit: fe3c796c3127f63f863fe9f1a66bb202826e07d6
Author: Bastien Montagne
Date:   Wed Sep 30 21:34:57 2015 +0200
Branches: free-refcount-ids
https://developer.blender.org/rBfe3c796c3127f63f863fe9f1a66bb202826e07d6

Free ID: Brush & World.

===================================================================

M	source/blender/blenkernel/BKE_brush.h
M	source/blender/blenkernel/BKE_world.h
M	source/blender/blenkernel/intern/brush.c
M	source/blender/blenkernel/intern/library.c
M	source/blender/blenkernel/intern/world.c
M	source/blender/editors/render/render_preview.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index aff3fb0..e64ca00 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -44,7 +44,8 @@ struct Brush *BKE_brush_add(struct Main *bmain, const char *name, short ob_mode)
 struct Brush *BKE_brush_first_search(struct Main *bmain, short ob_mode);
 struct Brush *BKE_brush_copy(struct Brush *brush);
 void BKE_brush_make_local(struct Brush *brush);
-void BKE_brush_free(struct Brush *brush);
+void BKE_brush_release_datablocks(struct Brush *brush);
+void BKE_brush_free(struct Brush *brush, const bool do_id_user);
 
 void BKE_brush_sculpt_reset(struct Brush *brush);
 
diff --git a/source/blender/blenkernel/BKE_world.h b/source/blender/blenkernel/BKE_world.h
index 7f4ba6c..422feb6 100644
--- a/source/blender/blenkernel/BKE_world.h
+++ b/source/blender/blenkernel/BKE_world.h
@@ -36,8 +36,8 @@
 struct Main;
 struct World;
 
-void BKE_world_free(struct World *sc);
-void BKE_world_free_ex(struct World *sc, bool do_id_user);
+void BKE_world_release_datablocks(struct World *wrld);
+void BKE_world_free(struct World *sc, const bool do_id_user);
 struct World *add_world(struct Main *bmian, const char *name);
 struct World *BKE_world_copy(struct World *wrld);
 struct World *localize_world(struct World *wrld);
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index e0ffd83..1e21c26 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -197,22 +197,48 @@ Brush *BKE_brush_copy(Brush *brush)
 	return brushn;
 }
 
-/* not brush itself */
-void BKE_brush_free(Brush *brush)
+/**
+ * Release all datablocks (ID) used by this brush (datablocks are never freed, they are just unreferenced).
+ *
+ * \param brush The brush which has to release its data.
+ */
+void BKE_brush_release_datablocks(Brush *brush)
 {
 	id_us_min((ID *)brush->mtex.tex);
+	brush->mtex.tex = NULL;
+
 	id_us_min((ID *)brush->mask_mtex.tex);
+	brush->mask_mtex.tex = NULL;
+
 	id_us_min((ID *)brush->paint_curve);
+	brush->paint_curve = NULL;
 
-	if (brush->icon_imbuf)
+	/* No ID refcount here... */
+	brush->toggle_brush = NULL;
+}
+
+/**
+ * Free (or release) any data used by this brush (does not free the brush itself).
+ *
+ * \param brush The brush to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this brush are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_brush_free(Brush *brush, const bool do_id_user)
+{
+	if (do_id_user) {
+		BKE_brush_release_datablocks(brush);
+	}
+
+	if (brush->icon_imbuf) {
 		IMB_freeImBuf(brush->icon_imbuf);
+	}
 
 	BKE_previewimg_free(&(brush->preview));
 
 	curvemapping_free(brush->curve);
 
-	if (brush->gradient)
-		MEM_freeN(brush->gradient);
+	MEM_SAFE_FREE(brush->gradient);
 }
 
 static void extern_local_brush(Brush *brush)
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index c4a8f52..a3e945c 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -985,7 +985,7 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, bool do_id_user)
 			BKE_key_free((Key *)id, do_id_user);
 			break;
 		case ID_WO:
-			BKE_world_free((World *)id);
+			BKE_world_free((World *)id, do_id_user);
 			break;
 		case ID_SCR:
 			BKE_screen_free((bScreen *)id, do_id_user);
@@ -1015,10 +1015,10 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, bool do_id_user)
 			BKE_action_free((bAction *)id);
 			break;
 		case ID_NT:
-			ntreeFreeTree_ex((bNodeTree *)id, do_id_user);
+			ntreeFreeTree_ex((bNodeTree *)id, do_id_user);  /* TODO! */
 			break;
 		case ID_BR:
-			BKE_brush_free((Brush *)id);
+			BKE_brush_free((Brush *)id, do_id_user);
 			break;
 		case ID_PA:
 			BKE_particlesettings_free((ParticleSettings *)id, do_id_user);
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index e4736b1..7f49705 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -51,36 +51,56 @@
 
 #include "GPU_material.h"
 
-void BKE_world_free_ex(World *wrld, bool do_id_user)
+/**
+ * Release all datablocks (ID) used by this world (datablocks are never freed, they are just unreferenced).
+ *
+ * \param wrld The world which has to release its data.
+ */
+void BKE_world_release_datablocks(World *wrld)
 {
 	MTex *mtex;
 	int a;
-	
+
 	for (a = 0; a < MAX_MTEX; a++) {
 		mtex = wrld->mtex[a];
-		if (do_id_user && mtex && mtex->tex) mtex->tex->id.us--;
-		if (mtex) MEM_freeN(mtex);
+		if (mtex && mtex->tex) {
+			id_us_min(&mtex->tex->id);
+			mtex->tex = NULL;
+		}
+	}
+}
+
+/**
+ * Free (or release) any data used by this world (does not free the world itself).
+ *
+ * \param wrld The world to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this world are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_world_free(World *wrld, const bool do_id_user)
+{
+	int a;
+
+	if (do_id_user) {
+		BKE_world_release_datablocks(wrld);
+	}
+
+	for (a = 0; a < MAX_MTEX; a++) {
+		MEM_SAFE_FREE(wrld->mtex[a]);
 	}
-	BKE_previewimg_free(&wrld->preview);
 
 	BKE_animdata_free((ID *)wrld);
 
 	/* is no lib link block, but world extension */
 	if (wrld->nodetree) {
 		ntreeFreeTree_ex(wrld->nodetree, do_id_user);
-		MEM_freeN(wrld->nodetree);
+		MEM_SAFE_FREE(wrld->nodetree);
 	}
 
-	if (wrld->gpumaterial.first)
-		GPU_material_free(&wrld->gpumaterial);
+	GPU_material_free(&wrld->gpumaterial);
 	
 	BKE_icon_id_delete((struct ID *)wrld);
-	wrld->id.icon_id = 0;
-}
-
-void BKE_world_free(World *wrld)
-{
-	BKE_world_free_ex(wrld, true);
+	BKE_previewimg_free(&wrld->preview);
 }
 
 World *add_world(Main *bmain, const char *name)
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index e0394ab..02c8224 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -860,7 +860,7 @@ static void shader_preview_free(void *customdata)
 		
 		/* get rid of copied world */
 		BLI_remlink(&pr_main->world, sp->worldcopy);
-		BKE_world_free_ex(sp->worldcopy, true); /* [#32865] - we need to unlink the texture copies, unlike for materials */
+		BKE_world_free(sp->worldcopy, true); /* [#32865] - we need to unlink the texture copies, unlike for materials */
 		
 		properties = IDP_GetProperties((ID *)sp->worldcopy, false);
 		if (properties) {




More information about the Bf-blender-cvs mailing list