From 590ed4feb1bfe2c5d0ada6f66e05123d689d192a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 13 Nov 2012 11:00:46 +0000 Subject: [PATCH] Render Engines: fix crash when changing render engine during rendering Crash would have been happen when changing render ending at the same time rendering happens. It could be final Cycles render or even preview LUX render. --- .../blender/render/extern/include/RE_engine.h | 1 + .../render/intern/source/external_engine.c | 24 +++++++++++++------ .../blender/render/intern/source/pipeline.c | 5 +++- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h index 1331c287d7c..d2ffc3a0e26 100644 --- a/source/blender/render/extern/include/RE_engine.h +++ b/source/blender/render/extern/include/RE_engine.h @@ -60,6 +60,7 @@ struct Scene; #define RE_ENGINE_PREVIEW 2 #define RE_ENGINE_DO_DRAW 4 #define RE_ENGINE_DO_UPDATE 8 +#define RE_ENGINE_RENDERING 16 extern ListBase R_engines; diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 8bdb805ada2..9053bc84bbc 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -316,6 +316,7 @@ int RE_engine_render(Render *re, int do_all) { RenderEngineType *type = RE_engines_find(re->r.engine); RenderEngine *engine; + int persistent_data = re->r.mode & R_PERSISTENT_DATA; /* verify if we can render */ if (!type->render) @@ -349,11 +350,17 @@ int RE_engine_render(Render *re, int do_all) re->i.totface = re->i.totvert = re->i.totstrand = re->i.totlamp = re->i.tothalo = 0; /* render */ - if (!re->engine) - re->engine = RE_engine_create(type); - engine = re->engine; + if (!engine) { + engine = RE_engine_create(type); + + if (persistent_data) + re->engine = engine; + } + + engine->flag |= RE_ENGINE_RENDERING; + /* TODO: actually link to a parent which shouldn't happen */ engine->re = re; @@ -382,8 +389,13 @@ int RE_engine_render(Render *re, int do_all) if (type->render) type->render(engine, re->scene); - if (!(re->r.mode & R_PERSISTENT_DATA)) { - RE_engine_free(re->engine); + engine->tile_x = 0; + engine->tile_y = 0; + engine->flag &= ~RE_ENGINE_RENDERING; + + /* re->engine becomes zero if user changed active render engine during render */ + if (!persistent_data || !re->engine) { + RE_engine_free(engine); re->engine = NULL; } @@ -393,8 +405,6 @@ int RE_engine_render(Render *re, int do_all) BLI_rw_mutex_unlock(&re->resultmutex); } - engine->tile_x = 0; - engine->tile_y = 0; freeparts(re); render_result_free_list(&engine->fullresult, engine->fullresult.first); diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 85cafa07759..f2549f04659 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -432,7 +432,10 @@ void RE_FreePersistentData(void) /* render engines can be kept around for quick re-render, this clears all */ for (re = RenderGlobal.renderlist.first; re; re = re->next) { if (re->engine) { - RE_engine_free(re->engine); + /* if engine is currently rendering, just tag it to be freed when render is finished */ + if (!(re->engine->flag & RE_ENGINE_RENDERING)) + RE_engine_free(re->engine); + re->engine = NULL; } }