Avoid race condition copying Scene for off-thread OpenGL image save
authorSergey Sharybin <sergey.vfx@gmail.com>
Wed, 26 Apr 2017 13:11:58 +0000 (15:11 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Wed, 26 Apr 2017 14:00:02 +0000 (16:00 +0200)
source/blender/editors/render/render_opengl.c

index ee21594856fe623a0eead2f77184d37f9f16ad18..1b0ba382284c95b71b34fb79bcfc4bbf7de38e49 100644 (file)
@@ -872,7 +872,7 @@ static bool screen_opengl_render_anim_initialize(bContext *C, wmOperator *op)
 
 typedef struct WriteTaskData {
        RenderResult *rr;
-       int cfra;
+       Scene tmp_scene;
 } WriteTaskData;
 
 static void write_result_func(TaskPool * __restrict pool,
@@ -881,10 +881,10 @@ static void write_result_func(TaskPool * __restrict pool,
 {
        OGLRender *oglrender = (OGLRender *) BLI_task_pool_userdata(pool);
        WriteTaskData *task_data = (WriteTaskData *) task_data_v;
-       Scene *scene = oglrender->scene;
+       Scene *scene = &task_data->tmp_scene;
        RenderResult *rr = task_data->rr;
        const bool is_movie = BKE_imtype_is_movie(scene->r.im_format.imtype);
-       const int cfra = task_data->cfra;
+       const int cfra = scene->r.cfra;
        bool ok;
        /* Don't attempt to write if we've got an error. */
        if (!oglrender->pool_ok) {
@@ -906,13 +906,11 @@ static void write_result_func(TaskPool * __restrict pool,
         * This is because underlying calls do not use r.cfra but use scene
         * for that.
         */
-       Scene tmp_scene = *scene;
-       tmp_scene.r.cfra = cfra;
        if (is_movie) {
                ok = RE_WriteRenderViewsMovie(&reports,
                                              rr,
-                                             &tmp_scene,
-                                             &tmp_scene.r,
+                                             scene,
+                                             &scene->r,
                                              oglrender->mh,
                                              oglrender->movie_ctx_arr,
                                              oglrender->totvideos,
@@ -932,8 +930,8 @@ static void write_result_func(TaskPool * __restrict pool,
                                             true,
                                             NULL);
 
-               BKE_render_result_stamp_info(&tmp_scene, tmp_scene.camera, rr, false);
-               ok = RE_WriteRenderViewsImage(NULL, rr, &tmp_scene, true, name);
+               BKE_render_result_stamp_info(scene, scene->camera, rr, false);
+               ok = RE_WriteRenderViewsImage(NULL, rr, scene, true, name);
                if (!ok) {
                        BKE_reportf(&reports,
                                    RPT_ERROR,
@@ -972,7 +970,7 @@ static bool schedule_write_result(OGLRender *oglrender, RenderResult *rr)
        Scene *scene = oglrender->scene;
        WriteTaskData *task_data = MEM_mallocN(sizeof(WriteTaskData), "write task data");
        task_data->rr = rr;
-       task_data->cfra = scene->r.cfra;
+       task_data->tmp_scene = *scene;
        BLI_mutex_lock(&oglrender->task_mutex);
        oglrender->num_scheduled_frames++;
        if (oglrender->num_scheduled_frames > MAX_SCHEDULED_FRAMES) {