diff --git a/source/blender/blenkernel/BKE_sequence.h b/source/blender/blenkernel/BKE_sequence.h index 65a3b0216fe..7162fa7b9dd 100644 --- a/source/blender/blenkernel/BKE_sequence.h +++ b/source/blender/blenkernel/BKE_sequence.h @@ -181,5 +181,5 @@ int check_single_seq(struct Sequence *seq); void fix_single_seq(struct Sequence *seq); int seq_test_overlap(struct ListBase * seqbasep, struct Sequence *test); int shuffle_seq(struct ListBase * seqbasep, struct Sequence *test); -void free_imbuf_seq(struct ListBase * seqbasep); +void free_imbuf_seq(struct ListBase * seqbasep, int check_mem_usage); diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 656a292da15..a2a7457545d 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -27,7 +27,7 @@ FILE(GLOB SRC intern/*.c) SET(INC - . ../../../intern/guardedalloc ../editors/include ../blenlib ../makesdna + . ../../../intern/guardedalloc ../../../intern/memutil ../editors/include ../blenlib ../makesdna ../render/extern/include ../../../intern/decimation/extern ../imbuf ../avi ../../../intern/elbeem/extern ../../../intern/opennl/extern ../../../intern/iksolver/extern ../blenloader ../quicktime diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index 7016d992f02..5b1c7b163ba 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -3,7 +3,7 @@ Import ('env') sources = env.Glob('intern/*.c') -incs = '. #/intern/guardedalloc ../editors/include ../blenlib ../makesdna' +incs = '. #/intern/guardedalloc #/intern/memutil ../editors/include ../blenlib ../makesdna' incs += ' ../render/extern/include #/intern/decimation/extern ../makesrna' incs += ' ../imbuf ../avi #/intern/elbeem/extern ../nodes' incs += ' #/intern/iksolver/extern ../blenloader' diff --git a/source/blender/blenkernel/intern/Makefile b/source/blender/blenkernel/intern/Makefile index fe7187200aa..fb75d01499e 100644 --- a/source/blender/blenkernel/intern/Makefile +++ b/source/blender/blenkernel/intern/Makefile @@ -41,6 +41,7 @@ CPPFLAGS += -I$(OPENGL_HEADERS) CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include +CPPFLAGS += -I../../../intern/memutil # Reference to the types in makesdna and imbuf CPPFLAGS += -I../../makesdna CPPFLAGS += -I../../makesrna diff --git a/source/blender/blenkernel/intern/sequence.c b/source/blender/blenkernel/intern/sequence.c index 4832086ac88..3b675a87e59 100644 --- a/source/blender/blenkernel/intern/sequence.c +++ b/source/blender/blenkernel/intern/sequence.c @@ -32,6 +32,7 @@ #include #include "MEM_guardedalloc.h" +#include "MEM_CacheLimiterC-Api.h" #include "DNA_listBase.h" #include "DNA_sequence_types.h" @@ -122,7 +123,7 @@ void new_tstripdata(Sequence *seq) /* free */ -static void free_proxy_seq(Sequence *seq) +void free_proxy_seq(Sequence *seq) { if (seq->strip && seq->strip->proxy && seq->strip->proxy->anim) { IMB_free_anim(seq->strip->proxy->anim); @@ -3039,11 +3040,36 @@ void free_imbuf_seq_except(Scene *scene, int cfra) SEQ_END } -void free_imbuf_seq(ListBase * seqbase) +void free_imbuf_seq(ListBase * seqbase, int check_mem_usage) { Sequence *seq; TStripElem *se; int a; + + if (check_mem_usage) { + /* Let the cache limitor take care of this (schlaile) */ + /* While render let's keep all memory available for render + (ton) + At least if free memory is tight... + This can make a big difference in encoding speed + (it is around 4 times(!) faster, if we do not waste time + on freeing _all_ buffers every time on long timelines...) + (schlaile) + */ + + uintptr_t mem_in_use; + uintptr_t mmap_in_use; + uintptr_t max; + + mem_in_use= MEM_get_memory_in_use(); + mmap_in_use= MEM_get_mapped_memory_in_use(); + max = MEM_CacheLimiter_get_maximum(); + + if (max == 0 || mem_in_use + mmap_in_use <= max) { + return; + } + } + for(seq= seqbase->first; seq; seq= seq->next) { if(seq->strip) { @@ -3076,7 +3102,11 @@ void free_imbuf_seq(ListBase * seqbase) } } if(seq->type==SEQ_META) { - free_imbuf_seq(&seq->seqbase); + free_imbuf_seq(&seq->seqbase, FALSE); + } + if(seq->type==SEQ_SCENE) { + /* FIXME: recurs downwards, + but do recurs protection somehow! */ } } @@ -3174,88 +3204,6 @@ void free_imbuf_seq_with_ipo(Scene *scene, struct Ipo *ipo) SEQ_END } -#if 0 -/* bad levell call... */ -void do_render_seq(RenderResult *rr, int cfra) -{ - static int recurs_depth = 0 - ImBuf *ibuf; - - recurs_depth++; - - ibuf= give_ibuf_seq(rr->rectx, rr->recty, cfra, 0, 100.0); - - recurs_depth--; - - if(ibuf) { - if(ibuf->rect_float) { - if (!rr->rectf) - rr->rectf= MEM_mallocN(4*sizeof(float)*rr->rectx*rr->recty, "render_seq rectf"); - - memcpy(rr->rectf, ibuf->rect_float, 4*sizeof(float)*rr->rectx*rr->recty); - - /* TSK! Since sequence render doesn't free the *rr render result, the old rect32 - can hang around when sequence render has rendered a 32 bits one before */ - if(rr->rect32) { - MEM_freeN(rr->rect32); - rr->rect32= NULL; - } - } - else if(ibuf->rect) { - if (!rr->rect32) - rr->rect32= MEM_mallocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect"); - - memcpy(rr->rect32, ibuf->rect, 4*rr->rectx*rr->recty); - - /* if (ibuf->zbuf) { */ - /* if (R.rectz) freeN(R.rectz); */ - /* R.rectz = BLI_dupallocN(ibuf->zbuf); */ - /* } */ - } - - /* Let the cache limitor take care of this (schlaile) */ - /* While render let's keep all memory available for render - (ton) - At least if free memory is tight... - This can make a big difference in encoding speed - (it is around 4 times(!) faster, if we do not waste time - on freeing _all_ buffers every time on long timelines...) - (schlaile) - */ - if (recurs_depth == 0) { /* with nested scenes, only free on toplevel... */ - uintptr_t mem_in_use; - uintptr_t mmap_in_use; - uintptr_t max; - - mem_in_use= MEM_get_memory_in_use(); - mmap_in_use= MEM_get_mapped_memory_in_use(); - max = MEM_CacheLimiter_get_maximum(); - - if (max != 0 && mem_in_use + mmap_in_use > max) { - fprintf(stderr, "Memory in use > maximum memory\n"); - fprintf(stderr, "Cleaning up, please wait...\n" - "If this happens very often,\n" - "consider " - "raising the memcache limit in the " - "user preferences.\n"); - free_imbuf_seq(); - } - free_proxy_seq(seq); - } - } - else { - /* render result is delivered empty in most cases, nevertheless we handle all cases */ - if (rr->rectf) - memset(rr->rectf, 0, 4*sizeof(float)*rr->rectx*rr->recty); - else if (rr->rect32) - memset(rr->rect32, 0, 4*rr->rectx*rr->recty); - else - rr->rect32= MEM_callocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect"); - } -} - -#endif - /* seq funcs's for transforming internally notice the difference between start/end and left/right. diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 5c82ff08094..036c0769c1e 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -1694,7 +1694,7 @@ static int sequencer_refresh_all_exec(bContext *C, wmOperator *op) if(ed==NULL) return OPERATOR_CANCELLED; - free_imbuf_seq(&ed->seqbase); + free_imbuf_seq(&ed->seqbase, FALSE); ED_area_tag_redraw(CTX_wm_area(C)); diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 83b55559a9a..14df6b8ec9f 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -48,6 +48,7 @@ #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */ +#include "BKE_sequence.h" #include "BKE_pointcache.h" #include "MEM_guardedalloc.h" @@ -2303,6 +2304,63 @@ static void renderresult_stampinfo(Scene *scene) BKE_stamp_buf(scene, (unsigned char *)rres.rect32, rres.rectf, rres.rectx, rres.recty, 4); } +static void do_render_seq(Render * re) +{ + static int recurs_depth = 0; + struct ImBuf *ibuf; + RenderResult *rr = re->result; + int cfra = re->r.cfra; + + recurs_depth++; + + ibuf= give_ibuf_seq(re->scene, rr->rectx, rr->recty, cfra, 0, 100.0); + + recurs_depth--; + + if(ibuf) { + if(ibuf->rect_float) { + if (!rr->rectf) + rr->rectf= MEM_mallocN(4*sizeof(float)*rr->rectx*rr->recty, "render_seq rectf"); + + memcpy(rr->rectf, ibuf->rect_float, 4*sizeof(float)*rr->rectx*rr->recty); + + /* TSK! Since sequence render doesn't free the *rr render result, the old rect32 + can hang around when sequence render has rendered a 32 bits one before */ + if(rr->rect32) { + MEM_freeN(rr->rect32); + rr->rect32= NULL; + } + } + else if(ibuf->rect) { + if (!rr->rect32) + rr->rect32= MEM_mallocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect"); + + memcpy(rr->rect32, ibuf->rect, 4*rr->rectx*rr->recty); + + /* if (ibuf->zbuf) { */ + /* if (R.rectz) freeN(R.rectz); */ + /* R.rectz = BLI_dupallocN(ibuf->zbuf); */ + /* } */ + } + + if (recurs_depth == 0) { /* with nested scenes, only free on toplevel... */ + Editing * ed = re->scene->ed; + if (ed) { + free_imbuf_seq(&ed->seqbase, TRUE); + } + } + } + else { + /* render result is delivered empty in most cases, nevertheless we handle all cases */ + if (rr->rectf) + memset(rr->rectf, 0, 4*sizeof(float)*rr->rectx*rr->recty); + else if (rr->rect32) + memset(rr->rect32, 0, 4*rr->rectx*rr->recty); + else + rr->rect32= MEM_callocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect"); + } +} + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* main loop: doing sequence + fields + blur + 3d render + compositing */ @@ -2316,7 +2374,7 @@ static void do_render_all_options(Render *re) if((re->r.scemode & R_DOSEQ) && re->scene->ed && re->scene->ed->seqbase.first) { /* note: do_render_seq() frees rect32 when sequencer returns float images */ if(!re->test_break(re->tbh)) - {}; //XXX do_render_seq(re->result, re->r.cfra); + do_render_seq(re); re->stats_draw(re->sdh, &re->i); re->display_draw(re->ddh, re->result, NULL);