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.
This commit is contained in:
Sergey Sharybin 2012-11-13 11:00:46 +00:00
parent 741e167f83
commit 590ed4feb1
3 changed files with 22 additions and 8 deletions

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

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

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