Cycles: Fix missing viewport updates after recent changes
authorSergey Sharybin <sergey.vfx@gmail.com>
Thu, 16 May 2019 15:19:05 +0000 (17:19 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 16 May 2019 15:24:16 +0000 (17:24 +0200)
We can not access ensured-to-be-evaluated dependency graph from the
render API: some of it is running from within evaluation which makes
it possible for engines to access list of evaluated IDs.

Solved by passing dependency graph to viewport functions, similar to
the final render functions.

doc/python_api/examples/bpy.types.RenderEngine.py
intern/cycles/blender/addon/__init__.py
source/blender/draw/engines/external/external_engine.c
source/blender/editors/render/render_update.c
source/blender/makesrna/intern/rna_render.c
source/blender/render/extern/include/RE_engine.h

index 6014b4f1d535acc9b4e21b704d623dce19e6ce7f..cfb32433248d05799c0f3618a9aadbc3ac49c6a1 100644 (file)
@@ -55,10 +55,9 @@ class CustomRenderEngine(bpy.types.RenderEngine):
     # whenever the scene or 3D viewport changes. This method is where data
     # should be read from Blender in the same thread. Typically a render
     # thread will be started to do the work while keeping Blender responsive.
-    def view_update(self, context):
+    def view_update(self, context, depsgraph):
         region = context.region
         view3d = context.space_data
-        depsgraph = context.depsgraph
         scene = depsgraph.scene
 
         # Get viewport dimensions
@@ -93,9 +92,8 @@ class CustomRenderEngine(bpy.types.RenderEngine):
     # with OpenGL, and not perform other expensive work.
     # Blender will draw overlays for selection and editing on top of the
     # rendered image automatically.
-    def view_draw(self, context):
+    def view_draw(self, context, depsgraph):
         region = context.region
-        depsgraph = context.depsgraph
         scene = depsgraph.scene
 
         # Get viewport dimensions
index a8e7428a50ff7b8bbba4dc3ee712bf2d868b2600..776a73dabd831548910e2f63ce4553cabb5abd6c 100644 (file)
@@ -87,8 +87,7 @@ class CyclesRender(bpy.types.RenderEngine):
         engine.bake(self, depsgraph, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result)
 
     # viewport render
-    def view_update(self, context):
-        depsgraph = context.evaluated_depsgraph_get()
+    def view_update(self, context, depsgraph):
         if not self.session:
             engine.create(self, context.blend_data,
                           context.region, context.space_data, context.region_data)
@@ -96,8 +95,7 @@ class CyclesRender(bpy.types.RenderEngine):
         engine.reset(self, context.blend_data, depsgraph)
         engine.sync(self, depsgraph, context.blend_data)
 
-    def view_draw(self, context):
-        depsgraph = context.evaluated_depsgraph_get()
+    def view_draw(self, context, depsgraph):
         engine.draw(self, depsgraph, context.region, context.space_data, context.region_data)
 
     def update_script_node(self, node):
index 643f51facd48cdc5ef71bffb8711e5cae5b7be2d..1223e31b891e61abd363fefffb531dda6141547c 100644 (file)
@@ -221,7 +221,7 @@ static void external_draw_scene_do(void *vedata)
     RenderEngine *engine = RE_engine_create_ex(engine_type, true);
     engine->tile_x = scene->r.tilex;
     engine->tile_y = scene->r.tiley;
-    engine_type->view_update(engine, draw_ctx->evil_C);
+    engine_type->view_update(engine, draw_ctx->evil_C, draw_ctx->depsgraph);
     rv3d->render_engine = engine;
   }
 
@@ -231,7 +231,7 @@ static void external_draw_scene_do(void *vedata)
 
   /* Render result draw. */
   type = rv3d->render_engine->type;
-  type->view_draw(rv3d->render_engine, draw_ctx->evil_C);
+  type->view_draw(rv3d->render_engine, draw_ctx->evil_C, draw_ctx->depsgraph);
 
   GPU_matrix_pop_projection();
 
index 55353039b24c88c953b0595dc833d197ec7e1329..64869b717462c3e659ff8d040a6341261ca521dd 100644 (file)
@@ -132,7 +132,10 @@ void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, int update
           CTX_wm_region_set(C, ar);
 
           engine->flag &= ~RE_ENGINE_DO_UPDATE;
