[Bf-blender-cvs] [049b6cf] master: Fix for image garbage collection failing to run for render-only views

Campbell Barton noreply at git.blender.org
Thu May 22 04:00:48 CEST 2014


Commit: 049b6cfa6ddcc44d8001804922f041367f3051c6
Author: Campbell Barton
Date:   Thu May 22 11:58:07 2014 +1000
https://developer.blender.org/rB049b6cfa6ddcc44d8001804922f041367f3051c6

Fix for image garbage collection failing to run for render-only views

Check for freeing old images was running per-object, move this to viewport drawing.

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

M	source/blender/blenkernel/BKE_image.h
M	source/blender/blenkernel/intern/image.c
M	source/blender/editors/space_view3d/drawobject.c
M	source/blender/editors/space_view3d/view3d_draw.c
M	source/blender/gpu/GPU_draw.h
M	source/blender/gpu/intern/gpu_draw.c
M	source/blender/render/intern/source/render_texture.c

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

diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index db052f5..f02a5d0 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -52,8 +52,9 @@ struct Main;
 void   BKE_images_init(void);
 void   BKE_images_exit(void);
 
+void    BLI_image_free_buffers(struct Image *image);
 /* call from library */
-void    BKE_image_free(struct Image *me);
+void    BKE_image_free(struct Image *image);
 
 void    BKE_imbuf_stamp_info(struct Scene *scene, struct Object *camera, struct ImBuf *ibuf);
 void    BKE_stamp_buf(struct Scene *scene, struct Object *camera, unsigned char *rect, float *rectf, int width, int height, int channels);
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 440320e..2d5b6b0 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -256,7 +256,11 @@ static void image_free_cahced_frames(Image *image)
 	}
 }
 
-static void image_free_buffers(Image *ima)
+/**
+ * Simply free the image data from memory,
+ * on display the image can load again (except for render buffers).
+ */
+void BLI_image_free_buffers(Image *ima)
 {
 	image_free_cahced_frames(ima);
 
@@ -278,7 +282,7 @@ void BKE_image_free(Image *ima)
 {
 	int a;
 
-	image_free_buffers(ima);
+	BLI_image_free_buffers(ima);
 	if (ima->packedfile) {
 		freePackedFile(ima->packedfile);
 		ima->packedfile = NULL;
@@ -835,8 +839,7 @@ void BKE_image_memorypack(Image *ima)
 
 void BKE_image_tag_time(Image *ima)
 {
-	if (ima)
-		ima->lastused = (int)PIL_check_seconds_timer();
+	ima->lastused = (int)PIL_check_seconds_timer();
 }
 
 #if 0
@@ -854,43 +857,6 @@ static void tag_all_images_time()
 }
 #endif
 
-void free_old_images(void)
-{
-	Image *ima;
-	static int lasttime = 0;
-	int ctime = (int)PIL_check_seconds_timer();
-
-	/*
-	 * Run garbage collector once for every collecting period of time
-	 * if textimeout is 0, that's the option to NOT run the collector
-	 */
-	if (U.textimeout == 0 || ctime % U.texcollectrate || ctime == lasttime)
-		return;
-
-	/* of course not! */
-	if (G.is_rendering)
-		return;
-
-	lasttime = ctime;
-
-	ima = G.main->image.first;
-	while (ima) {
-		if ((ima->flag & IMA_NOCOLLECT) == 0 && ctime - ima->lastused > U.textimeout) {
-			/* If it's in GL memory, deallocate and set time tag to current time
-			 * This gives textures a "second chance" to be used before dying. */
-			if (ima->bindcode || ima->repbind) {
-				GPU_free_image(ima);
-				ima->lastused = ctime;
-			}
-			/* Otherwise, just kill the buffers */
-			else {
-				image_free_buffers(ima);
-			}
-		}
-		ima = ima->id.next;
-	}
-}
-
 static uintptr_t image_mem_size(Image *image)
 {
 	uintptr_t size = 0;
@@ -2251,7 +2217,7 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
 
 	switch (signal) {
 		case IMA_SIGNAL_FREE:
-			image_free_buffers(ima);
+			BLI_image_free_buffers(ima);
 			if (iuser)
 				iuser->ok = 1;
 			break;
@@ -2283,7 +2249,7 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
 #if 0
 			/* force reload on first use, but not for multilayer, that makes nodes and buttons in ui drawing fail */
 			if (ima->type != IMA_TYPE_MULTILAYER)
-				image_free_buffers(ima);
+				BLI_image_free_buffers(ima);
 #else
 			/* image buffers for non-sequence multilayer will share buffers with RenderResult,
 			 * however sequence multilayer will own buffers. Such logic makes switching from
@@ -2292,7 +2258,7 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
 			 * are nicely detecting anyway, but freeing buffers always here makes multilayer
 			 * sequences behave stable
 			 */
-			image_free_buffers(ima);
+			BLI_image_free_buffers(ima);
 #endif
 
 			ima->ok = 1;
@@ -2311,14 +2277,14 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
 				if (pf) {
 					freePackedFile(ima->packedfile);
 					ima->packedfile = pf;
-					image_free_buffers(ima);
+					BLI_image_free_buffers(ima);
 				}
 				else {
 					printf("ERROR: Image not available. Keeping packed image\n");
 				}
 			}
 			else
-				image_free_buffers(ima);
+				BLI_image_free_buffers(ima);
 
 			if (iuser)
 				iuser->ok = 1;
@@ -2336,7 +2302,7 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
 			}
 			break;
 		case IMA_SIGNAL_COLORMANAGE:
-			image_free_buffers(ima);
+			BLI_image_free_buffers(ima);
 
 			ima->ok = 1;
 
@@ -2474,7 +2440,7 @@ static void image_initialize_after_load(Image *ima, ImBuf *ibuf)
 		else de_interlace_ng(ibuf);
 	}
 	/* timer */
-	ima->lastused = clock() / CLOCKS_PER_SEC;
+	BKE_image_tag_time(ima);
 
 	ima->ok = IMA_OK_LOADED;
 
@@ -2656,7 +2622,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
 	int assign = 0, flag;
 
 	/* always ensure clean ima */
-	image_free_buffers(ima);
+	BLI_image_free_buffers(ima);
 
 	/* is there a PackedFile with this image ? */
 	if (ima->packedfile) {
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index d238865..6df5fd8 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -7642,8 +7642,6 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
 		}
 	}
 
