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);

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to