-          engine->type->view_update(engine, C);
+          /* NOTE: Important to pass non-updated depsgraph, This is because this function is called
+           * from inside dependency graph evaluation. Additionally, if we pass fully evaluated one
+           * we will loose updates stored in the graph. */
+          engine->type->view_update(engine, C, CTX_data_depsgraph(C));
         }
         else {
           RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
index 81ec785748731085cb6a5c4d1eb1791a5528640a..2dc873ca17dbafb4ecd2c2c549806e17e208059b 100644 (file)
@@ -206,7 +206,9 @@ static void engine_bake(RenderEngine *engine,
   RNA_parameter_list_free(&list);
 }
 
-static void engine_view_update(RenderEngine *engine, const struct bContext *context)
+static void engine_view_update(RenderEngine *engine,
+                               const struct bContext *context,
+                               Depsgraph *depsgraph)
 {
   extern FunctionRNA rna_RenderEngine_view_update_func;
   PointerRNA ptr;
@@ -218,12 +220,15 @@ static void engine_view_update(RenderEngine *engine, const struct bContext *cont
 
   RNA_parameter_list_create(&list, &ptr, func);
   RNA_parameter_set_lookup(&list, "context", &context);
+  RNA_parameter_set_lookup(&list, "depsgraph", &depsgraph);
   engine->type->ext.call(NULL, &ptr, func, &list);
 
   RNA_parameter_list_free(&list);
 }
 
-static void engine_view_draw(RenderEngine *engine, const struct bContext *context)
+static void engine_view_draw(RenderEngine *engine,
+                             const struct bContext *context,
+                             Depsgraph *depsgraph)
 {
   extern FunctionRNA rna_RenderEngine_view_draw_func;
   PointerRNA ptr;
@@ -235,6 +240,7 @@ static void engine_view_draw(RenderEngine *engine, const struct bContext *contex
 
   RNA_parameter_list_create(&list, &ptr, func);
   RNA_parameter_set_lookup(&list, "context", &context);
+  RNA_parameter_set_lookup(&list, "depsgraph", &depsgraph);
   engine->type->ext.call(NULL, &ptr, func, &list);
 
   RNA_parameter_list_free(&list);
@@ -554,12 +560,18 @@ static void rna_def_render_engine(BlenderRNA *brna)
   func = RNA_def_function(srna, "view_update", NULL);
   RNA_def_function_ui_description(func, "Update on data changes for viewport render");
   RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
-  RNA_def_pointer(func, "context", "Context", "", "");
+  parm = RNA_def_pointer(func, "context", "Context", "", "");
+  RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+  parm = RNA_def_pointer(func, "depsgraph", "Depsgraph", "", "");
+  RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
 
   func = RNA_def_function(srna, "view_draw", NULL);
   RNA_def_function_ui_description(func, "Draw viewport render");
   RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
-  RNA_def_pointer(func, "context", "Context", "", "");
+  parm = RNA_def_pointer(func, "context", "Context", "", "");
+  RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+  parm = RNA_def_pointer(func, "depsgraph", "Depsgraph", "", "");
+  RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
 
   /* shader script callbacks */
   func = RNA_def_function(srna, "update_script_node", NULL);
index 1092ab553e9df96291569f27b71ec64f0c3b1e10..4f51f9874f81ff38fc795da58af0454b34b5db8c 100644 (file)
@@ -93,8 +93,12 @@ typedef struct RenderEngineType {
                const int depth,
                void *result);
 
-  void (*view_update)(struct RenderEngine *engine, const struct bContext *context);
-  void (*view_draw)(struct RenderEngine *engine, const struct bContext *context);
+  void (*view_update)(struct RenderEngine *engine,
+                      const struct bContext *context,
+                      struct Depsgraph *depsgraph);
+  void (*view_draw)(struct RenderEngine *engine,
+                    const struct bContext *context,
+                    struct Depsgraph *depsgraph);
 
   void (*update_script_node)(struct RenderEngine *engine,
                              struct bNodeTree *ntree,