[Bf-blender-cvs] [a68ceb0] master: Option to lock the interface while rendering

Sergey Sharybin noreply at git.blender.org
Wed Jan 29 11:10:35 CET 2014


Commit: a68ceb0af8ecc4c5df7a27b52814fcf0246ad36a
Author: Sergey Sharybin
Date:   Wed Jan 29 16:07:14 2014 +0600
https://developer.blender.org/rBa68ceb0af8ecc4c5df7a27b52814fcf0246ad36a

Option to lock the interface while rendering

Added function called WM_set_locked_interface which does
two things:

- Prevents event queue from being handled, so no operators
  (see below) or values are even possible to run or change.
  This prevents any kind of "destructive" action performed
  from user while rendering.

- Locks interface refresh for regions which does have lock
  set to truth in their template. Currently it's just a 3D
  viewport, but in the future more regions could be considered
  unsafe, or we could want to lock different parts of
  interface when doing different jobs.

  This is needed because 3D viewport could be using or changing
  the same data as renderer currently uses, leading to threading
  conflict.

  Notifiers are still allowed to handle, so render progress is
  seen on the screen, but would need to doublecheck on this, in
  terms some notifiers could be changing the data.

  For now interface locking happens for render job only in case
  "Lock Interface" checkbox is enabled.

  Other tools like backing would also benefit of this option.

  It is possible to mark operator as safe to be used in locked
  interface mode by adding OPTYPE_ALLOW_LOCKED bit to operator
  template flags.

  This bit is completely handled by wm_evem_system, not
  with operator run routines, so it's still possible to
  run operators from drivers and handlers.

  Currently allowed image editor navigation and zooming.

Reviewers: brecht, campbellbarton

Reviewed By: campbellbarton

Differential Revision: https://developer.blender.org/D142

===================================================================

M	release/scripts/startup/bl_ui/properties_render.py
M	source/blender/blenloader/intern/readfile.c
M	source/blender/editors/render/render_internal.c
M	source/blender/editors/space_image/image_ops.c
M	source/blender/makesdna/DNA_scene_types.h
M	source/blender/makesdna/DNA_windowmanager_types.h
M	source/blender/makesrna/intern/rna_scene.c
M	source/blender/render/extern/include/RE_pipeline.h
M	source/blender/render/intern/source/pipeline.c
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/WM_types.h
M	source/blender/windowmanager/intern/wm_event_system.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index 41516a7..f126153 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -71,6 +71,8 @@ class RENDER_PT_render(RenderButtonsPanel, Panel):
 
         layout.prop(rd, "display_mode", text="Display")
 
+        layout.prop(rd, "use_lock_interface")
+
 
 class RENDER_PT_dimensions(RenderButtonsPanel, Panel):
     bl_label = "Dimensions"
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 913bdfd..29de575 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -5554,6 +5554,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
 	wm->winactive = NULL;
 	wm->initialized = 0;
 	wm->op_undo_depth = 0;
+	wm->is_interface_locked = 0;
 }
 
 static void lib_link_windowmanager(FileData *fd, Main *main)
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 4ff4150..e57474a 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -58,6 +58,7 @@
 #include "BKE_main.h"
 #include "BKE_node.h"
 #include "BKE_multires.h"
+#include "BKE_object.h"
 #include "BKE_paint.h"
 #include "BKE_report.h"
 #include "BKE_sequencer.h"
@@ -116,6 +117,7 @@ typedef struct RenderJob {
 	ScrArea *sa;
 	ColorManagedViewSettings view_settings;
 	ColorManagedDisplaySettings display_settings;
+	bool interface_locked;
 } RenderJob;
 
 /* called inside thread! */
@@ -662,6 +664,29 @@ static void render_endjob(void *rjv)
 
 		BKE_image_release_ibuf(ima, ibuf, lock);
 	}