-	free_old_images();
-
 	ED_view3d_clear_mats_rv3d(rv3d);
 }
 
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 1175e67..219d77a 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -2727,6 +2727,10 @@ static void view3d_draw_objects(
 		v3d->zbuf = false;
 		glDisable(GL_DEPTH_TEST);
 	}
+
+	if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
+		GPU_free_images_old();
+	}
 }
 
 static void view3d_main_area_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
index ee1eabc..bdd70a4 100644
--- a/source/blender/gpu/GPU_draw.h
+++ b/source/blender/gpu/GPU_draw.h
@@ -134,6 +134,7 @@ bool GPU_upload_dxt_texture(struct ImBuf *ibuf);
 void GPU_free_image(struct Image *ima);
 void GPU_free_images(void);
 void GPU_free_images_anim(void);
+void GPU_free_images_old(void);
 
 /* smoke drawing functions */
 void GPU_free_smoke(struct SmokeModifierData *smd);
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 1845de1..6d142ad 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -76,6 +76,8 @@
 #include "GPU_extensions.h"
 #include "GPU_material.h"
 
+#include "PIL_time.h"
+
 #include "smoke_API.h"
 
 extern Material defmaterial; /* from material.c */
@@ -1311,6 +1313,45 @@ void GPU_free_images_anim(void)
 				GPU_free_image(ima);
 }
 
+
+void GPU_free_images_old(void)
+{
+	Image *ima;
+	static int lasttime = 0;
+	int ctime = (int)PIL_check_seconds_timer();
+
+	/*
+	 * Run garbage collector once for every collecting period of time
+	 * if textimeout is 0, that's the option to NOT run the collector
+	 */
+	if (U.textimeout == 0 || ctime % U.texcollectrate || ctime == lasttime)
+		return;
+
+	/* of course not! */
+	if (G.is_rendering)
+		return;
+
+	lasttime = ctime;
+
+	ima = G.main->image.first;
+	while (ima) {
+		if ((ima->flag & IMA_NOCOLLECT) == 0 && ctime - ima->lastused > U.textimeout) {
+			/* If it's in GL memory, deallocate and set time tag to current time
+			 * This gives textures a "second chance" to be used before dying. */
+			if (ima->bindcode || ima->repbind) {
+				GPU_free_image(ima);
+				ima->lastused = ctime;
+			}
+			/* Otherwise, just kill the buffers */
+			else {
+				BLI_image_free_buffers(ima);
+			}
+		}
+		ima = ima->id.next;
+	}
+}
+
+
 /* OpenGL Materials */
 
 #define FIXEDMAT	8
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index 597f93a..253f8a1 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -1132,7 +1132,9 @@ static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int o
 			case TEX_IMAGE:
 				if (osatex) retval = imagewraposa(tex, tex->ima, NULL, texvec, dxt, dyt, texres, pool);
 				else        retval = imagewrap(tex, tex->ima, NULL, texvec, texres, pool);
-				BKE_image_tag_time(tex->ima); /* tag image as having being used */
+				if (tex->ima) {
+					BKE_image_tag_time(tex->ima);
+				}
 				break;
 			case TEX_ENVMAP:
 				retval = envmaptex(tex, texvec, dxt, dyt, osatex, texres, pool);




More information about the Bf-blender-cvs mailing list