Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2014-01-29 14:07:14 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2014-01-29 14:07:14 +0400
commita68ceb0af8ecc4c5df7a27b52814fcf0246ad36a (patch)
tree889f16eef97ef9462c141df0a2e373302c015be6 /source/blender/editors/render
parent39eb314cb922b805e9126d5f0352f31c2f84f151 (diff)
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
Diffstat (limited to 'source/blender/editors/render')
-rw-r--r--source/blender/editors/render/render_internal.c85
1 files changed, 82 insertions, 3 deletions
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 4ff4150e06a..e57474a0443 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";