+
+	/* Finally unlock the user interface (if it was locked). */
+	if (rj->interface_locked) {
+		Scene *scene;
+
+		/* Interface was locked, so window manager couldn't have been changed
+		 * and using one from Global will unlock exactly the same manager as
+		 * was locked before running the job.
+		 */
+		WM_set_locked_interface(G.main->wm.first, false);
+
+		/* We've freed all the derived caches before rendering, which is
+		 * effectively the same as if we re-loaded the file.
+		 *
+		 * So let's not try being smart here and just reset all updated
+		 * scene layers and use generic DAG_on_visible_update.
+		 */
+		for (scene = G.main->scene.first; scene; scene = scene->id.next) {
+			scene->lay_updated = 0;
+		}
+
+		DAG_on_visible_update(G.main, false);
+	}
 }
 
 /* called by render, check job 'stop' value or the global */
@@ -687,10 +712,14 @@ static int render_break(void *UNUSED(rjv))
 
 /* runs in thread, no cursor setting here works. careful with notifiers too (malloc conflicts) */
 /* maybe need a way to get job send notifer? */
-static void render_drawlock(void *UNUSED(rjv), int lock)
+static void render_drawlock(void *rjv, int lock)
 {
-	BKE_spacedata_draw_locks(lock);
-	
+	RenderJob *rj = rjv;
+
+	/* If interface is locked, renderer callback shall do nothing. */
+	if (!rj->interface_locked) {
+		BKE_spacedata_draw_locks(lock);
+	}
 }
 
 /* catch esc */
@@ -721,6 +750,36 @@ static void screen_render_cancel(bContext *C, wmOperator *op)
 	WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_RENDER);
 }
 
+static void clean_viewport_memory(Main *bmain, Scene *scene, int renderlay)
+{
+	Object *object;
+	Scene *sce_iter;
+	Base *base;
+
+	for (object = bmain->object.first; object; object = object->id.next) {
+		object->id.flag |= LIB_DOIT;
+	}
+
+	for (SETLOOPER(scene, sce_iter, base)) {
+		if ((base->lay & renderlay) == 0) {
+			continue;
+		}
+
+		if (RE_allow_render_generic_object(base->object)) {
+			base->object->id.flag &= ~LIB_DOIT;
+		}
+	}
+
+	for (object = bmain->object.first; object; object = object->id.next) {
+		if ((object->id.flag & LIB_DOIT) == 0) {
+			continue;
+		}
+		object->id.flag &= ~LIB_DOIT;
+
+		BKE_object_free_derived_caches(object);
+	}
+}
+
 /* using context, starts job */
 static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *event)
 {
@@ -832,6 +891,26 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
 			rj->lay_override |= v3d->localvd->lay;
 	}
 
+	/* Lock the user interface depending on render settings. */
+	if (scene->r.use_lock_interface) {
+		int renderlay = rj->lay_override ? rj->lay_override : scene->lay;
+
+		WM_set_locked_interface(CTX_wm_manager(C), true);
+
+		/* Set flag interface need to be unlocked.
+		 *
+		 * This is so because we don't have copy of render settings
+		 * accessible from render job and copy is needed in case
+		 * of non-locked rendering, so we wouldn't try to unlock
+		 * anything if option was initially unset but then was
+		 * enabled during rendering.
+		 */
+		rj->interface_locked = true;
+
+		/* Clean memory used by viewport? */
+		clean_viewport_memory(rj->main, scene, renderlay);
+	}
+
 	/* setup job */
 	if (RE_seq_render_active(scene, &scene->r)) name = "Sequence Render";
 	else name = "Render";
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 38d1992..120e6f5 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -363,7 +363,7 @@ void IMAGE_OT_view_pan(wmOperatorType *ot)
 	ot->poll = space_image_main_area_poll;
 
 	/* flags */
