[Bf-blender-cvs] [2282a80] free-refcount-ids: ID freeing: materials and textures.

Bastien Montagne noreply at git.blender.org
Wed Sep 30 20:27:06 CEST 2015


Commit: 2282a8069772c9fef2ca47c1ffd0bda84631500d
Author: Bastien Montagne
Date:   Sun Sep 27 15:12:27 2015 +0200
Branches: free-refcount-ids
https://developer.blender.org/rB2282a8069772c9fef2ca47c1ffd0bda84631500d

ID freeing: materials and textures.

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

M	source/blender/blenkernel/BKE_material.h
M	source/blender/blenkernel/BKE_texture.h
M	source/blender/blenkernel/intern/library.c
M	source/blender/blenkernel/intern/material.c
M	source/blender/blenkernel/intern/texture.c
M	source/blender/editors/render/render_preview.c
M	source/blender/render/intern/source/render_texture.c

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

diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index a3c61f4..dda427e 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -45,8 +45,8 @@ struct Scene;
 /* materials */
 
 void init_def_material(void);
-void BKE_material_free(struct Material *sc); 
-void BKE_material_free_ex(struct Material *ma, bool do_id_user);
+void BKE_material_release_datablocks(struct Material *ma);
+void BKE_material_free(struct Material *ma, const bool do_id_user);
 void test_object_materials(struct Main *bmain, struct ID *id);
 void BKE_material_resize_object(struct Object *ob, const short totcol, bool do_id_user);
 void init_material(struct Material *ma);
diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h
index 95918b9..ba805a5 100644
--- a/source/blender/blenkernel/BKE_texture.h
+++ b/source/blender/blenkernel/BKE_texture.h
@@ -67,7 +67,8 @@ struct CBData *colorband_element_add(struct ColorBand *coba, float position);
 int colorband_element_remove(struct ColorBand *coba, int index);
 void colorband_update_sort(struct ColorBand *coba);
 
-void         BKE_texture_free(struct Tex *tex);
+void         BKE_texture_release_datablocks(struct Tex *tex);
+void         BKE_texture_free(struct Tex *tex, const bool do_id_user);
 void         BKE_texture_default(struct Tex *tex);
 struct Tex  *BKE_texture_copy(struct Tex *tex);
 struct Tex  *BKE_texture_add(struct Main *bmain, const char *name);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index e770564..a83b1e0 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -961,10 +961,10 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, bool do_id_user)
 			BKE_mball_free((MetaBall *)id, do_id_user);
 			break;
 		case ID_MA:
-			BKE_material_free((Material *)id);
+			BKE_material_free((Material *)id, do_id_user);
 			break;
 		case ID_TE:
-			BKE_texture_free((Tex *)id);
+			BKE_texture_free((Tex *)id, do_id_user);
 			break;
 		case ID_IM:
 			BKE_image_free((Image *)id);
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 3e7e98b..d6654fb 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -81,33 +81,66 @@ void init_def_material(void)
 	init_material(&defmaterial);
 }
 
-/* not material itself */
-void BKE_material_free(Material *ma)
+/**
+ * Release all datablocks (ID) used by this material (datablocks are never freed, they are just unreferenced).
+ *
+ * \param ma The material which has to release its data.
+ */
+void BKE_material_release_datablocks(Material *ma)
 {
-	BKE_material_free_ex(ma, true);
+	MTex *mtex;
+	int a;
+
+	if (ma == NULL)
+		return;
+
+	for (a = 0; a < MAX_MTEX; a++) {
+		mtex = ma->mtex[a];
+		if (mtex && mtex->tex) {
+			mtex->tex->id.us--;
+			mtex->tex = NULL;
+		}
+	}
+
+	/* No ID refcount here... */
+	ma->group = NULL;
 }
 
-/* not material itself */
-void BKE_material_free_ex(Material *ma, bool do_id_user)
+/**
+ * Free (or release) any data used by this material (does not free the material itself).
+ *
+ * \param ma The material to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this material are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_material_free(Material *ma, const bool do_id_user)
 {
 	MTex *mtex;
 	int a;
 	
+	BKE_material_release_datablocks(ma);
+
 	for (a = 0; a < MAX_MTEX; a++) {
 		mtex = ma->mtex[a];
-		if (do_id_user && mtex && mtex->tex) mtex->tex->id.us--;
-		if (mtex) MEM_freeN(mtex);
+		if (mtex) {
+			MEM_freeN(mtex);
+			ma->mtex[a] = NULL;
+		}
 	}
 	
-	if (ma->ramp_col) MEM_freeN(ma->ramp_col);
-	if (ma->ramp_spec) MEM_freeN(ma->ramp_spec);
+	if (ma->ramp_col) {
+		MEM_freeN(ma->ramp_col);
+		ma->ramp_col = NULL;
+	}
+	if (ma->ramp_spec) {
+		MEM_freeN(ma->ramp_spec);
+		ma->ramp_spec = NULL;
+	}
 	
 	BKE_animdata_free((ID *)ma);
 	
-	if (ma->preview)
-		BKE_previewimg_free(&ma->preview);
-	BKE_icon_id_delete((struct ID *)ma);
-	ma->id.icon_id = 0;
+	BKE_previewimg_free(&ma->preview);
+	BKE_icon_id_delete((ID *)ma);
 	
 	/* is no lib link block, but material extension */
 	if (ma->nodetree) {
@@ -115,11 +148,12 @@ void BKE_material_free_ex(Material *ma, bool do_id_user)
 		MEM_freeN(ma->nodetree);
 	}
 
