[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [57727] branches/soc-2013-depsgraph_mt: Experimental feature to lock the interface while rendering

Sergey Sharybin sergey.vfx at gmail.com
Tue Jun 25 11:04:43 CEST 2013


Revision: 57727
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=57727
Author:   nazgul
Date:     2013-06-25 09:04:42 +0000 (Tue, 25 Jun 2013)
Log Message:
-----------
Experimental feature 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
  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.

Currently this option would only make rendering thread-safe, but
in the future more benefits are possible to gain from it. Namely,
if we'll make renderer using it's own graph, this option would
allow to free memory used by 3D viewport graph, which would help
keeping memory usage low (or even would allow renderer not to
copy anything in this case).

Initially thought this change will also allow to free DMs used
by viewport, but we couldn't actually do this. This is because
of modifiers which uses other objects (like boolean), They're
in fact using viewport DM. This is bad because of few reasons.

We currently need to have viewport DM when rendering.
And for sure even in background render viewport DMs are being
calculated. This sounds like 2x computing is needed: one is for
viewport DM and one is for RenderDM.

If we'll have local graphs, we'll be able to compute RenderDMs
only and store them in graph. This would require a bit more of
the memory, but would solve current issues with viewport DM
used for modifiers operands while rendering and it should give
quite noticeable speedup.

Other tools like backing would also benefit of this option,
but rather get approval of current way of locking first.

Modified Paths:
--------------
    branches/soc-2013-depsgraph_mt/release/scripts/startup/bl_ui/properties_render.py
    branches/soc-2013-depsgraph_mt/source/blender/blenloader/intern/readfile.c
    branches/soc-2013-depsgraph_mt/source/blender/editors/render/render_internal.c
    branches/soc-2013-depsgraph_mt/source/blender/makesdna/DNA_scene_types.h
    branches/soc-2013-depsgraph_mt/source/blender/makesdna/DNA_windowmanager_types.h
    branches/soc-2013-depsgraph_mt/source/blender/makesrna/intern/rna_scene.c
    branches/soc-2013-depsgraph_mt/source/blender/windowmanager/WM_api.h
    branches/soc-2013-depsgraph_mt/source/blender/windowmanager/intern/wm_event_system.c

Modified: branches/soc-2013-depsgraph_mt/release/scripts/startup/bl_ui/properties_render.py
===================================================================
--- branches/soc-2013-depsgraph_mt/release/scripts/startup/bl_ui/properties_render.py	2013-06-25 07:27:59 UTC (rev 57726)
+++ branches/soc-2013-depsgraph_mt/release/scripts/startup/bl_ui/properties_render.py	2013-06-25 09:04:42 UTC (rev 57727)
@@ -70,6 +70,7 @@
         row.operator("render.play_rendered_anim", text="Play", icon='PLAY')
 
         layout.prop(rd, "display_mode", text="Display")
+        layout.prop(rd, "use_lock_interface")
 
 
 class RENDER_PT_dimensions(RenderButtonsPanel, Panel):

Modified: branches/soc-2013-depsgraph_mt/source/blender/blenloader/intern/readfile.c
===================================================================
--- branches/soc-2013-depsgraph_mt/source/blender/blenloader/intern/readfile.c	2013-06-25 07:27:59 UTC (rev 57726)
+++ branches/soc-2013-depsgraph_mt/source/blender/blenloader/intern/readfile.c	2013-06-25 09:04:42 UTC (rev 57727)
@@ -5514,6 +5514,7 @@
 	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)

Modified: branches/soc-2013-depsgraph_mt/source/blender/editors/render/render_internal.c
===================================================================
--- branches/soc-2013-depsgraph_mt/source/blender/editors/render/render_internal.c	2013-06-25 07:27:59 UTC (rev 57726)
+++ branches/soc-2013-depsgraph_mt/source/blender/editors/render/render_internal.c	2013-06-25 09:04:42 UTC (rev 57727)
@@ -273,6 +273,7 @@
 	short *do_update;
 	float *progress;
 	ReportList *reports;
+	bool interface_locked;
 } RenderJob;
 
 static void render_freejob(void *rjv)
@@ -497,6 +498,15 @@
 
 		BKE_image_release_ibuf(ima, ibuf, lock);
 	}
+
+	/* Finally unlock the user interface (if it was locked). */
+	if (rj->interface_locked) {
+		/* 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);
+	}
 }
 
 /* called by render, check job 'stop' value or the global */
@@ -522,10 +532,14 @@
 
 /* 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 */
@@ -648,6 +662,23 @@
 			rj->lay |= v3d->localvd->lay;
 	}
 