-	ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER;
+	ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER | OPTYPE_LOCK_BYPASS;
 	
 	/* properties */
 	RNA_def_float_vector(ot->srna, "offset", 2, NULL, -FLT_MAX, FLT_MAX,
@@ -577,7 +577,7 @@ void IMAGE_OT_view_zoom(wmOperatorType *ot)
 	ot->poll = space_image_main_area_poll;
 
 	/* flags */
-	ot->flag = OPTYPE_BLOCKING;
+	ot->flag = OPTYPE_BLOCKING | OPTYPE_LOCK_BYPASS;
 	
 	/* properties */
 	RNA_def_float(ot->srna, "factor", 0.0f, -FLT_MAX, FLT_MAX,
@@ -640,6 +640,9 @@ void IMAGE_OT_view_ndof(wmOperatorType *ot)
 	
 	/* api callbacks */
 	ot->invoke = image_view_ndof_invoke;
+
+	/* flags */
+	ot->flag = OPTYPE_LOCK_BYPASS;
 }
 
 /********************** view all operator *********************/
@@ -817,6 +820,9 @@ void IMAGE_OT_view_zoom_in(wmOperatorType *ot)
 	ot->exec = image_view_zoom_in_exec;
 	ot->poll = space_image_main_area_poll;
 
+	/* flags */
+	ot->flag = OPTYPE_LOCK_BYPASS;
+
 	/* properties */
 	RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX, "Location", "Cursor location in screen coordinates", -10.0f, 10.0f);
 }
@@ -859,6 +865,9 @@ void IMAGE_OT_view_zoom_out(wmOperatorType *ot)
 	ot->exec = image_view_zoom_out_exec;
 	ot->poll = space_image_main_area_poll;
 
+	/* flags */
+	ot->flag = OPTYPE_LOCK_BYPASS;
+
 	/* properties */
 	RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX, "Location", "Cursor location in screen coordinates", -10.0f, 10.0f);
 }
@@ -901,6 +910,9 @@ void IMAGE_OT_view_zoom_ratio(wmOperatorType *ot)
 	ot->exec = image_view_zoom_ratio_exec;
 	ot->poll = space_image_main_area_poll;
 
+	/* flags */
+	ot->flag = OPTYPE_LOCK_BYPASS;
+
 	/* properties */
 	RNA_def_float(ot->srna, "ratio", 0.0f, -FLT_MAX, FLT_MAX,
 	              "Ratio", "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out", -FLT_MAX, FLT_MAX);
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 076dc9c..177b687 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -432,7 +432,8 @@ typedef struct RenderData {
 	 * Render to image editor, fullscreen or to new window.
 	 */
 	short displaymode;
-	short pad7;
+	char use_lock_interface;
+	char pad7;
 
 	/**
 	 * Flags for render settings. Use bit-masking to access the settings.
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index ff43cc3..a17e416 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -154,6 +154,9 @@ typedef struct wmWindowManager {
 
 	ListBase timers;                  /* active timers */
 	struct wmTimer *autosavetimer;    /* timer for auto save */
+
+	char is_interface_locked;		/* indicates whether interface is locked for user interaction */
+	char par[7];
 } wmWindowManager;
 
 /* wmWindowManager.initialized */
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 4a54460..19d90ab 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -4539,6 +4539,11 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
 	RNA_def_property_ui_text(prop, "Display", "Select where rendered images will be displayed");
 	RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
 
+	prop = RNA_def_property(srna, "use_lock_interface", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "use_lock_interface", 1);
+	RNA_def_property_ui_text(prop, "Lock Interface", "Lock interface during rendering in favor of giving more memory to the renderer");
+	RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
 	prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
 	RNA_def_property_string_sdna(prop, NULL, "pic");
 	RNA_def_property_ui_text(prop, "Output Path",
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 32c0a1d..bc07f0c 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -290,5 +290,7 @@ struct Scene *RE_GetScene(struct Render *re);
 
 int RE_is_rendering_allowed(struct Scene *scene, struct Object *camera_override, struct ReportList *reports);
 
+bool RE_allow_render_generic_object(struct Object *ob);
+
 #endif /* __RE_PIPELINE_H__ */
 
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index ec2644e..39bc571 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -1602,6 +1602,18 @@ static bool rlayer_node_uses_alpha

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list