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.
This commit is contained in:
Campbell Barton 2014-05-22 11:58:07 +10:00
parent 90db85a263
commit 049b6cfa6d
7 changed files with 66 additions and 53 deletions

View File

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

View File

@ -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) {

View File

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

View File

@ -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])

View File

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

View File

@ -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

View File

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