diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2012-11-13 15:00:46 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2012-11-13 15:00:46 +0400 |
commit | 590ed4feb1bfe2c5d0ada6f66e05123d689d192a (patch) | |
tree | a1ff3f50dd786c25e4c800600b2e218369b2ee0a | |
parent | 741e167f83cd480fd0e0fb69aba13e543787a128 (diff) |
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.
-rw-r--r-- | source/blender/render/extern/include/RE_engine.h | 1 | ||||
-rw-r--r-- | source/blender/render/intern/source/external_engine.c | 24 | ||||
-rw-r--r-- | source/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; } } |