-	if (ma->texpaintslot)
+	if (ma->texpaintslot) {
 		MEM_freeN(ma->texpaintslot);
+		ma->texpaintslot = NULL;
+	}
 
-	if (ma->gpumaterial.first)
-		GPU_material_free(&ma->gpumaterial);
+	GPU_material_free(&ma->gpumaterial);
 }
 
 void init_material(Material *ma)
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 88a412d..3549fd8 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -557,23 +557,67 @@ int colorband_element_remove(struct ColorBand *coba, int index)
 
 /* ******************* TEX ************************ */
 
-void BKE_texture_free(Tex *tex)
+/**
+ * Release all datablocks (ID) used by this texture (datablocks are never freed, they are just unreferenced).
+ *
+ * \param tex The texture which has to release its data.
+ */
+void BKE_texture_release_datablocks(Tex *tex)
 {
-	if (tex->coba) MEM_freeN(tex->coba);
-	if (tex->env) BKE_texture_envmap_free(tex->env);
-	if (tex->pd) BKE_texture_pointdensity_free(tex->pd);
-	if (tex->vd) BKE_texture_voxeldata_free(tex->vd);
-	if (tex->ot) BKE_texture_ocean_free(tex->ot);
-	BKE_animdata_free((struct ID *)tex);
-	
-	BKE_previewimg_free(&tex->preview);
-	BKE_icon_id_delete((struct ID *)tex);
-	tex->id.icon_id = 0;
-	
+	if (tex == NULL)
+		return;
+
+	if (tex->ima) {
+		tex->ima->id.us--;
+		tex->ima = NULL;
+	}
+}
+
+/**
+ * Free (or release) any data used by this texture (does not free the texure itself).
+ *
+ * \param te The texure to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this texture are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_texture_free(Tex *tex, const bool do_id_user)
+{
+	if (do_id_user) {
+		BKE_texture_release_datablocks(tex);
+	}
+
+	BKE_animdata_free((ID *)tex);
+
+	/* is no lib link block, but material extension */
 	if (tex->nodetree) {
-		ntreeFreeTree(tex->nodetree);
+		ntreeFreeTree_ex(tex->nodetree, do_id_user);
 		MEM_freeN(tex->nodetree);
+		tex->nodetree = NULL;
+	}
+
+	if (tex->coba) {
+		MEM_freeN(tex->coba);
+		tex->coba = NULL;
+	}
+	if (tex->env) {
+		BKE_texture_envmap_free(tex->env);
+		tex->env = NULL;
 	}
+	if (tex->pd) {
+		BKE_texture_pointdensity_free(tex->pd);
+		tex->pd = NULL;
+	}
+	if (tex->vd) {
+		BKE_texture_voxeldata_free(tex->vd);
+		tex->vd = NULL;
+	}
+	if (tex->ot) {
+		BKE_texture_ocean_free(tex->ot);
+		tex->ot = NULL;
+	}
+	
+	BKE_previewimg_free(&tex->preview);
+	BKE_icon_id_delete((ID *)tex);
 }
 
 /* ------------------------------------------------------------------------- */
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 6dfd2b3..8a31bc0 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -828,7 +828,7 @@ static void shader_preview_free(void *customdata)
 		/* get rid of copied material */
 		BLI_remlink(&pr_main->mat, sp->matcopy);
 		
-		BKE_material_free_ex(sp->matcopy, false);
+		BKE_material_free(sp->matcopy, false);
 
 		properties = IDP_GetProperties((ID *)sp->matcopy, false);
 		if (properties) {
@@ -844,7 +844,7 @@ static void shader_preview_free(void *customdata)
 		
 		/* get rid of copied texture */
 		BLI_remlink(&pr_main->tex, sp->texcopy);
-		BKE_texture_free(sp->texcopy);
+		BKE_texture_free(sp->texcopy, false);
 		
 		properties = IDP_GetProperties((ID *)sp->texcopy, false);
 		if (properties) {
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index b282ec0..2f3f69a 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -3655,7 +3655,8 @@ void RE_free_sample_material(Material *mat)
 			MTex *mtex= mat->mtex[tex_nr];
 	
 			if (mtex->tex) {
-				BKE_texture_free(mtex->tex);
+				/* don't update user counts as we are freeing a duplicate */
+				BKE_texture_free(mtex->tex, false);
 				MEM_freeN(mtex->tex);
 				mtex->tex = NULL;
 			}
@@ -3663,7 +3664,7 @@ void RE_free_sample_material(Material *mat)
 	}
 
 	/* don't update user counts as we are freeing a duplicate */
-	BKE_material_free_ex(mat, false);
+	BKE_material_free(mat, false);
 	MEM_freeN(mat);
 }




More information about the Bf-blender-cvs mailing list