+	/* Lock the user interface depending on render settings. */
+	if (scene->r.use_lock_interface) {
+		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;
+
+		/* TODO(sergey): clean memory used by viewport? */
+	}
+
 	/* setup job */
 	if (RE_seq_render_active(scene, &scene->r)) name = "Sequence Render";
 	else name = "Render";

Modified: branches/soc-2013-depsgraph_mt/source/blender/makesdna/DNA_scene_types.h
===================================================================
--- branches/soc-2013-depsgraph_mt/source/blender/makesdna/DNA_scene_types.h	2013-06-25 07:27:59 UTC (rev 57726)
+++ branches/soc-2013-depsgraph_mt/source/blender/makesdna/DNA_scene_types.h	2013-06-25 09:04:42 UTC (rev 57727)
@@ -428,7 +428,8 @@
 	 * 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.

Modified: branches/soc-2013-depsgraph_mt/source/blender/makesdna/DNA_windowmanager_types.h
===================================================================
--- branches/soc-2013-depsgraph_mt/source/blender/makesdna/DNA_windowmanager_types.h	2013-06-25 07:27:59 UTC (rev 57726)
+++ branches/soc-2013-depsgraph_mt/source/blender/makesdna/DNA_windowmanager_types.h	2013-06-25 09:04:42 UTC (rev 57727)
@@ -151,6 +151,9 @@
 
 	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 */

Modified: branches/soc-2013-depsgraph_mt/source/blender/makesrna/intern/rna_scene.c
===================================================================
--- branches/soc-2013-depsgraph_mt/source/blender/makesrna/intern/rna_scene.c	2013-06-25 07:27:59 UTC (rev 57726)
+++ branches/soc-2013-depsgraph_mt/source/blender/makesrna/intern/rna_scene.c	2013-06-25 09:04:42 UTC (rev 57727)
@@ -4520,7 +4520,12 @@
 	RNA_def_property_enum_items(prop, display_mode_items);
 	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",

Modified: branches/soc-2013-depsgraph_mt/source/blender/windowmanager/WM_api.h
===================================================================
--- branches/soc-2013-depsgraph_mt/source/blender/windowmanager/WM_api.h	2013-06-25 07:27:59 UTC (rev 57726)
+++ branches/soc-2013-depsgraph_mt/source/blender/windowmanager/WM_api.h	2013-06-25 09:04:42 UTC (rev 57727)
@@ -412,6 +412,9 @@
 /* debugging only, convenience function to write on crash */
 int write_crash_blend(void);
 
+			/* Lock the interface for any communication */
+void        WM_set_locked_interface(struct wmWindowManager *wm, bool lock);
+
 #ifdef __cplusplus
 }
 #endif

Modified: branches/soc-2013-depsgraph_mt/source/blender/windowmanager/intern/wm_event_system.c
===================================================================
--- branches/soc-2013-depsgraph_mt/source/blender/windowmanager/intern/wm_event_system.c	2013-06-25 07:27:59 UTC (rev 57726)
+++ branches/soc-2013-depsgraph_mt/source/blender/windowmanager/intern/wm_event_system.c	2013-06-25 09:04:42 UTC (rev 57727)
@@ -2093,6 +2093,21 @@
 	wmWindowManager *wm = CTX_wm_manager(C);
 	wmWindow *win;
 
+	if (wm->is_interface_locked) {
+		/* If we're in locked interaction mode, skip all the events
+		 * from the queue and prevent them from being accumulated.
+		 * This is so no events are applied after interface is unlocked.
+		 */
+		for (win = wm->windows.first; win; win = win->next) {
+			wmEvent *event;
+			while ( (event = win->queue.first) ) {
+				BLI_remlink(&win->queue, event);
+				wm_event_free(event);
+			}
+		}
+		return;
+	}
+
 	/* update key configuration before handling events */
 	WM_keyconfig_update(wm);
 
@@ -3219,3 +3234,24 @@
 	WM_event_print(&event);
 #endif
 }
+
+void WM_set_locked_interface(wmWindowManager *wm, bool lock)
+{
+	/* This will prevent events from being handled while interface is locked
+	 *
+	 * Use a "local" flag for now, because currently no other areas could
+	 * benefit of locked interface anyway (aka using G.is_interface_locked
+	 * wouldn't be useful anywhere outside of window manager, so let's not
+	 * pollute global context with such an information for now).
+	 */
+	wm->is_interface_locked = lock ? 1 : 0;
+
+	/* This will prevent drawing regions which uses non-threadsafe data.
+	 * Currently it'll be just a 3D viewport.
+	 *
+	 * TODO(sergey): Make it different locked states, so different jobs
+	 *               could lock different areas of blender and allow
+	 *               interation with others?
+	 */
+	BKE_spacedata_draw_locks(lock);
+}




More information about the Bf-blender-cvs mailing list